43219
Реализация интерпретатора для модифицированной грамматики учебного языка MILAN
Курсовая
Информатика, кибернетика и программирование
Position текущая позиция в строке просматриваемая лексическим анализатором; Number_String текущая строка программы просматриваемая лексическим анализатором; при любом условии любой символ. Семантические функции к Rсхеме лексического анализатора: y0: подготовка инициализация таблиц и переменных Position=0 Number_String=1; y1: чтение следующего символа программы на языке МИЛАН; y2: увеличение счётчика текущей позиции Position; y3: переход на новую строку в программе увеличение счётчика текущей строки и...
Русский
2013-11-04
1.68 MB
50 чел.
Министерство образования и науки Российской Федерации
Волжский политехнический институт (филиал) федерального государственного бюджетного образовательного учреждения высшего профессионального образования «Волгоградский государственный технический университет»
(ВПИ (филиал) ВолгГТУ)
Факультет «_________________________________________________________»
Кафедра «___________________________________________________________»
ПОЯСНИТЕЛЬНАЯ ЗАПИСКА
к курсовому работе (проекту)
по дисциплине «_____________________________________________________»
на тему______________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
Студент_____________________________________________________________
(имя, отчество, фамилия)
Группа________________________
Руководитель работы (проекта) ________________________ _____________________
(подпись и дата подписания) (долж., инициалы и фамилия)
Оценка ________________________
(в баллах)
Члены комиссии:
_____________________ ____________________________
(подпись и дата подписания) (инициалы и фамилия)
_____________________ ____________________________
(подпись и дата подписания) (инициалы и фамилия)
_____________________ ____________________________
(подпись и дата подписания) (инициалы и фамилия)
Нормоконтролер ______________________________ _____________________________
(подпись, дата подписания) (инициалы и фамилия)
Волжский, 2011 г.
____________________________________________________________________________________________________________________________________________________________________________________________________________
________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
Перечень графического материала
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
Исполнитель работы _____________________________ __________________________
(подпись и дата подписания) (фамилия, имя, отчество)
Руководитель работы ____________________________ __________________________
(подпись и дата подписания) (фамилия, имя, отчество)
Консультанты по разделам:
________________________________ _________________________ __________________________
(краткое наименование раздела) (подпись и дата подписания) (фамилия, имя, отчество)
________________________________ _________________________ ___________________________
(краткое наименование раздела) (подпись и дата подписания) (фамилия, имя, отчество)
Введение
Целью данной курсовой работы является ознакомление с принципами и методами работы интерпретаторов и реализация интерпретатора для модифицированной грамматики учебного языка MILAN.
Согласно варианту, грамматику языка нужно дополнить следующими конструкциями:
1) <оператор-переключатель>::= SWITCH (<выражение>)
{ CASE <константа> : <последовательность операторов>
{ CASE <константа> : <последовательность операторов> }
[ DEFAULT : <последовательность операторов> ] }
2) <цикл-FОR>::= FOR <идентификатор> := <выражение> TO <выражение> [STEP <выражение>]
<последовательность операторов>
ENDFOR
3) Комментарий в фигурных скобках.
Пример: { раздел описания переменных }
4) -- : декремент (уменьшение значения переменной на 1)
1. Теоретическая часть.
1.1. Обзор методов и алгоритмов работы интерпретатора языка MILAN.
Работа интерпретатора языка MILAN происходит в два этапа: на первом выполняется лексический анализ входного текста, а на втором синтаксический анализ, совмещённый с интерпретацией.
Часть интепретатора, которая выполняет лексический анализ, называется лексическим анализатором. Лексический анализатор воспринимает исходный текст программы и преобразует его в последовательность лексем - промежуточный язык, удобный для синтаксического анализа.
После лексической обработки и расстановки ссылок последовательность лексем, массивы идентификаторов и констант поступают на обработку интерпретатору. Задача интерпретатора - распознать конструкции языка и выполнить действия, предписанные входной программой
1.2. Грамматика модифицированного языка MILAN в виде БНФ. Описание лексического и синтаксического анализаторов модифицированного языка MILAN.
Грамматика модифицированного языка MILAN в виде БНФ:
W= <программа> ::= BEGIN <последовательность операторов> END
L= <последовательность операторов> ::= <оператор>|
<оператор>;<последовательность операторов>
S= <оператор> ::= <идентификатор>:=<выражение> |
OUTPUT(<выражение>) |
WHILE <условие> DO <последовательность операторов> ENDDO |
IF <условие> THEN <последовательность операторов> ENDIF |
IF <условие> THEN <последовательность операторов>
ELSE <последовательность операторов> ENDIF|
FOR <идентификатор> := <выражение> TO <выражение>
<последовательность операторов> ENDFOR |
FOR <идентификатор> := <выражение> TO <выражение>
STEP <выражение> <последовательность операторов> ENDFOR|
SWITH(<выражение>){<последовательность переключателей}
Q= < последовательность переключателей> ::= CASE <константа> : <последовательность операторов>| CASE <константа> : <последовательность операторов>< последовательность переключателей> |CASE <константа> : <последовательность операторов>< последовательность переключателей> DEFAUT : <последовательность операторов>
D = <DEFAULT-ветвь> : : = DEFAULT<последовательность операторов>
B = <условие> ::= <выражение> <знак отношения> <выражение>
E= <выражение> ::= <терм> | <операция типа сложения> <терм> |
<терм> <операция типа сложения> <терм> |
<операция типа сложения> <терм> <операция типа сложения><терм>
T=<терм> ::= <множитель> | <множитель> <операция типа умножения> <множитель>
P=<множитель> ::= <идентификатор> | <константа> | READ | (<выражение>)
I=<идентификатор> ::= <буква> | <идентификатор> <буква> |
<идентификатор> <цифра>
K=<константа> ::= <цифра> | <константа> <цифра>
O=<знак отношения> ::= > | < | >= | <= | = |<>
M=<операция типа умножения> ::= * | /
N=<операция типа сложения> ::= + | -
U=< операция типа инкремент> ::=++
G=<комментарий>::={<текст комментария>}
R=<текст комментария>::=<буква>|<комментарий><буква>|<комментарий>
<цифра>|<цифра >
A= <буква> ::= a | b | ...| z
C= <цифра> ::= 0 | 1 | ...| 9
Описание лексического и синтаксического анализаторов модифицированного языка MILAN.
Лексический анализатор строит таблицы (массивы) идентификаторов и констант. Таким образом, основными функциями лексического анализатора являются: построение последовательности лексем; построение таблицы идентификаторов; построение таблицы констант; расстановка ссылок для передачи управления.
Для повышения эффективности последующих действий лексемы обычно представляются в виде пары (код, значение). На этапе синтаксического анализа используется первая компонента пары - код. Вторая компонента - значение, используется при семантических вычислениях. Для языка MILAN используются определения лексем, представленные в таблице 1. При распознавании идентификаторов и констант лексическим анализатором используются следующие правила грамматики: , , , .
Таким образом, в последовательности лексем идентификаторы и константы становятся терминалами, и грамматика языка упрощается.
Таблица 1. Таблица лексем модифицированного языка MILAN.
Название лексемы |
Код |
Запись в языке |
Обозначение |
Значение |
Служебные слова: BEGIN DO ELSE END ENDDO ENDIF IF OUTPUT READ THEN WHILE FOR TO STEP ENDFOR SWITCH CASE DEFAULT |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
BEGIN DO ELSE END ENDDO ENDIF IF OUTPUT READ THEN WHILE FOR TO STEP ENDFOR SWITCH CASE DEFAULT |
BEGIN DO ELSE END ENDDO ENDIF IF OUTPUT READ THEN WHILE FOR TO STEP ENDFOR SWITCH CASE DEFAULT |
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
Точка с запятой |
17 |
; |
tz |
0 |
Знак отношения: = <> > < >= <= |
18 |
= <> > < >= <= |
otn |
k(=)=0 k(<>)=1 k(>)=2 k(<)=3 k(>=)=4 k(<=)=5 |
Операция типа сложения: + - |
19 |
+ - |
ots |
k(+)=0 k(-)=1 |
Операция типа умножения: * / |
20 |
* / |
otu |
k(*)=0 k(/)=1 |
Присваивание |
21 |
:= |
oprsv |
0 |
Открывающаяся скобка |
22 |
( |
os |
0 |
Закрывающаяся скобка |
23 |
) |
zs |
0 |
Идентификатор |
24 |
a, b23 |
id |
Указатель на таблицу идентификаторов |
Константа без знака |
25 |
32, 0274 |
int |
Указатель на таблицу констант |
Открывающая фигурная скобка |
26 |
{ |
ofs |
0 |
Закрывающая фигурная скобка |
27 |
} |
zfs |
0 |
Двоеточие |
28 |
: |
dv |
0 |
Декремент |
29 |
-- |
dec |
0 |
Скобки комментариев |
30 |
{} |
coms |
0 |
На рисунке 1 представлена R-схема лексического анализатора модифицированного языка MILAN.
Рис. 1. R-схема лексического анализатора модифицированного языка MILAN.
Семантические функции к рис.1.
- $Position - текущая позиция в строке, просматриваемая лексическим анализатором;
- $Number_String - текущая строка программы, просматриваемая лексическим анализатором;
- * - при любом условии (любой символ).
Семантические функции к R-схеме лексического анализатора:
y0: подготовка (инициализация таблиц и переменных), $Position=0, $Number_String=1;
y1: чтение следующего символа программы на языке МИЛАН;
y2: увеличение счётчика текущей позиции ($Position++);
y3: переход на новую строку в программе, увеличение счётчика текущей строки, и сброс счётчика позиции ($Number_String++, $Position=0);
y4: накопление символов ключевого слова или идентификатора;
y5: проверка на принадлежность выделенного слова к ключевым словам;
y6: проверка на принадлежность выделенного слова к идентификаторам;
y7: накопление символов константы;
y8: проверка на принадлежность выделенной константы таблице констант;
y9: запись сформированной лексемы в массив лексем;
y10: завершение работы лексического анализатора;
y11: формирование лексемы;
Ограничения: Программа на языке МИЛАН должна содержать <=15 идентификаторов, <= 15 констант, <=500 лексем
На рисунке 2 представлена R-схема расстановки ссылок и семантические функции к ней.
Рис 2. R-схема расстановки ссылок.
Для описания семантических функций синтаксической диаграммы расстановки ссылок введены обозначения:
- $Tab_Lexems[..]->Code - массив номеров лексем;
- $Tab_Lexems[..]->Value -массив значений лексем;
- $Number_Lexem - номер очередной рассматриваемой лексемы в массиве лексем;
- $Stek_do - стек для циклов WHILE;
- $Stek_if - стек для развилок IF;
- $Stek_for - стек для циклов FOR;
- $Stek_sw - стек для операторов-переключателей SWITCH().
Семантические функции к R-схеме расстановки ссылок:
y0: подготовка (инициализация стеков и переменных), номер очередной лексемы $Number_Lexem=1, прочитать лексему с номером $Number_Lexem;
y1: значение $Number_Lexem занести стек $Stek_do ($Number_Lexem→$Stek_do);
y2: снять вершину стека $Stek_do в переменную $s ($s ← $Stek_do), снять вершину стека $Stek_do в переменную $r ($r ← $Stek_do), значение $r+1 присвоть лексеме с номером $Number_Lexem [ENDDO→WHILE+1] ($Tab_Lexems[$Number_Lexem]->Value=$r+1), значение $Number_Lexem+1 присвоить лексеме с номером $s [DO→ENDDO+1] ($Tab_Lexems[$s]->Value=$Number_Lexem+1);
y3: значение $Number_Lexem занести в стек $Stek_if ($Number_Lexem→$Stek_if);
y4: снять вершину стека $Stek_if в переменную $r ($r ← $Stek_if), присвоить значение $Number_Lexem+1 лексеме c номером $r [THEN→ELSE+1] ($Tab_Lexems[$r]->Value=$Number_Lexem+1), занести в $Stek_if значение $Number_Lexem ($Number_Lexem→$Stek_if);
y5: снять вершину стека $Stek_if в переменную $r ($r←$Stek_if), присвоить значение $Number_Lexem+1 лексеме c номером $r [THEN→ENDIF+1, ELSE→ENDIF+1] ($Tab_Lexems[$r]->Value=$Number_Lexem+1) занести в $Stek_if значение $Number_Lexem ($Number_Lexem→$Stek_if);
y6: завершить работу;
y7: $Number_Lexem++, прочитать очередную лексему с номером $Number_Lexem;
y8: значение $Number_Lexem занести в стек $Stek_for ($Number_Lexem→$Stek_for);
y9: снять вершину стека $Stek_for в переменную $s ($s ← $Stek_for), значение $s+1 присвоть лексеме с номером $Number_Lexem [ENDFOR→FOR+1] ($Tab_Lexems[$Number_Lexem]->Value=$s+1), значение $Number_Lexem+1 присвоить лексеме с номером $s ($Tab_Lexems[$s]->Value=$Number_Lexem+1);
y10: снять вершину стека $Stek_rep в переменную $m ($m ← $Stek_rep), значение $m присвоим лексеме с номером $l ($Tab_Lexems[$l]->Value=$m) [REPEAT+1→<условие>]; значение $l+1 присвоить лексеме с номером $p [UNTIL→REPEAT+1] ($Tab_Lexems[$p]->Value=$l+1);
y11: значение $Number_Lexem занести в стек $Stek_sw ($Number_Lexem→$Stek_sw), снять значение с вершины стека $Stek_sw в переменную $f ($f ← $Stek_sw);
y12: значение $Number_Lexem занести в стек $Stek_sw ($Number_Lexem→$Stek_sw), снять значение с вершины стека $Stek_sw в переменную $q ($q ← $Stek_sw);
y13: значение $Number_Lexem занести в стек $Stek_sw ($Number_Lexem→$Stek_sw), снять значение с вершины стека $Stek_sw в переменную $w ($w ← $Stek_sw), лексеме с номером $q присвоить значение $w [CASE→}] или $w+1 [CASE1→CASE2; CASE→DEFAULT];
y14: значение $Number_Lexem занести в стек $Stek_sw ($Number_Lexem→$Stek_sw), снять значение с вершины стека $Stek_sw в переменную $z ($z ← $Stek_sw),
y15: значение $Number_Lexem занести в стек $Stek_sw ($Number_Lexem→$Stek_sw), снять значение с вершины стека $Stek_sw в переменную $w ($w ← $Stek_sw), лексеме с номером $z присвоить значение $w+1 [DEFAULT→}+1], лексеме с номером $f присвоить значение $w+1 [SWITCH→}+1], лексеме с номером $q присвоить значение $z [CASE→DEFAULT].
Синтаксический разбор будет производиться над массивом лексем. Уточним грамматику языка MILAN, которая будет использована для синтаксического анализа последовательности лексем. Множество терминалов в уточненной грамматике - это множество лексем.
1)
2)
3)
4)
5)
6)
7)
8)
9)
10)
11)
12)
13)
14)
Здесь и - число идентификаторов и констант; нетерминалы обозначают конструкции языка: - <программа>; -<последовательность операторов>; - <оператор>; - <условие>; - <выражение>; - <терм>; - <множитель>; - <константа>; O - <знак отношения>; M - <операция типа умножения>; N - <операция типа сложения>; I - <идентификатор>, F - <CASE-последовательность>, D - <DEFAULT-ветвь>.
На рисунках 3 и 4 представлены R-схемы интерпретатора.
Рис 3. R-схема интерпретатора: нетерминальные символы W, L, S, F, D.
Рис 4. R-схема интерпретатора: нетерминальные символы B,E,T,P.
Семантическии функции к R-схеме интерпретатора.
y0: инициализация стеков и переменных;
y1: занесение в стек $StekRes идентификатора $Tab_Lexems[$Number_Lexem]->Value;
y2: занесение в стек $StekRes константы $Tab_Lexems[$Number_Lexem]->Value;
y3: прочитать целое число с терминала в переменную $Cifra и положить его в $StekRes ($Cifra→$StekRes);
y4: чтение следующей лексемы ($Number_Lexem++);
y5: занесение в стек $StekMul значение операции типа умножения ($Tab_Lexems[$Number_Lexem]->Value→$StekMul);
y6: в переменную $Bi снять элемент со стека $StekRes ($Bi←$StekRes), в переменную $Ai снять элемент со стека $StekRes ($Ai←$StekRes), в переменную $kmul снять элемент со стека $StekMul ($kmul←$StekMul), выполнить операцию типа умножение $Ai otu($kmul) $Bi и результат занести в стек $StekRes;
y7: занесение в стек $StekSum кода операции типа сложения;
y8: в переменную $ksum снять со стека $StekSum значение лексемы ots ($ksum←$StekSum), если $ksum=1, то снять в переменную $Ai элемент со стека $StekRes ($Ai←$StekRes), сменить знак этого числа и занести его в стек $StekRes (-$Ai→$StekRes);
y9: занесение в стек $StekSum кода операции типа сложения;
y10: в переменную $Bi снять элемент со стека $StekRes ($Bi←$StekRes), в переменную $Ai снять элемент со стека $StekRes ($Ai←$StekRes), в переменную $ksum снять элемент со стека $StekSum ($ksum←$StekSum), вы полнить операцию типа сложение $Ai ots($ksum) $Bi и результат занести в стек $StekRes;
y11: добавление в стек $StekRel значения операции типа отношение ($Tab_Lexems[$Number_Lexem]->Value→$StekRel);
y12: в переменную $Bi снять элемент со стека $StekRes ($Bi←$StekRes), в переменную $Ai снять элемент со стека $StekRes ($Ai←$StekRes), в переменную $krel снять элемент со стека $StekRel ($krel←$StekRel), выполнить операцию сравнения $Ai otn($krel) $Bi и результат занести в стек $StekRes ([0, 1] →$StekRes);
y13: добавить значение лексемы с номером Number_Lexem в стек StekIdent ($Tab_Lexems[$Number_Lexem]->Value→$StekIdent);
y14: в переменную $Ai снять элемент со стека $StekRes ($Ai←$StekRes), в переменную $Bi снять со стека $StekIdent значение лексемы ident ($Bi←$StekIdent), идентификатору с номером $Bi, присвоить значение $Ai ($ArrIdent[$Bi]=$Ai);
y15: в переменную $Ai снять элемент со стека $StekRes ($Ai←$StekRes), напечатать переменную $Ai;
y16: в переменную $Ai снять элемент со стека $StekRes ($Ai←$StekRes), если $Ai=1, то это истина, иначе - ложь;
y17: перейти на лексему номер $Tab_Lexems[$Number_Lexem]->Value;
y18: в переменную $Ai снять элемент со стека $StekRes ($Ai←$StekRes), если $Ai=1, то это истина, иначе - ложь;
y19: перейти на лексему номер $Tab_Lexems[$Number_Lexem]->Value-1;
y20: завершение работы;
y21: в переменную $Ai снять элемент со стека $StekRes ($Ai←$StekRes);
y22: в переменную $Bi снять элемент со стека $StekRes ($Bi←$StekRes), если $Ai=$Bi, то считать следующую лексему, в противном случае перейти на лексему $Tab_Lexems[$cvalcase]->Value;
y23: в переменную $cvalsw занести значение $Number_Lexem;
y24: в переменную $cvalcase занести значение $Number_Lexem;
y25: перейти на лексему $Tab_Lexems[$cvalsw]->Value;
y26: занести в $Bi значение $Tab_Lexems[$Number_Lexem]->Value, в переменную $Ai занести значение $ArrIdent[$Bi], увеличить значение на 1, занести $Ai в стек $StekRes ($Ai→$StekRes), в переменную $Ai снять элемент со стека $StekRes ($Ai←$StekRes), в переменную $Bi снять элемент со стека $StekIdent ($Bi←$StekIdent), в $ArrIdent[$Bi] занести значение $Ai;
y27: в переменную $ires занести значение $Tab_Lexems[$Number_Lexem]->Value, в переменную $res занести значение $ArrIdent[$ires];
y28: переменную $res увеличить на 1, занести значение $res в стек $StekRes, в переменную $res считать элемет из стека $StekRes, в переменную $ires снять элемент со стека $StekIdent, $ArrIdent[$ires] присвоить значение $res;
y29: в переменную $ires занести значение $NomIdent, в переменную $res занести значение $ArrIdent[$NomIdent].
2. Исследовательская часть
2.1 Программная реализация интерпретатора модифицированного языка MILAN (с комментариями).
<?php
//Описание классов
/* элемент массива лексем */
class Element_Lexems
{
/* код лексемы */
public $Code = 0 ;
/* значение лексемы */
public $Value = 0 ;
}
/* Элемент таблицы ключевых [зарезервированных] слов */
class Element_Key_Words
{
/* Ключевое слово */
public $Key_Word = '';
/* Код ключевого слова */
public $Code_Key_Word = 0;
}
//Описание констант
/* Количество ключевых слов языка МИЛАН */
define("MAX_KEY_WORDS",18);
/* Кода ключевых слов языка МИЛАН */
define("_BEGIN_", 1);
define("_DO_", 2);
define("_ELSE_", 3);
define("_END_", 4);
define("_ENDDO_", 5);
define("_ENDIF_", 6);
define("_IF_", 7);
define("_OUTPUT_", 8);
define("_READ_", 9);
define("_THEN_", 10);
define("_WHILE_", 11);
define("_SWITH_", 21);
define("_CASE_", 22);
define("_DEFAUT_", 23);
define("_FOR_", 24);
define("_TO_", 25);
define("_STEP_", 26);
define("_ENDFOR_", 27);
/* Кода лексем языка МИЛАН */
define("_SEMICOLON_",12); /* ; */
define("_RELATION_",13); // операция типа отношение
/* значения операции типа отношение */
define("_EQUAL_", 0); /* = */
define("_NOTEQUAL_", 1); /* <> */
define("_GT_", 2); /* > */
define("_LT_", 3); /* < */
define("_GE_", 4); /* >= */
define("_LE_", 5); /* <= */
define("_SUMM_", 14); /* операция типа сложение */
/* значения операции типа сложение */
define("_PLUS_", 0); /* + */
define("_MINUS_", 1); /* - */
define("_MUL_", 15); /* операция типа умножение */
/* значения операции типа сложение */
define("_STAR_", 0); /* * */
define("_SLASH_", 1); /* / */
define("_ASSIGNMENT_", 16); /* присваивание */
define("_DECREMENT_", 28); /* -- */
define("_COLON_", 31); /* : */
define("_BRACE_OPEN_", 29); /* { */
define("_BRACE_CLOSE_", 30); /* } */
define("_LPAREN_", 17); /* ( */
define("_RPAREN_", 18); /* ) */
define("_IDENTIFIER_", 19); /* идентификатор */
define("_CONSTANT_", 20); /* константа */
/* Таблица ключевых [зарезервированных] слов языка МИЛАН */
/* Ключевые слова в массиве должны быть упорядочены, т.к. */
/* поиск в массиве осуществляется методом "бинарного поиска" */
$Table_Key_Words = Array();
function ct_AddElement($Key_Word, $Code_Key_Word)
{
$ct_Element = new Element_Key_Words;
$ct_Element->Key_Word = $Key_Word;
$ct_Element->Code_Key_Word = $Code_Key_Word;
return $ct_Element;
}
//создаём новый массив
$Table_Key_Words[1] = ct_AddElement('BEGIN', _BEGIN_);
$Table_Key_Words[2] = ct_AddElement('CASE', _CASE_);
$Table_Key_Words[3] = ct_AddElement('DEFAUT', _DEFAUT_);
$Table_Key_Words[4] = ct_AddElement('DO', _DO_);
$Table_Key_Words[5] = ct_AddElement('ELSE', _ELSE_);
$Table_Key_Words[6] = ct_AddElement('END', _END_);
$Table_Key_Words[7] = ct_AddElement('ENDDO', _ENDDO_);
$Table_Key_Words[8] = ct_AddElement('ENDFOR', _ENDFOR_);
$Table_Key_Words[9] = ct_AddElement('ENDIF', _ENDIF_);
$Table_Key_Words[10] = ct_AddElement('FOR', _FOR_);
$Table_Key_Words[11] = ct_AddElement('IF', _IF_);
$Table_Key_Words[12] = ct_AddElement('OUTPUT', _OUTPUT_);
$Table_Key_Words[13] = ct_AddElement('READ', _READ_);
$Table_Key_Words[14] = ct_AddElement('STEP', _STEP_);
$Table_Key_Words[15] = ct_AddElement('SWITH', _SWITH_);
$Table_Key_Words[16]= ct_AddElement('THEN', _THEN_);
$Table_Key_Words[17] = ct_AddElement('TO', _TO_);
$Table_Key_Words[18]= ct_AddElement('WHILE', _WHILE_);
/* максимально допустимое количество идентификаторов в программе */
define("MAX_IDENTIFIERS", 15);
/* максимально допустимое количество констант в программе */
define("MAX_CONSTANTS", 15);
/* максимально допустимое количество лексем в программе */
define("MAX_LEXEMS", 500);
/* массив сообщений об ошибках в программе на МИЛАНе */
$Error_Message = Array(
/* 1 */ 'Неизвестный символ в программе.',
/* 2 */ 'Превышение максимального количества идентификаторов.',
/* 3 */ 'Превышение максимального количества констант.',
/* 4 */ 'Переполнение массива лексем.',
/* 5 */ 'Переполнение стека Stek_do.',
/* 6 */ 'Нехватка элементов в стеке Stek_do.',
/* 7 */ 'Неправильное обращение к функции для работы со стеком Stek_do.',
/* 8 */ 'Переполнение стека Stek_if.',
/* 9 */ 'Нехватка элементов в стеке Stek_if.',
/* 10 */ 'Неправильное обращение к функции для работы со стеком Stek_if.',
/* 11 */ 'Несоответствие в операторах WHILE-DO-ENDDO.',
/* 12 */ 'Несоответствие в операторах IF-THEN-ELSE-ENDIF.',
/* 13 */ 'Конструкция <программа>. Нет BEGIN.',
/* 14 */ 'Конструкция <программа>. Нет END.',
/* 15 */ 'Переполнение стека StekIdent.',
/* 16 */ 'Конструкция <оператор>. Неверное присваивание.',
/* 17 */ 'Нехватка элементов в стеке StekRes.',
/* 18 */ 'Нехватка элементов в стеке StekIdent.',
/* 19 */ 'Конструкция <оператор>. Неверный оператор OUTPUT.',
/* 20 */ 'Конструкция <оператор>. Неверный оператор WHILE.',
/* 21 */ 'Конструкция <оператор>. Отсутствует THEN в операторе IF.',
/* 22 */ 'Конструкция <оператор>. Отсутствует ENDIF в операторе IF.',
/* 23 */ 'Конструкция <оператор>. Отсутствует ELSE или ENDIF в операторе IF.',
/* 24 */ 'Конструкция <условие>. Неверная операция отношения.',
/* 25 */ 'Переполнение стека StekRel.',
/* 26 */ 'Нехватка элементов в стеке StekRel.',
/* 27 */ 'Переполнение стека StekRes.',
/* 28 */ 'Нехватка элементов в стеке StekMul.',
/* 29 */ 'Переполнение стека StekMul.',
/* 30 */ 'Деление на ноль.',
/* 31 */ 'Конструкция <множитель>. Нет закрывающей скобки.',
/* 32 */ 'Переполнение стека StekSum.',
/* 33 */ 'Нехватка элементов в стеке StekSum.',
/* 33 */ 'Нехватка элементов в стеке StekSum.',
/* 34 */ 'Конструкция <оператор>. Отсутствует ( в операторе SWITH.',
/* 35 */ 'Конструкция <оператор>. Отсутствует ) в операторе SWITH.',
/* 36 */ 'Переполнение стека $StekCaseValue',
/* 37 */ 'Переполнение стека $StekDefaultValue',
/* 38 */ 'Конструкция <оператор>. Отсутствует { в операторе SWITH.',
/* 39 */ 'Конструкция <оператор>. Отсутствует CASE в операторе SWITH.',
/* 40 */ 'Нехватка элементов в стеке $StekCaseValue',
/* 41 */ 'Конструкция <оператор>. Отсутствует константа в операторе SWITH.',
/* 42 */ 'Нехватка элементов в стеке $StekDefaultValue',
/* 43 */ 'Конструкция <оператор>. Отсутствует : в операторе SWITH.',
/* 44 */ 'Конструкция <оператор>. Отсутствует } в операторе SWITH.',
/* 45 */ 'Перепонение стека $Stek_case.',
/* 46 */ 'Нехватка элементов в стеке $Stek_case.',
/* 47 */ 'Несоответствие в операторах SWITH-CASE-DEFAUT',
/* 48 */ 'Конструкция <оператор>. Отсутствует идентификатор в операторе FOR.',
/* 49 */ 'Конструкция <оператор>. Отсутствует присвоение в операторе FOR.',
/* 50 */ 'Конструкция <оператор>. Отсутствует TO в операторе FOR.',
/* 51 */ 'Конструкция <оператор>. Отсутствует ENDFOR в операторе FOR.',
/* 52 */ 'Переполнение стека $StekForExit',
/* 53 */ 'Нехватка элементов в стеке $StekForExit',
/* 54 */ 'Несоответствие в операторах FOR-TO-ENDFOR',
/* 55 */ 'Переполнение стека $Stek_to',
/* 56 */ 'Нехватка элементов в стеке $Stek_to',
/* 57 */ 'После преддекремента отсутствует идентификатор',
/* 58 */ 'Переполнение стека $StekPostDec',
/* 59 */ 'Нехватка элементов в стеке $StekPostDec',
/* 60 */ 'Переполнение стека $StekPostDecCount',
/* 61 */ 'Нехватка элементов в стеке $StekPostDecCount');
/* массив лексем */
$Tab_Lexems = Array ();
/* массив идентификаторов */
$Tab_Identifiers = Array ();
/* массив констант */
$Tab_Constants = Array ();
/* Имя программы на языке МИЛАН */
$Input_Programm = '';
/* Входной файл программы на языке МИЛАН */
/* Входной символ программы на языке МИЛАН */
$Input_Letter = '';
/* Номер очередного символа в программе */
$Number_Letter = 0;
/* Код ошибки */
$Code_Error = -1 ;
/* Номер строки и позиции в которой ошибка */
$Number_String = 0;
$Position = 0;
/* Номер очередной лексемы в программе */
$Number_Lexem = 0;
/* Сформированная Лексическим Анализатором лексема */
$Current_Lexem = new Element_Lexems;
/* Количество лексем в программе */
$Number_Lexems_Programm = 0;
/* Номер очередного идентификатора в программе */
$Number_Identifiers = 0;
/* Номер очередной константы в программе */
$Number_Constants = 0;
/*************************************************************************/
/* Stek_Integer(...) */
/* Функция для работы со стеками типа Integer. */
/* Аргументы: */
/* Operation - код операции ( 0 - инициализация стека; */
/* 1 - извлечение элемента из стека */
/* в Element; */
/* 2 - добавление элемента */
/* в стек Element; */
/* $Current_Stek - массив из 50 элементов ; */
/* $Top - вершина стека ; */
/* $Element - элемент который кладется в стек или в который */
/* возвращается вершина стека. */
/* Функция возвращает значение TRUE, если операция работы со стеком */
/* выполнена успешно, FALSE - в противном случае. */
/*************************************************************************/
function Stek_Integer( $Operation ,
&$Current_Stek,
&$Top,
&$Element)
{
global $Code_Error;
switch ($Operation):
/* Инициализация стека */
Case 0 :
$Top=0;
for ($i=1;$i<=50;$i++)
{
$Current_Stek[$i]=0;
}
break;
/* Извлечение элемента со стека */
Case 1 :
if ($Top<=0)
{
return FALSE;
}
else
{
$Element=$Current_Stek[$Top];
$Top--;
}
break;
/* Добавление элемента в стек */
Case 2 :
if ($Top>=50)
{
return FALSE;
}
else
{
$Top++;
$Current_Stek[$Top]=$Element;
}
break;
/* Сообщение об ошибке */
default:
$Code_Error=4;
return FALSE;
endswitch;
return TRUE;
} /* End Stek_Integer*/
/*************************************************************************/
/* Replicate(<ВырC>,<ВырN>) */
/* Аргументы: <ВырC>, <ВырN>. */
/* Результат: Функция возвращает символьную строку, полученную */
/* повторением <ВырN> раз строки <ВырC>. */
/*************************************************************************/
Function Replicate($String_Letter, $Num)
{
$Word='';
for($i=1; $i<=$Num; $i++)
$Word = $Word . $String_Letter;
return $Word;
} /* End Replicate */
/*************************************************************************/
/* Space(<ВырN>) */
/* Аргументы: <ВырN>. */
/* Функция возвращает строку, состоящую из <ВырN> пробелов. */
/*************************************************************************/
Function Space($Num)
{
return Replicate(' ',$Num);
} /* End Space */
/*************************************************************************/
/* Print_Error */
/* Процедура вывода на экран сообщения об ошибке для */
/* Лексического Анализатора */
/* Расстановки ссылок */
/* Интерпретатора */
/*************************************************************************/
function Print_Error($Variant)
{
global $Number_String;
global $Position;
global $Number_Lexem;
global $Code_Error;
global $Error_Message;
global $Tab_Lexems;
global $ct_buf;
switch ($Variant)
{
Case 1 :
print ('<html><head><title>РЕЗУЛЬТАТ РАБОТЫ ЛЕКСИЧЕСКОГО АНАЛИЗАТОРА</title></head><body><br><H2 align="center">РЕЗУЛЬТАТ РАБОТЫ ЛЕКСИЧЕСКОГО АНАЛИЗАТОРА</H2><br><hr><br>
<table cellspacing="3" cellpadding="3" align="center"><tr><td >НАЙДЕНА ОШИБКА: </td><td align="center"><font color="red"> ' . $Error_Message[$Code_Error] . '</font></td></tr>
<tr><td> СТРОКА: </td><td align="left"><font color="blue">' . $Number_String . '</font></td></tr>
<tr><td> ПОЗИЦИЯ:</td><td align="left"><font color="blue">' . $Position . '</font></td></tr></table>
<br><hr><br><div align="center">
<form method="post" action="INTERFACE.php">
<input type="submit" value=" ОК " >
<input name="source" type="hidden" value="'.$ct_buf.'">
</form></div></body></html> ');
break;
Case 2 :
print ('<html><head><title>РЕЗУЛЬТАТ РАБОТЫ СИНТАКСИЧЕСКОГО АНАЛИЗАТОРА</title></head><body><br><H2 align="center">РЕЗУЛЬТАТ РАБОТЫ СИНТАКСИЧЕСКОГО АНАЛИЗАТОРА</H2><br><hr><br>
<table cellspacing="3" cellpadding="3" align="center"><tr><td >НАЙДЕНА ОШИБКА: </td><td align="center"><font color="red"> ' . $Error_Message[$Code_Error] . '</font></td></tr>
<tr><td> ЛЕКСЕМА: </td><td align="left"><font color="blue">' . $Number_Lexem . '</font></td></tr></table>
<br><hr><br><div align="center">
<form method="post" action="INTERFACE.php">
<input type="submit" value=" ОК ">
<input name="source" type="hidden" value="'.$ct_buf.'">
</form></div></body></html> ');
break;
}
} /* End Print_Error */
/************************************************************************/
/* Isdigit(<ВырC>) */
/* Функция возвращает значение TRUE, если <вырC> начинается с цифры. */
/************************************************************************/
Function Isdigit($Figure)
{
$ct_res=ereg("[0-9]", $Figure{0});
return $ct_res;
} /* End Isdigit */
/************************************************************************/
/* Isalpha(<ВырC>) */
/* Функция возвращает значение TRUE, если <вырC> начинается с буквы. */
/************************************************************************/
Function Isalpha($Letter)
{
$ct_res=ereg("[A-Za-zА-Яа-я]", $Letter{0});
return $ct_res;
} /* End Isalpha */
/*************************************************************************/
/* Lexical_Analyzer */
/* Лексический анализатор: Выполняет первую стадию транслятора - */
/* лексический анализ. Осуществляет просмотр исходного текста */
/* программы на МИЛАНе, распознавание и классификацию лексем. */
/* Строит: */
/* массив лексем; */
/* массив идентификаторов; */
/* массив констант; */
/* Производит расстановку ссылок для передачи управления. */
/* Входные данные: текст с программой на МИЛАНе. */
/* Результат: массив лексем, массив идентификаторов и констант. */
/*************************************************************************/
function Lexical_Analyzer()
{
/************************************************************************/
/* Found_in_Table_Key_Words */
/* Функция бинарного поиска в таблице ключевых слов */
/* Вход: Word - выражение символьного типа, Code - код найденного */
/* ключевого слова */
/* Выход: Функция возвращает значение TRUE, если Word ключевое слово, и */
/* FALSE - в противном случае. В переменной Code содержится код */
/* ключевого слова, или 0 в противном случае. */
/************************************************************************/
Function Found_in_Table_Key_Words($Word, &$Code)
{
global $Table_Key_Words;
$k=0;
$m=1;
$n=MAX_KEY_WORDS;
while ($m<=$n):
$k=intval($m+($n-$m) / 2);
if ($Word==$Table_Key_Words[$k]->Key_Word)
{
$Code=$Table_Key_Words[$k]->Code_Key_Word;
return TRUE;
}
elseif ($Word>$Table_Key_Words[$k]->Key_Word)
{
$m=$k+1;
}
else
$n=$k-1;
endwhile;
return FALSE;
}
/***********************************************************************/
/* Found_in_Table_Identifiers(<ВырC>) */
/* Функция для проверки идентификатора в таблице идентификаторов. */
/* Аргументы: <вырC>, содержащее имя идентификатора. */
/* Результат: номер идентификатора в таблице идентификаторов */
/* ( 0 - если идентификатор <ВырC> отсутствует в */
/* таблице идентификаторов). */
/***********************************************************************/
Function Found_in_Table_Identifiers($Identifier)
{
global $Tab_Identifiers;
global $Number_Identifiers;
for( $i=1;$i<=$Number_Identifiers;$i++)
{
if ($Tab_Identifiers[$i]==$Identifier)
return $i;
}
return 0;
} /* End Found_in_Table_Identifiers */
/*Функция Вывода сообщения об ошибке */
function Print_Error_Message()
{
global $Code_Error;
if ($Code_Error>-1)
{
Print_Error(1);
return 0;
}
//Если ошибок нет, то нормальное завершение лексического анализа
End_Lexical_Analyzer();
}
//Функция выхода из Лексического Анализатора
function End_Lexical_Analyzer()
{
global $Number_Lexems_Programm;
global $Number_Lexem;
global $Code_Error;
$Number_Lexems_Programm=$Number_Lexem;
/* Расстановка ссылок для операторов цикла и развилки */
Setup_Refference();
/* Проверка на ошибки, появившиеся в процессе расстановки ссылок */
if ($Code_Error>-1)
{
Print_Error(2);
return 0;
}
/* Печать таблицы массива лексем */
global $ct_milanMode;
global $ct_buf;
if($ct_milanMode==0)
{
Print_Tab_Lexems();
/* Печать таблицы массивов идентификаторов и констант */
Print_Tab_Identifiers_Constants();
/* Закрытие файла с программой на языке МИЛАН */
/* функция y10: нормальное завершение работы лексического анализатора */
global $Tab_Identifiers;
global $Tab_Constants;
global $ct_TabLEX_Value_str;
global $ct_TabLEX_Code_str;
//поля типа hidden используются для сохранения данных полученных в результате работы лексического анализатора $Tab_Constants, $Tab_Identifiers
print (
"<br><hr><br><div align=\"center\"><font color=\"blue\"> НОРМАЛЬНОЕ ЗАВЕРШЕНИЕ РАБОТЫ ЛЕКСИЧЕСКОГО АНАЛИЗАТОРА</font><br><br>
<form id=\"sourceform\" name=\"sourceform\" action='MILAN.PHP' method=\"post\" >
<input name=\"source\" type=\"hidden\" value='".$ct_buf."'> <!--поле хранит исходный код программы -->
<input name=\"lex_code\" type=\"hidden\" value='".$ct_TabLEX_Code_str."'> <!--поле хранит значения CODE таблицы лексем -->
<input name=\"lex_value\" type=\"hidden\" value='".$ct_TabLEX_Value_str."'> <!--поле хранит значения VALUE таблицы лексем -->
<input name=\"tab_ident\" type=\"hidden\" value='" .join('%',$Tab_Identifiers). "'> <!--поле хранит данные таблицы идентификаторов -->
<input name=\"tab_const\" type=\"hidden\" value='" .join('%',$Tab_Constants). "'> <!--поле хранит данные таблицы констант -->
<input name=\"next\" type=\"submit\" value=\"Далее\" align=\"center\" size=\"40\">
<input name=\"mode\" type=\"hidden\" value=\"1\"> <!--поле хранит текущий режим работы скрипта -->
</form></div> "
);
}
return 0;
}
/************************************************************************/
/* Letter; */
/* Процедура для выделения символов ключевого слова или */
/* идентификатора. Занесение в массив лексем кода и значения */
/* лексемы (ключевого слова или идентификатора). */
/* Аргументы: нет аргументов. */
/* Результат: нет результата. */
/************************************************************************/
Function Letter()
{
global $Input_Letter;
global $Current_Lexem;
global $Number_Identifiers;
global $Position;
global $Code_Error;
global $Tab_Identifiers;
/* Начало процедуры Letter */
$Word = '';
$Code_Word = 0;
$Position_ = 0;
/* функция у4: накопление символов ключевого слова или идентификатора */
$Word = $Word . $Input_Letter;
/* функция у1: прочитать следующий символ */
Read($Input_Letter);
$Position_++;
/* Выделить ключевое слово или идентификатор */
while ((Isalpha($Input_Letter)) || (Isdigit($Input_Letter))):
/* функция у4: накопление символов ключевого слова или идентификатора */
$Word=$Word . $Input_Letter;
/* функция у1: прочитать следующий символ */
Read($Input_Letter);
$Position_++;
endwhile;
/* функция у5: проверка на принадлежность */
/* выделенного слова к ключевым словам */
if (Found_in_Table_Key_Words($Word, $Code_Word))
{
/* функция у11: формирование лексемы */
$Current_Lexem->Code = $Code_Word;
$Current_Lexem->Value = 0;
}
/* функция у6: проверка на принадлежность */
/* выделенного слова к идентификаторам */
elseif (Found_in_Table_Identifiers($Word)>0)
{
/* функция у11: формирование лексемы */
$Current_Lexem->Code = 19;
$Current_Lexem->Value = Found_in_Table_Identifiers($Word);
}
elseif ($Number_Identifiers<MAX_IDENTIFIERS)
{
/* запись выделенного слова в таблицу идентификаторов */
$Number_Identifiers++;
$Tab_Identifiers[$Number_Identifiers]=$Word;
/* функция у11: формирование лексемы */
$Current_Lexem->Code=19;
$Current_Lexem->Value=$Number_Identifiers;
}
else
/* Превышение максимального количества идентификаторов */
$Code_Error=1;
if ($Code_Error==-1)
$Position+=$Position_;
} /* End Letter */
/***********************************************************************/
/* Found_in_Table_Constants(<ВырC>) */
/* Функция для проверки константы в таблице констант. */
/* Аргументы: <вырC>, содержащее константу. */
/* Результат: номер константы в таблице констант */
/* ( 0 - если константа <ВырC> отсутствует в таблице */
/* констант). */
/***********************************************************************/
Function Found_in_Table_Constants($Constant)
{
//глобальные переменные
global $Number_Constants;
global $Constant_Value;
global $Tab_Constants;
for($i=1;$i<= $Number_Constants;$i++)
{
$Constant_Value=intval($Constant);
if ($Tab_Constants[$i]==$Constant_Value)
return $i;
}
return 0;
} /* End Found_in_Table_Constants */
/************************************************************************/
/* Digit; */
/* Процедура для выделения символов константы, проверки в таблице */
/* констант и занесения в таблицу. */
/* Аргументы: нет аргументов. */
/* Результат: нет результата. */
/************************************************************************/
Function Digit()
{
/* Начало процедуры Digit */
//глобальные переменные
global $Current_Lexem;
global $Code_Error;
global $Tab_Constants;
global $Input_Letter;
global $Number_Constants;
//локальные переменные
$Constant_Value = 0;
$Word = '';
/* функция у7: накопление символов константы */
$Word = $Word . $Input_Letter;
$Position_=0;
/* функция у1: прочитать следующий символ */
Read($Input_Letter);
$Position_++;
/* Выделить константу */
while (Isdigit($Input_Letter)):
/* функция у7: накопление символов константы */
$Word=$Word . $Input_Letter;
/* функция у1: прочитать следующий символ */
Read($Input_Letter);
$Position_++;
endwhile;
/* функция у8: проверка на принадлежность */
/* выделенной константы таблице констант */
if (Found_in_Table_Constants($Word)>0)
{
/* функция у11: формирование лексемы */
$Current_Lexem->Code=20;
$Current_Lexem->Value=Found_in_Table_Constants($Word);
}
elseif ($Number_Constants<MAX_CONSTANTS)
{
/* запись выделенной константы в таблицу констант */
$Number_Constants++;
$Constant_Value=intval($Word);
$Tab_Constants[$Number_Constants]=$Constant_Value;
/* функция у11: формирование лексемы */
$Current_Lexem->Code=20;
$Current_Lexem->Value=$Number_Constants;
}
else
/* Превышение максимального количества констант */
$Code_Error=2;
global $Position;
if ($Code_Error==-1)
$Position=$Position+$Position_;
return 0;
} /* End Digit */
/************************************************************************/
/* Setup_Refference */
/* Процедура расстановки ссылок: */
/* DO-->ENDDO+1, ENDDO-->WHILE+1 */
/* THEN-->ELSE+1 */
/* THEN-->ENDIF+1, ELSE-->ENDIF+1 */
/* {-->CASE */
/* :-->CASE, :-->DEFAUT, :-->} */
/* FOR --> ENDFOR+1 */
/* ENDFOR --> TO+1 */
/* Аргументы: Массив лексем. */
/* Результат: Массив лексем с расставленными ссылками. */
/************************************************************************/
function Setup_Refference()
{
/* функция y0: подготовка (инициализация стеков и переменных), */
/* номер очередной лексемы Number_Lexem=1, прочитать лексему с номером */
/* Number_Lexem */
//Глобальные переменные
global $Number_Lexem;
global $Tab_Lexems;
global $Code_Error;
global $Number_Lexems_Programm;
//Локальные переменные
$r=0;
$s=0;
$Top_do = 0;
$Top_if = 0;
$Top_case= 0;
$Top_to = 0;
$Stek_if = Array();
$Stek_do = Array();
$Stek_case=Array();
$Stek_to =Array();
$Number_Lexem = 1;
Stek_Integer(0,$Stek_do,$Top_do,$r);
Stek_Integer(0,$Stek_if,$Top_if,$s);
Stek_Integer(0,$Stek_case,$Top_case,$s);
Stek_Integer(0,$Stek_to, $Top_to, $s);
do
{
switch($Tab_Lexems[$Number_Lexem]->Code):
Case _COLON_ :
/* функция у8: занести значение $Number_Lexem в стек*/
/* $Stek_case ($Number_Lexem-->$Stek_case) */
if (!Stek_Integer(2,$Stek_case,$Top_case,$Number_Lexem))
{
/* Переполнение стека CASE*/
$Code_Error=45;
return 0;
}
break;
Case _BRACE_OPEN_ :
/* функция у8: занести значение $Number_Lexem в стек*/
/* $Stek_case ($Number_Lexem-->$Stek_case) */
if (!Stek_Integer(2,$Stek_case,$Top_case,$Number_Lexem))
{
/* Переполнение стека CASE*/
$Code_Error=45;
return 0;
}
break;
Case _CASE_ :
/* функция у9: снять вершину стека $Stek_case в переменную */
/* $r ($r<$Stek_case), присвоить значение $Number_Lexem */
/* лексеме c номером $r [:>CASE, :>DEFAUT, :>} ] */
/* ($Tab_Lexems[$r]->Value=$Number_Lexem). */
if (!Stek_Integer(1,$Stek_case,$Top_case,$r))
{
/* Недостача элементов в стеке $Stek_case*/
$Code_Error=46;
return 0;
}
$Tab_Lexems[$r]->Value=$Number_Lexem;
break;
Case _DEFAUT_ :
/* функция у9: снять вершину стека $Stek_case в переменную */
/* $r ($r<$Stek_case), присвоить значение $Number_Lexem */
/* лексеме c номером $r [:>CASE, :>DEFAUT, :>} ] */
/* ($Tab_Lexems[$r]->Value=$Number_Lexem). */
if (!Stek_Integer(1,$Stek_case,$Top_case,$r))
{
/* Недостача элементов в стеке $Stek_case*/
$Code_Error=46;
return 0;
}
$Tab_Lexems[$r]->Value=$Number_Lexem;
break;
Case _BRACE_CLOSE_ :
/* функция у9: снять вершину стека $Stek_case в переменную */
/* $r ($r<$Stek_case), присвоить значение $Number_Lexem */
/* лексеме c номером $r [:>CASE, :>DEFAUT, :>} ] */
/* ($Tab_Lexems[$r]->Value=$Number_Lexem). */
if (!Stek_Integer(1,$Stek_case,$Top_case,$r))
{
/* Недостача элементов в стеке $Stek_case*/
$Code_Error=46;
return 0;
}
$Tab_Lexems[$r]->Value=$Number_Lexem;
break;
Case _WHILE_ :
/* функция y1: значение $Number_Lexem занести */
/* стек $Stek_do ($Number_Lexem-->$Stek_do) */
if (!Stek_Integer(2,$Stek_do,$Top_do,$Number_Lexem))
{
/* Переполнение стека DO*/
$Code_Error=4;
return 0;
}
/* функция y7: $Number_Lexem++, */
/* прочитать очередную лексему с номером $Number_Lexem */
$Number_Lexem++;
while ($Tab_Lexems[$Number_Lexem]->Code!=_DO_):
/* функция y7: Number_Lexem=Number_Lexem+1, */
/* прочитать очередную лексему с номером $Number_Lexem */
$Number_Lexem++;
if ($Number_Lexem>$Number_Lexems_Programm)
{
/* Несоответствие в операторах WHILE-DO-OD */
$Code_Error=10;
return 0;
}
endwhile;
/* функция y1: значение $Number_Lexem занести */
/* стек $Stek_do ($Number_Lexem-->$Stek_do) */
if (!Stek_Integer(2,$Stek_do,$Top_do,$Number_Lexem))
{
/* Переполнение стека DO */
$Code_Error=4;
return 0;
}
break;
Case _ENDDO_ :
/* функция y2: снять вершину стека $Stek_do в */
/* переменную $s ($s<--$Stek_do), снять вершину */
/* стека $Stek_do в переменную $r ($r<--$Stek_do), */
/* значение $r+1 присвоить лексеме */
/* с номером $Number_Lexem [ENDDO-->WHILE+1] */
/* ($Tab_Lexems[$Number_Lexem]->Value=r+1), */
/* значение Number_Lexem+1 присвоить лексеме */
/* с номером s [DO-->ENDDO+1] */
/* ($Tab_Lexems[$s]->Value=$Number_Lexem+1. */
if (!Stek_Integer(1,$Stek_do,$Top_do,$s))
{
/* Нехватка элементов в стеке DO */
$Code_Error=5;
return 0;
}
if (!Stek_Integer(1,$Stek_do,$Top_do,$r))
{
/* Нехватка элементов в стеке DO */
$Code_Error=5;
return 0;
}
/* ENDDO-->WHILE+1*/
$Tab_Lexems[$Number_Lexem]->Value=$r+1;
/* DO-->ENDDO+1 */
$Tab_Lexems[$s]->Value=$Number_Lexem+1;
break;
Case _IF_ :
/* функция y7: $Number_Lexem++, */
/* прочитать очередную лексему с номером $Number_Lexem */
$Number_Lexem++;
while ($Tab_Lexems[$Number_Lexem]->Code!=_THEN_):
/* функция y7: $Number_Lexem++, */
/* прочитать очередную лексему с номером $Number_Lexem */
$Number_Lexem++;
if ($Number_Lexem>$Number_Lexems_Programm)
{
/* Несоответствие операторах IF-THEN-ELSE-ENDIF */
$Code_Error=11;
return 0;
}
endwhile;
/* функция y3: значение $Number_Lexem занести */
/* стек $Stek_if ($Number_Lexem-->$Stek_if) */
if (!Stek_Integer(2,$Stek_if,$Top_if,$Number_Lexem))
{
/* Переполнение стека IF */
$Code_Error=7;
return 0;
}
break;
Case _ELSE_ :
/* функция y4: снять вершину стека $Stek_if в */
/* переменную $r ($r<--$Stek_if), присвоить */
/* значение $Number_Lexem+1 лексеме c номером */
/* r [THEN-->ELSE+1] */
/* ($Tab_Lexems[$r]->Value=$Number_Lexem+1), */
/* занести в $Stek_ if значение Number_Lexem */
/* ($Number_Lexem-->$Stek_if) */
if (!Stek_Integer(1,$Stek_if,$Top_if,$r))
{
/* Нехватка элементов в стеке IF */
$Code_Error=8;
return 0;
}
/* THEN-->ELSE+1 */
$Tab_Lexems[$r]->Value=$Number_Lexem+1;
if (!Stek_Integer(2,$Stek_if,$Top_if,$Number_Lexem))
{
/* Переполнение стека IF */
$Code_Error=7;
return 0;
}
break;
Case _ENDIF_ :
/* функция y5: снять вершину стека $Stek_if в */
/* переменную $r ($r<--$Stek_if), присвоить */
/* значение $Number_Lexem+1 лексеме c номером */
/* $r [THEN-->ENDIF+1, ELSE-->ENDIF+1] */
/* ($Tab_Lexems[$r]->Value=$Number_Lexem+1) */
/* занести в $Stek_ if значение Number_Lexem */
/* ($Number_Lexem-->$Stek_if) */
if (!Stek_Integer(1,$Stek_if,$Top_if,$r))
{
/* Нехватка элементов в стеке IF */
$Code_Error=8;
return 0;
}
/* THEN-->ENDIF+1, ELSE -->ENDIF+1 */
$Tab_Lexems[$r]->Value=$Number_Lexem+1;
break;
Case _TO_ :
/* функция y10: */
if (!Stek_Integer(2,$Stek_to,$Top_to,$Number_Lexem))
{
/* Переполнение стека TO*/
$Code_Error=55;
return 0;
}
break;
Case _ENDFOR_ :
/* функция y11: */
if (!Stek_Integer(1,$Stek_to,$Top_to,$r))
{
/* Нехватка элементов в стеке TO*/
$Code_Error=56;
return 0;
}
$Tab_Lexems[$r]->Value=$Number_Lexem+1;
$Tab_Lexems[$Number_Lexem]->Value=$r+1;
break;
endswitch;
/* функция y7: $Number_Lexem++, */
/* прочитать очередную лексему с номером */
$Number_Lexem++;
}
while ($Number_Lexem<=$Number_Lexems_Programm);
if ($Top_if!=0)
{
/* Несоответствие в операторах IF-THEN-ELSE-ENDIF */
$Code_Error=11;
}
if ($Top_do!=0)
{
/* Несоответствие в операторах WHILE-DO-OD */
$Code_Error=10;
}
if ($Top_case!=0)
{
/* Несоответствие в операторах SWITH-CASE-DEFAUT */
$Code_Error=47;
}
if ($Top_to!=0)
{
/* Несоответствие в операторах FOR-TO-ENDFOR */
$Code_Error=54;
}
} /* End Setup_Refference */
/************************************************************************/
/* Print_Tab_Lexems */
/* Процедура печати таблицы массива лексем. */
/* Аргументы: нет аргументов. */
/* Результат: Высвечивание на экране таблицы. */
/************************************************************************/
Function Print_Tab_Lexems()
{
$Number = '';
$Number_ = '';
$Zastav = ''; /* Шапка таблицы массива лексем */
$TabLex = ''; /* Таблица массива лексем */
global $Number_Lexems_Programm;
global $Tab_Lexems;
global $ct_TabLEX_Code_str;
global $ct_TabLEX_Value_str;
echo '<br><H2> <div align="center">РЕЗУЛЬТАТ РАБОТЫ ЛЕКСИЧЕСКОГО АНАЛИЗАТОРА</div></H2><br><hr><br>';
/* Начало процедуры Print_Tab_Lexems */
/* Формирование шапки таблицы массива лексем */
$Zastav = '<table border=1 width="450" align="center"><tr><td colspan=19><div align="center">Т А Б Л И Ц А Л Е К С Е М</div></td></tr>';
$Zastav .= '<tr><td> Номер </td>';
$End=intval($Number_Lexems_Programm /10)+1;
for ($i=0;$i<=9;$i++)
{
$Zastav .='<td align="center"> ' . $i . '</td>';
}
$Zastav .= '</tr>';
/* печать таблицы массива лексем */
/* Вывод содержимого таблицы */
for ($i=1; $i<=$End;$i++)
{
$ct_Pos=($i-1)*10;
$TabLex= '<tr><td align="center">'. strval($ct_Pos) . '</td>';
for ($j=0;$j<=9;$j++)
{
if ((($i==1) && ($j==0)) || ($Tab_Lexems[$ct_Pos+$j]->Code)=='')
$TabLex .='<td> </td>';
else
{
$Number = $Tab_Lexems[$ct_Pos+$j]->Code;
$Number_= $Tab_Lexems[$ct_Pos+$j]->Value;
$ct_TabLEX_Code_str.= $Number.'%';
$ct_TabLEX_Value_str.= $Number_.'%';
$TabLex .='<td align="center">' . Space(2-strlen($Number)) . $Number . ',' . Space(2-strlen($Number_)) . $Number_ . '</td>';
}
}
$Zastav .= $TabLex .'</tr>';
}
$Zastav .= '</table>';
echo ($Zastav);
} /* End Print_Tab_Lexems */
/************************************************************************/
/* Print_Tab_Identifiers_Constants */
/* Процедура печати таблицы массивов идентификаторов и констант. */
/* Аргументы: нет аргументов. */
/* Результат: Высвечивание на экране таблиц. */
/************************************************************************/
Function Print_Tab_Identifiers_Constants()
{
$Number='';
$Number_='';
/* Таблица массивов идентификаторов и констант */
$Tab_Identifiers_Constants = '';
global $Tab_Constants;
global $Tab_Identifiers;
global $Number_Identifiers;
global $Number_Constants;
/* Начало процедуры Print_Tab_Identifiers_Constatns */
/* Формирование таблицы массива идентификаторов */
$Tab_Identifiers_Constants = '<br><br><table border=1 width="450" align="center"><tr><td colspan=2 align="center">МАССИВ ИДЕНТИФИКАТОРОВ </td></tr>';
$Tab_Identifiers_Constants .= '<tr><td align="center"> Номер </td><td align="center"> ИДЕНТИФИКАТОР </td></tr>';
for($i=1;$i<=$Number_Identifiers;$i++)
{
$Tab_Identifiers_Constants .= '<tr><td align="center">' . $i . '</td><td align="center">' . $Tab_Identifiers[$i] . '</td></tr>';
}
/* Формирование таблицы массива констант */
$Tab_Identifiers_Constants .= '</table><br><br><table border=1 width="450" align="center"><tr><td colspan=2 align="center">МАССИВ КОНСТАНТ </td></tr>';
$Tab_Identifiers_Constants .= '<tr><td align="center"> Номер </td><td align="center"> КОНСТАНТА </td></tr>';
for($i=1;$i<=$Number_Constants;$i++)
{
$Tab_Identifiers_Constants .= '<tr><td align="center">' . $i . '</td><td align="center">' . $Tab_Constants[$i] . '</td></tr>';
}
$Tab_Identifiers_Constants .= '</table>';
echo($Tab_Identifiers_Constants);
} /* Print_Tab_Identifiers_Constants */
/* Основной блок Лексического Анализатора */
/* функция у0: подготовка (инициализация таблиц и переменных) */
global $Code_Error;
global $Tab_Lexems;
global $Input_Letter;
global $Number_Lexems_Programm;
global $Number_Lexem;
global $Number_Identifiers;
global $Number_Constants;
global $Number_String;
global $Position;
global $Current_Lexem;
/* функция у1: чтение следующего символа программы на языке МИЛАН */
if (Read($Input_Letter)==0)
{
echo('ОШИБКА: Отсутствуют данные для разбора.');
exit; // Завершение работы интерпретатора
}
$Position=0;
$Number_String=1;
$ct_spec= '['.Chr(9). Chr(10).Chr(13). Chr(32).']';
do
{
/* Игнорирование спец. символов и пробела */
while (ereg($ct_spec,$Input_Letter{0}) )
{
switch (ord($Input_Letter{0})):
case 9 : /* функция y2: увеличение счётчика текущей позиции */
/* ($Position=$Position+1) */
$Position++;
break;
case 13 :
/* функция y3: переход на новую строку в программе, */
/* увеличение счётчика текущей строки, и сброс */
/* счётчика позиции ( $Number_String=$Number_String+1,*/
/* Position=0) */
$Number_String++;
$Position=0;
break;
case 32 : /* функция y2: увеличение счётчика текущей позиции $Position++ */
$Position++;
break;
endswitch;
/* функция у1: чтение следующего символа программы на языке МИЛАН */
Read($Input_Letter);
}
if(isAlpha($Input_Letter{0})) // если введённый символ является буквой
Letter();
elseif(isDigit($Input_Letter{0})) // если введённый символ является цифрой
Digit();
else
{
switch ($Input_Letter{0}):
Case ';' :
/* функция у11: формирование лексемы */
$Current_Lexem->Code=12;
$Current_Lexem->Value=0;
/* функция у1: чтение следующего символа */
Read($Input_Letter);
$Position++;
break;
Case '=' :
/* функция у11: формирование лексемы */
$Current_Lexem->Code=13;
$Current_Lexem->Value=0;
/* функция у1: чтение следующего символа */
Read($Input_Letter);
$Position++;
break;
Case '>' :
/* функция у1: чтение следующего символа */
Read($Input_Letter);
$Position++;
if ($Input_Letter=='=')
{
/* функция у11: формирование лексемы */
$Current_Lexem->Code=13;
$Current_Lexem->Value=4;
/* функция у1: чтение следующего символа */
Read($Input_Letter);
$Position++;
}
else
{
/* функция у11: формирование лексемы */
$Current_Lexem->Code=13;
$Current_Lexem->Value=2;
}
break;
Case '<' :
/* функция у1: чтение следующего символа */
Read($Input_Letter);
$Position++;
switch ($Input_Letter):
case '>' :
/* функция у11: формирование лексемы */
$Current_Lexem->Code=13;
$Current_Lexem->Value=1;
/* функция у1: чтение следующего символа */
Read($Input_Letter);
$Position=$Position+1;
break;
case '=' :
/* функция у11: формирование лексемы */
$Current_Lexem->Code=13;
$Current_Lexem->Value=5;
/* функция у1: чтение следующего символа */
Read($Input_Letter);
$Position=$Position+1;
break;
default:
/* функция у11: формирование лексемы */
$Current_Lexem->Code=13;
$Current_Lexem->Value=3;
break;
endswitch;
break;
Case '+' :
/* функция у11: формирование лексемы */
$Current_Lexem->Code=14;
$Current_Lexem->Value=0;
/* функция у1: чтение следующего символа */
Read($Input_Letter);
$Position++;
break;
Case '-' :
/* функция у1: чтение следующего символа */
Read($Input_Letter);
$Position++;
if ($Input_Letter=='-')
{
/* функция у11: формирование лексемы */
$Current_Lexem->Code=28;
$Current_Lexem->Value=0;
/* функция у1: чтение следующего символа */
Read($Input_Letter);
$Position++;
}
else
{
/* функция у11: формирование лексемы */
$Current_Lexem->Code=14;
$Current_Lexem->Value=1;
}
break;
Case '*' :
/* функция у11: формирование лексемы */
$Current_Lexem->Code=15;
$Current_Lexem->Value=0;
/* функция у1: чтение следующего символа */
Read($Input_Letter);
$Position++;
break;
Case '/' :
/* функция у11: формирование лексемы */
$Current_Lexem->Code=15;
$Current_Lexem->Value=1;
/* функция у1: чтение следующего символа */
Read($Input_Letter);
$Position++;
break;
Case '{' :
/* функция у1: чтение предыдущего символа символа */
Read($Input_Letter);
$Position--;
if ($Input_Letter==';')
while($Input_Letter!='}')
{/* функция у1: чтение следующего символа */
Read($Input_Letter);
$Position=$Position+1; }
else
/* функция у11: формирование лексемы */
$Current_Lexem->Code=28;
$Current_Lexem->Value=0;
/* функция у1: чтение следующего символа */
Read($Input_Letter);
$Position++;
break;
Case '}' :
/* функция у11: формирование лексемы */
$Current_Lexem->Code=29;
$Current_Lexem->Value=0;
/* функция у1: чтение следующего символа */
Read($Input_Letter);
$Position++;
break;
Case ':' :
/* функция у1: чтение следующего символа */
Read($Input_Letter);
$Position++;
if ($Input_Letter=='=')
{
/* функция у11: формирование лексемы */
$Current_Lexem->Code=16;
$Current_Lexem->Value=0;
/* функция у1: чтение следующего символа */
Read($Input_Letter);
$Position++;
}
else
{
/* функция у11: формирование лексемы */
$Current_Lexem->Code=31;
$Current_Lexem->Value=0;
}
break;
Case '(' :
/* функция у11: формирование лексемы */
$Current_Lexem->Code=18;
$Current_Lexem->Value=0;
/* функция у1: чтение следующего символа */
Read($Input_Letter);
$Position++;
break;
Case ')' :
/* функция у11: формирование лексемы */
$Current_Lexem->Code=18;
$Current_Lexem->Value=0;
/* функция у1: чтение следующего символа */
Read($Input_Letter);
$Position++;
break;
/* Признак конца программы */
Case Chr(26) :
End_Lexical_Analyzer();
return 0;
default: /* Неопознанный символ в программе */
$Code_Error=0;
endswitch;
}
/* Переполнение массива лексем */
if ($Number_Lexem+1>MAX_LEXEMS)
$Code_Error=3;
/* Проверка на ошибку */
if ($Code_Error>-1)
{
Print_Error_Message();
return 0;
}
/* функция у9: запись сформированной лексемы в массив лексем */
$Number_Lexem++;
$Tab_Lexems[$Number_Lexem]->Code=$Current_Lexem->Code;
$Tab_Lexems[$Number_Lexem]->Value=$Current_Lexem->Value;
}while (TRUE);
}
/*************************************************************************/
/* Syntactical_Analyzer */
/* Процедура синтаксического анализа, совмещенная со стадией */
/* генерации действий. */
/* Входные данные: массив лексем (после сканера), */
/* массив идентификаторов (после сканера), */
/* массив констант (после сканера). */
/* */
/* Выходные данные: Выполнение программы на языке МИЛАН. */
/* */
/* Обработка конструкций языка осуществляется процедурами: */
/* ProcedureL, ProcedureS, ProcedureB, ProcedureE, */
/* ProcedureT, ProcedureP. */
/* Процедура Syntactical_Analyzer использует стеки: */
/* $StekRes - стек результатов вычислений; */
/* $StekIdent - стек идентификаторов; */
/* $StekMul - стек для операций типа умножения; */
/* $StekSum - стек для операций типа сложения; */
/* $StekRel - стек для операций типа отношения. */
/*************************************************************************/
//Объявление глобальных переменных
$StekRes = Array();
$StekIdent = Array();
$StekMul = Array();
$StekSum = Array();
$StekRel = Array();
$StekCaseValue = Array();
$StekDefaultValue = Array();
$ArrIdent = Array();
$TopRes=0;
$TopCaseValue=0;
$TopDefaultValue=0;
$TopIdent=0;
$TopMul=0;
$TopSum=0;
$TopRel=0;
$Ai=0;
$Bi=0;
Function Syntactical_Analyzer()
{
/*************************************************************************/
/* Процедура ProcedureP - обработка конструкции <множитель> */
/* <множитель>::=<идентификатор>|<константа>|READ|(<выражение>) */
/*************************************************************************/
Function ProcedureP()
{
global $Tab_Lexems;
global $Tab_Constants;
global $Number_Lexem;
global $StekRes;
global $TopRes;
global $ArrIdent;
global $Code_Error;
$NomIdent =0;
$Cifra =0;
switch ($Tab_Lexems[$Number_Lexem]->Code):
Case _DECREMENT_ :
/*Обработка преддекремента*/
ProcedureX();
/* y1: занесение в стек StekRes идентификатора $Tab_Lexems[$Number_Lexem]->Value */
$NomIdent=$Tab_Lexems[$Number_Lexem]->Value;
if (!Stek_Integer(2, $StekRes, $TopRes, $ArrIdent[$NomIdent]))
{
/* Переполнение стека $StekRes */
$Code_Error=26;
return 0;
}
/* функция y4: чтение следующей лексемы ($Number_Lexem++)*/
$Number_Lexem++;
/*Обработка возможного постдекремента*/
ProcedureY();
return 0;
break;
Case _IDENTIFIER_ :
/* y1: занесение в стек StekRes идентификатора $Tab_Lexems[$Number_Lexem]->Value */
$NomIdent=$Tab_Lexems[$Number_Lexem]->Value;
if (!Stek_Integer(2, $StekRes, $TopRes, $ArrIdent[$NomIdent]))
{
/* Переполнение стека $StekRes */
$Code_Error=26;
return 0;
}
/* функция y4: чтение следующей лексемы ($Number_Lexem++)*/
$Number_Lexem++;
/*Обработка возможного постдекремента*/
ProcedureY();
return 0;
break;
Case _CONSTANT_ :
$NomIdent=$Tab_Lexems[$Number_Lexem]->Value;
/* y2: занесение в стек $StekRes константы $Tab_Lexems[$Number_Lexem].Value;*/
if (!Stek_Integer(2, $StekRes, $TopRes, $Tab_Constants[$NomIdent]))
{
/* Переполнение стека $StekRes */
$Code_Error=26;
return 0;
}
/* функция y4: чтение следующей лексемы */
/* ($Number_Lexem++) */
$Number_Lexem++;
return 0;
break;
Case _READ_ :
/* y3: прочитать целое число из формы в переменную */
/* $Cifra и положить его в $StekRes ($Cifra-->$StekRes),*/
/* чтение целого числа из формы */
global $ct_buf;
global $ct_readBUF; //$ct_readBUF - переменная является стеком для чтения данных вида "1%2%11"
global $ct_readCount;
global $Tab_Identifiers;
global $Tab_Constants;
global $ct_TabLEX_Value_str;
global $ct_TabLEX_Code_str;
$len = count($ct_readBUF); //количество элементов в массиве $ct_readBUF
if($ct_readCount>=$len)
{
echo('<html>
<head>
<title>Ожидается ввод данных от пользователя:</title>
</head>
<body>
<br><h2>ФОРМА ДЛЯ ВВОДА ДАННЫХ</h2> Запрос №: '.($len+1).'<hr><br>');
echo('ВВЕДИТЕ ЦЕЛОЕ ЧИСЛО:<br><br> ');
echo ('<script type="text/javascript">
function ScanForInt() <!--javascript для обработки-->
{
var x=inputform.stdin.value; <!--получаем текущее введённое значение из поля ввода с именем "stdin" в переменную "x"-->
for(i=0;i<=x.length;i++) <!--цикл для прохода по всей строке "x"-->
{
var s=x.substr(i).charCodeAt(); <!--получаем ASCII код i-ого символа-->
if(s<48 || s>57) <!--диапазон кодов (48..57) соответствет в таблице ASCII - целым числам от 0..9 -->
{
alert("Введите целое число"); <!--выдаём сообщение пользователю -->
return false; <!--выходим из скрипта -->
}
}
return x.length>0; <!--возвращаем TRUE, если длина больше 0, иначе FALSE -->
}
</script>
<form name="inputform" action="milan.php" method="POST">
<input type="text" name="stdin" /> <!--в поле с именем "stdin" хранится введённое пользователем число -->
<input name="source" type="hidden" value="'.$ct_buf.'"/> <!--переменная для хранения исходного кода программы MILAN -->
<input name="lex_code" type="hidden" value="'.$ct_TabLEX_Code_str.'"> <!--поле хранит значения CODE таблицы лексем -->
<input name="lex_value" type="hidden" value="'.$ct_TabLEX_Value_str.'"> <!--поле хранит значения VALUE таблицы лексем -->
<input name="tab_ident" type="hidden" value="' .join('%',$Tab_Identifiers). '"> <!--поле хранит данные таблицы идентификаторов -->
<input name="tab_const" type="hidden" value="' .join('%',$Tab_Constants). '"> <!--поле хранит данные таблицы констант -->
<input name="readbuf" type="hidden" value="'. join("%",$ct_readBUF) .'"/> <!--функция join("%",$ct_readBUF) преобразует массив данных в строку разделённую "%" -->
<input name="mode" type="hidden" value="2"> <!--поле хранит текущий режим работы скрипта-->
<!--Кнопка для отправки данных в скрипт "milan.php", в случае получения значения "TRUE" от функции ScanForInt() -->
<input type="button" name="send" value="Отправить" onclick="if(ScanForInt())inputform.submit()">
</form> </body></html>');
exit; //!! производится завершение работы интерпретатора и ожидание ввода данных
}
$Cifra=$ct_readBUF[$ct_readCount++];
if (!Stek_Integer(2, $StekRes, $TopRes, $Cifra))
{
/* Переполнение стека $StekRes */
$Code_Error=26;
return 0;
}
/* функция y4: чтение следующей лексемы ($Number_Lexem++)*/
$Number_Lexem++;
break;
Case _LPAREN_ :
/* функция y4: чтение следующей лексемы ($Number_Lexem++)*/
$Number_Lexem++;
/* Обработка конструкции <выражение> */
ProcedureE();
/* Проверка на ошибки, появившиеся в процессе обработки конструкции <выражение>*/
if ($Code_Error!=-1)
return 0;
if ($Tab_Lexems[$Number_Lexem]->Code==_RPAREN_)
{
/* функция y4: чтение следующей лексемы ($Number_Lexem++)*/
$Number_Lexem++;
}
else
{
/* Конструкция <множитель>. Нет закрывающей скобки. */
$Code_Error=30;
return 0;
}
endswitch;
return 0;
} /* End ProcedureP */
/*************************************************************************/
/* Процедура ProcedureT - обработка конструкции <терм> */
/* <терм>::=<множитель>|<множитель><операция типа умножения><множитель> */
/*************************************************************************/
Function ProcedureT()
{
global $Code_Error;
global $Tab_Lexems;
global $Number_Lexem;
global $StekMul;
global $TopMul;
global $StekRes;
global $TopRes;
global $Bi;
global $Ai;
$c = 0;
$kmul = 0;
/* Обработка конструкции множитель */
ProcedureP();
/* Проверка на ошибки, появившиеся в процессе */
/* обработки конструкции <множитель> */
if ($Code_Error!=-1)
return 0;
while (TRUE)
{
if ($Tab_Lexems[$Number_Lexem]->Code == _MUL_)
{
/* y5: занесение в стек $StekMul значение операции типа умножения */
/* $Tab_Lexems[$Number_Lexem]->Value-->StekMul */
if (!Stek_Integer(2, $StekMul, $TopMul, $Tab_Lexems[$Number_Lexem]->Value))
{
/* Переполнение стека $StekMul */
$Code_Error=28;
return 0;
}
/* функция y4: чтение следующей лексемы ($Number_Lexem++)*/
$Number_Lexem++;
/* Обработка конструкции <множитель> */
ProcedureP();
/* Проверка на ошибки, появившиеся в процессе */
/* обработки конструкции <множитель> */
if ($Code_Error!=-1)
return 0;
/* y6: в переменную $Bi снять элемент со стека $StekRes ($Bi<--$StekRes), */
/* в переменную $Ai снять элемент со стека $StekRes ($Ai<--$StekRes), */
/* в переменную kmul снять элемент со стека $StekMul ($kmul<--$StekMul), */
/* выполнить операцию типа умножение $Ai otu($kmul) $Bi и результат */
/* занести в стек $StekRes */
if (!Stek_Integer(1, $StekRes, $TopRes,$Bi))
{
/* Нехватка элементов в стеке $StekRes */
$Code_Error=16;
return 0;
}
if (!Stek_Integer(1, $StekRes, $TopRes, $Ai))
{
/* Нехватка элементов в стеке $StekRes */
$Code_Error=16;
return 0;
}
if (!Stek_Integer(1, $StekMul, $TopMul, $kmul))
{
/* Нехватка элементов в стеке $StekMul */
$Code_Error=27;
return 0;
}
/* Выполнение умножения */
$c=$Ai*$Bi;
$mode= _SLASH_;
if ($kmul==$mode)
{
if ($Bi!=0)
{
$c=intval($Ai / $Bi); //присвоим $c целую часть от деления $Ai и $Bi
}
else
{
/* Деление на ноль */
$Code_Error=29;
return 0;
}
}
/* занесение результата в стек $StekRes */
if (!Stek_Integer(2, $StekRes, $TopRes, $c))
{
/* Переполнение стека $StekRes */
$Code_Error=26;
return 0;
}
}
return 0;
}
}
/* End ProcedureT */
/*************************************************************************/
/* Процедура ProcedureE - обработка конструкции <выражение> */
/* <выражение>::=<терм>|<операция типа сложения><терм> | */
/* <терм><операция типа сложения><терм> | */
/* <операция типа сложения><терм><операция типа сложения><терм> */
/*************************************************************************/
Function ProcedureE()
{
global $TopSum;
global $TopRes;
global $StekSum;
global $StekRes;
global $Tab_Lexems;
global $Number_Lexem;
global $Code_Error;
global $Ai;
global $Bi;
$c =0;
$ksum =0;
if ($Tab_Lexems[$Number_Lexem]->Value==_SUMM_)
{
/* y7: занесение в стек $StekSum кода операции типа сложения */
if (!Stek_Integer(2, $StekSum, $TopSum, $Tab_Lexems[$Number_Lexem]->Value))
{
/* Переполнение стека $StekSum */
$Code_Error=31;
return 0;
}
/* функция y4: чтение следующей лексемы ($Number_Lexem++)*/
$Number_Lexem++;
/* Обработка конструкции <терм> */
ProcedureT();
/* Проверка на ошибки, появившиеся в процессе */
/* обработки конструкции <терм> */
if ($Code_Error!=-1)
return 0;
/* y8: в переменную ksum снять со стека $StekSum значение */
/* лексемы ots ($ksum<--$StekSum), если ksum=1, то снять */
/* в переменную Ai элемент со стека $Stekres ($Ai<--$StekRes), */
/* сменить знак этого числа и занести его в стек $StekRes */
/* -$Ai-->$StekRes */
if (!Stek_Integer(1, $StekSum, $TopSum, $ksum))
{
/* Нехватка элементов в стеке $StekSum */
$Code_Error=32;
return 0;
}
if ($ksum!=_PLUS_)
{
if (!Stek_Integer(1, $StekRes, $TopRes, $Ai))
{
/* Нехватка элементов в стеке $StekRes */
$Code_Error=16;
return 0;
}
$Ai=-$Ai;
if (!Stek_Integer(2, $StekRes, $TopRes, $Ai))
{
/* Переполнение стека $StekRes */
$Code_Error=26;
return 0;
}
}
}
/* случай отсутствия операции сложения */
/* Обработка конструкции <терм> */
ProcedureT();
/* Проверка на ошибки, появившиеся в процессе */
/* обработки конструкции <терм> */
if ($Code_Error!=-1)
return 0;
while (TRUE):
if ($Tab_Lexems[$Number_Lexem]->Code==_SUMM_)
{
/* y9: занесение в стек $StekSum кода операции типа сложения */
if (!Stek_Integer(2, $StekSum, $TopSum, $Tab_Lexems[$Number_Lexem]->Value))
{
/* Переполнение стека $StekSum */
$Code_Error=31;
return 0;
}
/* функция y4: чтение следующей лексемы ($Number_Lexem++) */
$Number_Lexem++;
/* Обработка конструкции <терм> */
ProcedureT();
/* Проверка на ошибки, появившиеся в процессе */
/* обработки конструкции <терм> */
if ($Code_Error!=-1)
return 0;
/* y10: в переменную $Bi снять элемент со стека $StekRes ($Bi<--$StekRes),*/
/* в переменную $Ai снять элемент со стека $StekRes ($Ai<--$StekRes), */
/* в переменную ksum снять элемент со стека $StekSum ($ksum<--$StekSum), */
/* выполнить операцию типа сложение $Ai ots($ksum) $Bi и результат */
/* занести в стек $StekRes */
if (!Stek_Integer(1, $StekRes, $TopRes, $Bi))
{
/* Нехватка элементов в стеке $StekRes */
$Code_Error=16;
return 0;
}
if (!Stek_Integer(1, $StekRes, $TopRes, $Ai))
{
/* Нехватка элементов в стеке $StekRes */
$Code_Error=16;
return 0;
}
if (!Stek_Integer(1, $StekSum, $TopSum, $ksum))
{
/* Нехватка элементов в стеке $StekSum */
$Code_Error=32;
return 0;
}
$c=$Ai+$Bi;
if ($ksum!=_PLUS_)
$c=$Ai-$Bi;
/* занесение результата в стек $StekRes */
if (!Stek_Integer(2, $StekRes, $TopRes, $c))
{
/* Переполнение стека $StekRes */
$Code_Error=26;
return 0;
}
}
return 0;
endwhile;
} /* End ProcedureE */
/*************************************************************************/
/* Процедура ProcedureB - обработка конструкции <условие> */
/* <условие>::=<выражение><знак отношения><выражение> */
/*************************************************************************/
Function ProcedureB()
{
global $TopSum;
global $TopRes;
global $StekSum;
global $StekRes;
global $StekRel;
global $TopRel;
global $Tab_Lexems;
global $Number_Lexem;
global $Code_Error;
global $Ai;
global $Bi;
$c =0;
$krel =0;
/* Обработка конструкции <выражение> */
ProcedureE();
/* Проверка на ошибки, появившиеся в процессе */
/* обработки конструкции <выражение> */
if ($Code_Error!=-1)
return 0;
if ($Tab_Lexems[$Number_Lexem]->Code==_RELATION_)
{
/* y11: добавление в стек $StekRel значения операции типа отношение */
/* ($Tab_Lexems[$Number_Lexem]->Value-->$StekRel) */
if (!Stek_Integer(2, $StekRel, $TopRel, $Tab_Lexems[$Number_Lexem]->Value))
{
/* Переполнение стека $StekRel */
$Code_Error=24;
return 0;
}
/* функция y4: чтение следующей лексемы ($Number_Lexem++) */
$Number_Lexem++;
/* Обработка конструкции <выражение> */
ProcedureE();
/* Проверка на ошибки, появившиеся в процессе обработки конструкции <выражение> */
if ($Code_Error!=-1)
return 0;
/* y12: в переменную Bi снять элемент со стека $StekRes ($Bi<--$StekRes),*/
/* в переменную $Ai снять элемент со стека StekRes ($Ai<--$StekRes), */
/* в переменную $krel снять элемент со стека $StekRel (krel<--$StekRel), */
/* выполнить операцию сравнения $Ai otn($krel) Bi и результат занести */
/* в стек $StekRes ([0, 1]-->$StekRes) */
if (!Stek_Integer(1, $StekRes, $TopRes, $Bi))
{
/* Нехватка элементов в стеке $StekRes */
$Code_Error=16;
return 0;
}
if (!Stek_Integer(1, $StekRes, $TopRes, $Ai))
{
/* Нехватка элементов в стеке $StekRes */
$Code_Error=16;
return 0;
}
if (!Stek_Integer(1, $StekRel, $TopRel, $krel))
{
/* Нехватка элеметов в стеке $StekRel */
$Code_Error=25;
return 0;
}
/* выполнение сравнения */
switch ($krel):
case _EQUAL_: if ($Ai==$Bi) $c=1;break;
case _NOTEQUAL_: if ($Ai!=$Bi) $c=1;break;
case _GT_: if ($Ai>$Bi) $c=1;break;
case _LT_: if ($Ai<$Bi) $c=1;break;
case _GE_: if ($Ai>=$Bi) $c=1;break;
case _LE_: if ($Ai<=$Bi) $c=1;break;
default:
$c=0;
endswitch;
/* занесение результата в стек $StekRes */
if (!Stek_Integer(2, $StekRes, $TopRes, $c))
{
/* Переполнение стека $StekRes */
$Code_Error=26;
return 0;
}
}
else
{
/* Конструкция <условие>. Неверная операция отношения. */
$Code_Error=23;
return 0;
}
return 0;
} /* End ProcedureB */
/*************************************************************************/
/* Процедура ProcedureS - обработка конструкции */
/* <оператор>::=<идентификатор>:=<выражение> | OUTPUT(<выражение>) | */
/* WHILE <условие> DO <последовательность операторов> ENDDO| */
/* IF <условие> THEN <последовательность операторов> ENDIF | */
/* <последовательность операторов> ENDIF */
/*************************************************************************/
function ProcedureS()
{
global $TopRes;
global $Tab_Constants;
global $StekRes;
global $StekForExit;
global $TopForExit;
global $StekCaseValue;
global $TopCaseValue;
global $TopDefaultValue;
global $StekDefaultValue;
global $Tab_Lexems;
global $Number_Lexem;
global $Code_Error;
global $StekIdent;
global $TopIdent;
global $ArrIdent;
global $Ai;
global $Bi;
global $StekPostDec;
global $StekPostDecCount;
global $TopPostDecCount;
global $TopPostDec;
$ForAi=0;
$ForBi=0;
$ForCi=0;
$ForDi=0;
$ForWhile=1;
$Ai=0;
/*подготовка к работе стека $StekPostDecCount для конкретного оператора */
if (!Stek_Integer(2, $StekPostDecCount, $TopPostDecCount, $Ai))
{
/* Нехватка элементов в стеке $StekCaseValue */
$Code_Error=16;
return 0;
}
switch ($Tab_Lexems[$Number_Lexem]->Code):
case _DECREMENT_ :
/*обработка преддекремента*/
ProcedureX();
/* Проверка на ошибки, появившиеся в процессе */
/* обработки преддекремента */
if ($Code_Error!=-1)
return 0;
/* y13:добавить значение лексемы с номером $Number_Lexem */
/* в стек $StekIdent ($Tab_Lexems[$Number_Lexem]->Value-->$StekIdent)*/
if (!Stek_Integer(2, $StekIdent, $TopIdent,$Tab_Lexems[$Number_Lexem]->Value))
{
/* Переполнение стека $StekIdent */
$Code_Error=14;
Exit;
}
/* функция y4: чтение следующей лексемы ($Number_Lexem++) */
$Number_Lexem++;
/*Обработка возможного постдекремента*/
ProcedureY();
if ($Tab_Lexems[$Number_Lexem]->Code==_ASSIGNMENT_)
{
/* функция y4: чтение следующей лексемы ($Number_Lexem++) */
$Number_Lexem++;
/* Обработка конструкции <выражение> */
ProcedureE();
/* Проверка на ошибки, появившиеся в процессе */
/* обработки конструкции <выражение> */
if ($Code_Error!=-1)
return 0;
}
else
{
/* Конструкция <оператор>. Неверное присваивание.*/
$Code_Error=15;
return 0;
}
/* y14: в переменную $Ai снять элемент со стека $StekRes*/
/* ($Ai<--$StekRes), в переменную $Bi снять со стека */
/* $StekIdent значение лексемы ident ($Bi<--$StekIdent), */
/* идентификатору с номером $Bi, присвоить значение $Ai */
/* $ArrIdent[$Bi]=$Ai */
if (!Stek_Integer(1, $StekRes, $TopRes,$Ai))
{
/* Нехватка элементов в стеке $StekRes */
$Code_Error=16;
return 0;
}
if (!Stek_Integer(1, $StekIdent, $TopIdent, $Bi))
{
/* Нехватка элементов в стеке $StekIdent */
$Code_Error=17;
return 0;
}
$ArrIdent[$Bi]=$Ai;
break;
/* Обработка оператора присваивания */
/* <идентификатор>:=<выражение> */
case _IDENTIFIER_ :
/* y13:добавить значение лексемы с номером $Number_Lexem */
/* в стек $StekIdent ($Tab_Lexems[$Number_Lexem]->Value-->$StekIdent)*/
if (!Stek_Integer(2, $StekIdent, $TopIdent,$Tab_Lexems[$Number_Lexem]->Value))
{
/* Переполнение стека $StekIdent */
$Code_Error=14;
Exit;
}
/* функция y4: чтение следующей лексемы ($Number_Lexem++) */
$Number_Lexem++;
ProcedureY();
if ($Tab_Lexems[$Number_Lexem]->Code==_ASSIGNMENT_)
{
/* функция y4: чтение следующей лексемы ($Number_Lexem++) */
$Number_Lexem++;
/* Обработка конструкции <выражение> */
ProcedureE();
/* Проверка на ошибки, появившиеся в процессе */
/* обработки конструкции <выражение> */
if ($Code_Error!=-1)
return 0;
}
else
{
/* Конструкция <оператор>. Неверное присваивание.*/
$Code_Error=15;
return 0;
}
/* y14: в переменную $Ai снять элемент со стека $StekRes*/
/* ($Ai<--$StekRes), в переменную $Bi снять со стека */
/* $StekIdent значение лексемы ident ($Bi<--$StekIdent), */
/* идентификатору с номером $Bi, присвоить значение $Ai */
/* $ArrIdent[$Bi]=$Ai */
if (!Stek_Integer(1, $StekRes, $TopRes,$Ai))
{
/* Нехватка элементов в стеке $StekRes */
$Code_Error=16;
return 0;
}
if (!Stek_Integer(1, $StekIdent, $TopIdent, $Bi))
{
/* Нехватка элементов в стеке $StekIdent */
$Code_Error=17;
return 0;
}
$ArrIdent[$Bi]=$Ai;
break;
case _OUTPUT_ :
/* функция y4: чтение следующей лексемы ($Number_Lexem++)*/
$Number_Lexem++;
if ($Tab_Lexems[$Number_Lexem]->Code==_LPAREN_)
{
/* функция y4: чтение следующей лексемы ($Number_Lexem++) */
$Number_Lexem++;
/* Обработка конструкции <выражение> */
ProcedureE();
/* Проверка на ошибки, появившиеся в процессе */
/* обработки конструкции <выражение> */
if ($Code_Error!=-1)
return 0;
}
else
{
/* Конструкция <оператор>.Неверный оператор OUTPUT.*/
$Code_Error=18;
return 0;
}
if ($Tab_Lexems[$Number_Lexem]->Code==_RPAREN_)
{
/* функция y4: чтение следующей лексемы ($Number_Lexem++) */
$Number_Lexem++;
/* y15: в переменную $Ai снять элемент со стека StekRes */
/* ($Ai<--$StekRes), напечатать переменную $Ai */
if (!Stek_Integer(1, $StekRes,$TopRes, $Ai))
{
/* Нехватка элементов в стеке $StekRes */
$Code_Error=16;
return 0;
}
echo('
<br>
<hr>
<br>
ВЫВОД: ' . $Ai . '
<br>
');
}
else
{
/* Конструкция <оператор>. Неверный оператор OUTPUT.*/
$Code_Error=18;
return 0;
}
break;
case _WHILE_ :
/* функция y4: чтение следующей лексемы ($Number_Lexem++)*/
$Number_Lexem++;
while (TRUE)
{
/* Обработка конструкции <условие> */
ProcedureB();
/* Проверка на ошибки, появившиеся в процессе */
/* обработки конструкции <условие> */
if ($Code_Error!=-1)
return 0;
/* y16: в переменную $Ai снять элемент со стека StekRes */
/* ($Ai<--$StekRes), если $Ai=1, то это истина, иначе - ложь */
if (!Stek_Integer(1, $StekRes, $TopRes, $Ai))
{
/* Нехватка элементов в стеке $StekRes */
$Code_Error=16;
return 0;
}
if ($Tab_Lexems[$Number_Lexem]->Code==_DO_)
{
/* проверка истинности условия: $Ai==1 (TRUE), */
/* $Ai==0 (FALSE) */
if ($Ai==1) /* обработка TRUE */
{
/* функция y4: чтение следующей лексемы ($Number_Lexem++) */
$Number_Lexem++;
/* Обработка конструкции */
/* <последовательность операторов> */
ProcedureL();
/* Проверка на ошибки, появившиеся в процессе */
/* обработки конструкции */
/* <последовательность операторов> */
if ($Code_Error!=-1)
return 0;
if ($Tab_Lexems[$Number_Lexem]->Code==_ENDDO_)
{
/* y17: перейти на лексему номер */
/* $Tab_Lexems[$Number_Lexem]->Value */
$Number_Lexem=$Tab_Lexems[$Number_Lexem]->Value;
Continue;
}
else
{
/* Конструкция <оператор>. Неверный оператор WHILE. */
$Code_Error=19;
return 0;
}
}
else /* обработка FALSE */
{
/* перейти на лексему номер $Tab_Lexems[$Number_Lexem]->Value */
$Number_Lexem=$Tab_Lexems[$Number_Lexem]->Value;
return 0;
}
}
else
{
/* Конструкция <оператор>. Неверный оператор WHILE. */
$Code_Error=19;
return 0;
}
}
break;
case _IF_ :
/* функция y4: чтение следующей лексемы ($Number_Lexem++) */
$Number_Lexem++;
/* Обработка конструкции <условие> */
ProcedureB();
/* Проверка на ошибки, появившиеся в процессе */
/* обработки конструкции <условие> */
if ($Code_Error!=-1)
return 0;
/* y18: в переменную $Ai снять элемент со стека $StekRes */
/* ($Ai<--$StekRes), если $Ai=1, то это истина, */
/* иначе - ложь */
if (!Stek_Integer(1, $StekRes, $TopRes, $Ai))
{
/* Нехватка элементов в стеке $StekRes */
$Code_Error=16;
return 0;
}
if ($Tab_Lexems[$Number_Lexem]->Code!=_THEN_)
{
/* Конструкция <оператор>. */
/* Отсутствует THEN в операторе IF. */
$Code_Error=20;
return 0;
}
/* проверка истинности условия: $Ai==1 (TRUE), */
/* $Ai==0 (FALSE) */
if ($Ai==1) /* Обработка TRUE */
{
/* функция y4: чтение следующей лексемы ($Number_Lexem++) */
$Number_Lexem++;
/* Обработка конструкции */
/* <последовательность операторов> после ELSE */
ProcedureL();
/* Проверка на ошибки, появившиеся в процессе */
/* обработки конструкции */
/* <последовательность операторов> */
if ($Code_Error!=-1)
return 0;
if ($Tab_Lexems[$Number_Lexem]->Code==_ELSE_)
{
/* y19: перейти на лексему номер $Tab_Lexems[$Number_Lexem]->Value-1 */
/* */
$Number_Lexem=$Tab_Lexems[$Number_Lexem]->Value-1;
if ($Tab_Lexems[$Number_Lexem]->Code==_ENDIF_)
{
/* функция y4: чтение следующей лексемы ($Number_Lexem++)*/
$Number_Lexem++;
return 0;
}
else
{
/* Конструкция <оператор>. */
/* Отсутствует ENDIF в операторе IF.*/
$Code_Error=21;
return 0;
}
}
elseif ($Tab_Lexems[$Number_Lexem]->Code==_ENDIF_)
{
/* функция y4: чтение следующей лексемы ($Number_Lexem++) */
$Number_Lexem++;
return 0;
}
else
{
/* Конструкция <оператор>. */
/* Отсутствует ENDIF в операторе IF.*/
$Code_Error=21;
return 0;
}
}
else /* Обработка FALSE */
{
/* y19: перейти на лексему номер $Tab_Lexems[$Number_Lexem]->Value-1 */
$Number_Lexem=$Tab_Lexems[$Number_Lexem]->Value-1;
if ($Tab_Lexems[$Number_Lexem]->Code==_ELSE_)
{
/* функция y4: чтение следующей лексемы ($Number_Lexem++) */
$Number_Lexem++;
/* Обработка конструкции */
/* <последовательность операторов> после ELSE */
ProcedureL();
/* Проверка на ошибки, появившиеся в процессе */
/* обработки конструкции */
/* <последовательность операторов> */
if ($Code_Error!=-1)
return 0;
if ($Tab_Lexems[$Number_Lexem]->Code==_ENDIF_)
{
/* функция y4: чтение следующей лексемы ($Number_Lexem++) */
$Number_Lexem++;
return 0;
}
else
{
/* Конструкция <оператор>. */
/* Отсутствует ENDIF в операторе IF.*/
$Code_Error=21;
return 0;
}
}
elseif ($Tab_Lexems[$Number_Lexem]->Code==_ENDIF_)
{
/* функция y4: чтение следующей лексемы ($Number_Lexem++) */
$Number_Lexem++;
return 0;
}
else
{
/* Конструкция <оператор>. */
/* Отсутствует ELSE или ENDIF в операторе IF.*/
$Code_Error=22;
return 0;
}
}
break;
case _SWITH_ :
/* функция y4: чтение следующей лексемы ($Number_Lexem++) */
$Number_Lexem++;
if ($Tab_Lexems[$Number_Lexem]->Code==_LPAREN_)
/* функция y4: чтение следующей лексемы ($Number_Lexem++) */
$Number_Lexem++;
else
{
/* Конструкция <оператор>. */
/* Отсутствует ( в операторе SWITH.*/
$Code_Error=34;
return 0;
}
/* Обработка конструкции <выражение> */
ProcedureE();
/* Проверка на ошибки, появившиеся в процессе */
/* обработки конструкции <выражение> */
if ($Code_Error!=-1)
return 0;
if ($Tab_Lexems[$Number_Lexem]->Code==_RPAREN_)
/* функция y4: чтение следующей лексемы ($Number_Lexem++) */
$Number_Lexem++;
else
{
/* Конструкция <оператор>. */
/* Отсутствует ) в операторе SWITH.*/
$Code_Error=35;
return 0;
}
if ($Tab_Lexems[$Number_Lexem]->Code==_BRACE_OPEN_)
{
/*функция у21: снять вершину стека $StekRes в переменную $Ai [$StekRes->$Ai];
отправить значение переменной $Ai в стек $StekCaseValue[$Ai->$StekCaseValue];
в стек $StekDefaultValue занести 1 [$StekDefaultValue->1]*/
if (!Stek_Integer(1, $StekRes, $TopRes, $Ai))
{
/* Нехватка элементов в стеке $StekRes */
$Code_Error=16;
return 0;
}
if (!Stek_Integer(2, $StekCaseValue, $TopCaseValue, $Ai))
{
/* Переполнение стека $StekCaseValue */
$Code_Error=36;
return 0;
}
$Ai=1;
if (!Stek_Integer(2, $StekDefaultValue, $TopDefaultValue, $Ai))
{
/* Переполнение стека $StekDefaultValue */
$Code_Error=37;
return 0;
}
/* функция y4: чтение следующей лексемы ($Number_Lexem++) */
$Number_Lexem++;
}
else
{
/* Конструкция <оператор>. */
/* Отсутствует { в операторе SWITH.*/
$Code_Error=38;
return 0;
}
if ($Tab_Lexems[$Number_Lexem]->Code==_CASE_)
{
/* функция y4: чтение следующей лексемы ($Number_Lexem++) */
$Number_Lexem++;
}
else
{
/* Конструкция <оператор>. */
/* Отсутствует CASE в операторе SWITH.*/
$Code_Error=39;
return 0;
}
if ($Tab_Lexems[$Number_Lexem]->Code==_CONSTANT_)
{
/*функция у22: y22: снять вершину стека $StekCaseValue в переменную $Ai [$StekCaseValue ->$Ai];
отправить значение переменной $Ai в стек $StekCaseValue [$Ai-> $StekCaseValue];
значение прочитанной константы занести в $Bi[$Tab_Constants[$Tab_Lexems[$Number_Lexem]->Value]];
сравнить $Ai и $bi: $Ai==$Bi движение по TRUE, иначе по FALSE; */
if (!Stek_Integer(1, $StekCaseValue, $TopCaseValue, $Ai))
{
/* Нехватка элементов в стеке $StekCaseValue */
$Code_Error=16;
return 0;
}
if (!Stek_Integer(2, $StekCaseValue, $TopCaseValue, $Ai))
{
/* Нехватка элементов в стеке $StekCaseValue */
$Code_Error=40;
return 0;
}
$Bi=$Tab_Constants[$Tab_Lexems[$Number_Lexem]->Value];
if ($Ai==$Bi)
$Ai=1;
else
$Ai=0;
/* функция y4: чтение следующей лексемы ($Number_Lexem++) */
$Number_Lexem++;
}
else
{
/* Конструкция <оператор>. */
/* Отсутствует константа в операторе SWITH.*/
$Code_Error=41;
return 0;
}
if ($Ai==1)
{
/*функция у23: снять вершину стека $StekDefaultValue в переменную $ai[$StekDefaultValue->$Ai];
переменной $Ai присвоить значение 0[$Ai=0];
отправить переменную $Ai в стек $StekDefaultValue[$Ai->$StekDefaultValue];*/
if (!Stek_Integer(1, $StekDefaultValue, $TopDefaultValue, $Ai))
{
/* Нехватка элементов в стеке $StekDefaultValue */
$Code_Error=42;
return 0;
}
$Ai=0;
if (!Stek_Integer(2, $StekDefaultValue, $TopDefaultValue, $Ai))
{
/* Переполнение стека $StekDefaultValue */
$Code_Error=37;
return 0;
}
if ($Tab_Lexems[$Number_Lexem]->Code==_COLON_)
{
/* функция y4: чтение следующей лексемы ($Number_Lexem++) */
$Number_Lexem++;
}
else
{
/* Конструкция <оператор>. */
/* Отсутствует : в операторе SWITH.*/
$Code_Error=43;
return 0;
}
ProcedureL();
/* Проверка на ошибки, появившиеся в процессе */
/* обработки конструкции <последовательность операторов> */
if ($Code_Error!=-1)
return 0;
}
else
{
if ($Tab_Lexems[$Number_Lexem]->Code==_COLON_)
{
/* функция y24: снять значение текущей лексемы в переменную
$Ai[$Tab_Lexems[$Number_Lexem]->Value -> $Ai];
номеру текущей лексемы присвоить значение $Ai [$Ai->$Number_Lexem]*/
$Ai=$Tab_Lexems[$Number_Lexem]->Value;
$Number_Lexem=$Ai;
}
else
{
/* Конструкция <оператор>. */
/* Отсутствует : в операторе SWITH.*/
$Code_Error=43;
return 0;
}
}
ProcedureZ();
/* Проверка на ошибки, появившиеся в процессе */
/* обработки конструкции <содержимое> */
if ($Code_Error!=-1)
return 0;
if ($Tab_Lexems[$Number_Lexem]->Code==_BRACE_CLOSE_)
{
/*функция y26: снять вершину стека $StekCaseValue в
переменную $Ai[$StekCaseValue->$Ai];*/
if (!Stek_Integer(1, $StekCaseValue, $TopCaseValue, $Ai))
{
/* Нехватка элементов в стеке $StekCaseValue */
$Code_Error=40;
return 0;
}
/* функция y4: чтение следующей лексемы ($Number_Lexem++) */
$Number_Lexem++;
}
else
{
/* Конструкция <оператор>. */
/* Отсутствует } в операторе SWITH.*/
$Code_Error=44;
return 0;
}
break;
case _FOR_ :
/* функция y4: чтение следующей лексемы ($Number_Lexem++) */
$Number_Lexem++;
/*Обработка возможного преддекремента*/
if ($Tab_Lexems[$Number_Lexem]->Code==_DECREMENT_)
ProcedureX();
/* Проверка на ошибки, появившиеся в процессе */
/* обработки преддекремента */
if ($Code_Error!=-1)
return 0;
if ($Tab_Lexems[$Number_Lexem]->Code==_IDENTIFIER_)
{
/* y13:добавить значение лексемы с номером $Number_Lexem */
/* в стек $StekIdent ($Tab_Lexems[$Number_Lexem]->Value-->$StekIdent)*/
if (!Stek_Integer(2, $StekIdent, $TopIdent,$Tab_Lexems[$Number_Lexem]->Value))
{
/* Переполнение стека $StekIdent */
$Code_Error=14;
Exit;
}
/* функция y4: чтение следующей лексемы ($Number_Lexem++) */
$Number_Lexem++;
}
else
{
/*Ошибка в FOR - нет идентификатора*/
$Code_Error=48;
return 0;
}
/* Обработка возможного постдекремента*/
ProcedureY();
if ($Tab_Lexems[$Number_Lexem]->Code==_ASSIGNMENT_)
{
/* функция y4: чтение следующей лексемы ($Number_Lexem++) */
$Number_Lexem++;
}
else
{
/*Ошибка в FOR - нет присвоения*/
$Code_Error=49;
echo "Нет присвоения";
return 0;
}
/* Обработка конструкции <выражение> */
ProcedureE();
/* Проверка на ошибки, появившиеся в процессе */
/* обработки конструкции <выражение> */
if ($Code_Error!=-1)
return 0;
/* y14: в переменную $Ai снять элемент со стека $StekRes*/
/* ($Ai<--$StekRes), в переменную $Bi снять со стека */
/* $StekIdent значение лексемы ident ($Bi<--$StekIdent), */
/* идентификатору с номером $Bi, присвоить значение $Ai */
/* $ArrIdent[$Bi]=$Ai */
if (!Stek_Integer(1, $StekRes, $TopRes,$Ai))
{
/* Нехватка элементов в стеке $StekRes */
$Code_Error=16;
return 0;
}
if (!Stek_Integer(1, $StekIdent, $TopIdent, $Bi))
{
/* Нехватка элементов в стеке $StekIdent */
$Code_Error=17;
return 0;
}
if (!Stek_Integer(2, $StekIdent, $TopIdent, $Bi))
{
/* Переполнение в стеке $StekIdent */
$Code_Error=14;
return 0;
}
$ArrIdent[$Bi]=$Ai;
if ($Tab_Lexems[$Number_Lexem]->Code==_TO_)
{
/*функция y29: значение текущей лексемы занести в стек
$StekForExit [$Tab_Lexems[$Number_Lexem]->Value -> $StekForExit];*/
if (!Stek_Integer(2, $StekForExit, $TopForExit, $Tab_Lexems[$Number_Lexem]->Value))
{
/* Переполнение стека $StekForExit */
$Code_Error=52;
return 0;
}
/* функция y4: чтение следующей лексемы ($Number_Lexem++) */
$Number_Lexem++;
}
else
{
/*Ошибка в FOR - нет TO */
$Code_Error=50;
return 0;
}
/* Обработка конструкции <выражение> */
ProcedureE();
/* Проверка на ошибки, появившиеся в процессе */
/* обработки конструкции <выражение> */
if ($Code_Error!=-1)
return 0;
/*функция у27: y27: снять вершину стека $StekRes в переменную $ai[$StekRes->$Ai];*/
if (!Stek_Integer(1, $StekRes, $TopRes,$Ai))
{
/* Нехватка элементов в стеке $StekRes */
$Code_Error=16;
return 0;
}
ProcedureU();
/* Проверка на ошибки, появившиеся в процессе */
/* обработки конструкции <шаг> */
if ($Code_Error!=-1)
return 0;
ProcedureL();
/* Проверка на ошибки, появившиеся в процессе */
/* обработки конструкции <последовательность операторов> */
if ($Code_Error!=-1)
return 0;
if ($Tab_Lexems[$Number_Lexem]->Code==_ENDFOR_)
{
/*y28: значение текущей лексемы занести в $Ai [$Tab_Lexems[$Number_Lexem]->Value -> $Ai];
номеру текущей лексемы присвоить значение переменной $Ai [$Ai->$Number_Lexem]*/
$Ai=$Tab_Lexems[$Number_Lexem]->Value;
$Number_Lexem=$Ai;
}
else
{
/*Ошибка в FOR - нет ENDFOR */
$Code_Error=51;
return 0;
}
while ($ForWhile)
{
/* Обработка конструкции <выражение> */
ProcedureE();
/* Проверка на ошибки, появившиеся в процессе */
/* обработки конструкции <выражение> */
if ($Code_Error!=-1)
return 0;
/*функция у30: снять вершину стека $StekRes в
переменную $ForAi[$StekRes->$ForAi];*/
if (!Stek_Integer(1, $StekRes, $TopRes,$ForAi))
{
/* Нехватка элементов в стеке $StekRes */
$Code_Error=16;
return 0;
}
ProcedureU();
/* Проверка на ошибки, появившиеся в процессе */
/* обработки конструкции <шаг> */
if ($Code_Error!=-1)
return 0;
/*функция у31: переменную $ForAi занести в переменную $ForBi[U()->$ForBi];
занести в переменную $ForCi вершину стека $StekIdent [$StekIdent->$ForCi];
занести в стек $StekIdent значение переменной $ForCi [$ForCi->$StekIdent];
&n