Автор: Пользователь скрыл имя, 21 Марта 2013 в 22:48, курсовая работа
В данном курсовом проекте будет поэтапно создан компилятор. Для разработки компилятора первым и наиболее главным шагом должна служить создание грамматики, посредствам которой компилятор должен будет производить анализ и синтез кода исходной программы во внутреннее представление. Написание компилятора заключается в создании трех основных модулей, во-первых, это лексический анализатор, который производит поиск лексем в исходном тексте обрабатываемой программы, во-вторых, разработка синтаксического анализатора, целью которого является поиск конструкции исходного языка и сравнение её с заранее определенной грамматикой, и, наконец, перевод во внутренние коды, который осуществляет преобразование исходного кода обрабатываемой программы во внутренние коды при учете удачной работы лексического и синтаксического анализатора.
Введение 2
1 Постановка задачи 3
1.1 Задание на проектирование 3
1.2 Входные данные 3
1.3 Выходные данные 3
2 Аналитическая часть 4
2.1 Анализ поставленной задачи 4
2.2 Описание используемой грамматики 5
2.3 Блок-схема алгоритма 6
3 Проектная часть 10
3.1 Общие сведения 10
3.2 Описание классов 10
3.3 Описание логической структуры 11
3.4 Входные данные 12
3.5 Выходные данные 12
4 Контрольные примеры 13
Заключение 16
Список использованной литературы 17
Приложение 1 18
Приложение 2 20
Приложение 3 26
Приложение 4 28
}
}
?>
Файл <lexer_keyws.php>
<?
$lexer_keyws = array (
"keywords" => array (
"var" => array (
"regexp" => "\bvar\b",
"substr" => "var",
"matches" => array(),
),
"integer" => array (
"regexp" => "\binteger\b",
"substr" => "integer",
"matches" => array(),
),
"begin" => array (
"regexp" => "\bbegin\b",
"substr" => "begin",
"matches" => array(),
),
"end" => array (
"regexp" => "\bend",
"substr" => "end",
"matches" => array(),
),
"if" => array (
"regexp" => "\bif\b",
"substr" => "if",
"matches" => array(),
),
"then" => array (
"regexp" => "\bthen\b",
"substr" => "then",
"matches" => array(),
),
"else" => array (
"regexp" => "\belse\b",
"substr" => "else",
"matches" => array(),
),
"while" => array (
"regexp" => "\bwhile\b",
"substr" => "while",
"matches" => array(),
),
"do" => array (
"regexp" => "\bdo\b",
"substr" => "do",
"matches" => array(),
),
),
"identificators" => array (
"regexp" => "(\\$[\w|\d]*\b|[\d]+)",
"matches" => array(),
),
"delim" => array (
"notequal" => array (
"regexp" => "<>",
"matches" => array(),
),
"appoint" => array (
"regexp" => ":=",
"matches" => array(),
),
"equal" => array (
"regexp" => "=",
"matches" => array(),
),
"large" => array (
"regexp" => ">",
"matches" => array(),
),
"little" => array (
"regexp" => "<",
"matches" => array(),
),
"equalorlarge" => array (
"regexp" => ">=",
"matches" => array(),
),
"equalorlittle" => array (
"regexp" => "<=",
"matches" => array(),
),
"plus" => array (
"regexp" => "\+",
"matches" => array(),
),
"minus" => array (
"regexp" => "-",
"matches" => array(),
),
"star" => array (
"regexp" => "\*",
"matches" => array(),
),
"div" => array (
"regexp" => "\/",
"matches" => array(),
),
"twodots" => array (
"regexp" => ":",
"matches" => array(),
),
"dotandcomma" => array (
"regexp" => ";",
"matches" => array(),
),
"dot" => array (
"regexp" => "\.",
"matches" => array(),
),
"comma" => array (
"regexp" => ",",
"matches" => array(),
),
),
"comments" => array (
"slashnstar" => array (
"regexp" => "\/\*.*?\*\/",
"matches" => array(),
),
"slashes" => array (
"regexp" => "\/\/.*?\r",
"matches" => array(),
),
),
);
$lexer_preerrors = array (
"obligatory" => array (
"one" => array (
),
"more" => array (
"first" => array("key" => "keywords", "val" => "begin"),
"second" => array("key" => "keywords", "val" => "end"),
),
),
"pair" => array (
"equal" => array (
"terminators" => array (
"first" => array("key" => "keywords", "val" => "begin"),
"second" => array("key" => "keywords", "val" => "end"),
),
"cycle" => array (
"first" => array("key" => "keywords", "val" => "while"),
"second" => array("key" => "keywords", "val" => "do"),
),
"condition" => array (
"first" => array("key" => "keywords", "val" => "if"),
"second" => array("key" => "keywords", "val" => "then"),
),
),
"nomore" => array (
"condition" => array (
"first" => array("key" => "keywords", "val" => "if"),
"second" => array("key" => "keywords", "val" => "else"),
),
),
),
);
$lexer_text_errors = array (
"error" => " Компиляция на этапе лексического анализа завершилась неудачно, найдено @N@ ошибки(-ок).<hr/>",
"preerror" =>"На этапе лексического анализа были выявлены следующие ошибки:<br/>",
"noerror" => " Компиляция успешно прошла этап лексического анализа.<hr/>",
"unknown" => "@N@. Найден нераспознанный символ ['@key@'] в позиции @pos@.<br/>",
"obligatory" => array(
"one" => array(
"notfound" => "@N@. Не найдено ключевое слово ['@key@'], которое должно встречаться один.<br/>",
"moreone" => "@N@. Ключевое слово ['@key@'] встречается более одного раза, должно встречаться только один раз.<br/>",
),
"more" => "@N@. Не найдено ключевое слово ['@key@'], которое должно встречаться один или более раз",
),
"pair" => array(
"equal" => "@N@. Не найдено или найдено лишнее ключевое слово ['@key@'] в позиции @pos@.<br/>",
"nomore" => "@N@. Не найдено или найдено лишнее ключевое слово ['@key@'] в позиции @pos@.<br/>",
),
);
?>
Файл <lexer.php>
<?
class LeXer { // класс Лексера
var
$sourceString, // исходная строка
$resultString, // результрующая строка (не должна содержать символов после анализа)
$keyws, // массив шаблонов и совпадений ключевых слов, идентификаторов, комментариев, разделителей
$currentType, // массив текущего обрабатываемого шаблона (keywords, identificators, delim, comments)
$currentName,
// название текущего
$currentValue,
// массив, содержащий шаблон и
совпадения текущего
$currentPattern, // текущий обрабатываемый шаблон ("var", "<>", "\/\/.*?\r")
$preerrors, // заранее определенные ошибки (несовпадение пар либо объязательных символов)
$errors=array(), // массив с найденными ошибками
$text_errors, // массив сообщений об ошибках
$error_mess, // результирующие сообщение об ошибке
$count; // количество ошибок
//--
function LeXer ($string, $keyws, $preerrors, $lexer_text_errors) { // конструктор класса
$this->sourceString = $string;
$this->resultString = $string;
$this->keyws = $keyws;
$this->preerrors = $preerrors;
$this->text_errors = $lexer_text_errors;
$this->error_mess = "";
$this->count = 0;
}
//--
function lxGetPattern () { // достает шаблон (образец) для поиска по указанному элементу
if ($pattern = $this->currentValue['regexp']) {
if (is_array($pattern) ) {
$res=array();
foreach ($pattern as $pat) array_push($res, $pat);
return "'[".implode("|", $res)."]' si";
} else {
return "/".$pattern."/si";
}
}
return false;
}
//--
function lxListKeyws () { // сравнение шаблона со входным текстом, удаление совпадений из $resultString
if (($this->sourceString) && ($this->resultString) && ($this->currentPattern)) {
preg_match_all ($this->currentPattern, $this->sourceString, $matches);
if ($matches) {
foreach ($matches as $m) foreach ($m as $key=>$val) {
while (($strpos =
strpos($this->resultString, $this->currentValue['substr'])
if (!in_array($strpos,
$this->keyws['keywords'][$
$sourcelen = strlen($this->resultString);
$this->resultString = substr_replace ($this->resultString, "",$strpos, strlen($val));
array_push($this->keyws['
}
}
}
}
}
return false;
}
//--
function lxKeyws () { // поиск совпадений ключевых слов
$this->currentType = $this->keyws['keywords'];
foreach ($this->currentType as $keyValue => $valValue) {
$this->currentName = $keyValue; // название обрабатыываемого значения (if || for || array || // || ;)
$this->currentValue = $valValue; // само значение
$this->currentPattern = $this->lxGetPattern(); // само значение (рег выражение, массив совпадений)
$this->lxListKeyws();
}
}
//--
function lxRemoveComments () { // вырезание комментариев
$this->currentType = $this->keyws['comments'];
foreach ($this->currentType as $keyValue => $valValue) {
$this->currentName = $keyValue; // название обрабатыываемого значения (if || for || array || // || ;)
$this->currentValue = $valValue; // само значение
$this->currentPattern = $this->lxGetPattern(); // само значение (рег выражение, массив совпадений)
preg_match_all ($this->currentPattern, $this->sourceString, $matches);
if ($matches) {
foreach ($matches as $m) foreach ($m as $match) {
$strpos = strpos($this->resultString, $match);
if ($strpos !== false) {
if (!in_array($match, $this->keyws['comments'][$
$this->resultString = substr_replace ($this->resultString, "",$strpos, strlen($match));
array_push($this->keyws['
}
}
}
}
}
}
//--
function lxDelimeters () { // поиск разделителей
$this->currentType = $this->keyws['delim'];
foreach ($this->currentType as $keyValue => $valValue) {
$this->currentName = $keyValue;
$this->currentValue = $valValue;
$this->currentPattern = $this->lxGetPattern();
if ($this->currentPattern && $this->resultString) {
preg_match_all ($this->currentPattern, $this->resultString, $matches);
if ($matches) {
foreach ($matches as $m) foreach ($m as $match) {
$strpos = strpos($this->resultString, $match);
if ($strpos !== false) {
$this->resultString = substr_replace ($this->resultString, "",$strpos, strlen($match));
array_push($this->keyws['
}
}
}
}
}
}
//--
function lxIdentificators () { // отбражение результатов сканирования
$this->currentType = $this->keyws['identificators']
$this->currentName = 'identificators';
$this->currentValue = $this->currentType;
$this->currentPattern = $this->lxGetPattern();
if ($this->currentPattern && $this->sourceString) {
preg_match_all ($this->currentPattern, $this->sourceString, $matches);
if ($matches) {
foreach ($matches as $m) foreach ($m as $match) {
// echo "|".$match."|";
$strpos = strpos($this->resultString, $match);
if ($strpos !== false) {
$this->resultString = substr_replace ($this->resultString, "",$strpos, strlen($match));
array_push($this->keyws['
}
}
}
}
}
//--
function lxDiagnostics () { // поиск ошибок
//
preg_match_all ("/\S+?\s/si", $this->resultString, $matches); // поиск оставшихся ('неразобранных') слов
if ($matches) {
foreach ($matches as $m) foreach ($m as $match) {
$strpos = strpos($this->resultString, $match);
if ($strpos !== false) {
$this->count++;
$this->errors['unknown'][$
}
}
}
//
foreach ($this->preerrors['obligatory'
if (count($this->keyws[$val["key"