43219

Реализация интерпретатора для модифицированной грамматики учебного языка MILAN

Курсовая

Информатика, кибернетика и программирование

Position текущая позиция в строке просматриваемая лексическим анализатором; Number_String текущая строка программы просматриваемая лексическим анализатором; при любом условии любой символ. Семантические функции к Rсхеме лексического анализатора: y0: подготовка инициализация таблиц и переменных Position=0 Number_String=1; y1: чтение следующего символа программы на языке МИЛАН; y2: увеличение счётчика текущей позиции Position; y3: переход на новую строку в программе увеличение счётчика текущей строки и...

Русский

2013-11-04

1.68 MB

24 чел.

Министерство образования и науки Российской Федерации

Волжский политехнический институт (филиал) федерального государственного бюджетного образовательного учреждения высшего профессионального образования «Волгоградский государственный технический университет»

(ВПИ (филиал) ВолгГТУ)

Факультет «_________________________________________________________»

Кафедра «___________________________________________________________»

ПОЯСНИТЕЛЬНАЯ ЗАПИСКА

к курсовому работе (проекту)

по дисциплине «_____________________________________________________»

на тему______________________________________________________________

____________________________________________________________________

____________________________________________________________________

____________________________________________________________________

Студент_____________________________________________________________

(имя, отчество, фамилия)

Группа________________________

Руководитель работы (проекта) ________________________      _____________________

(подпись и дата подписания)                 (долж., инициалы и фамилия)

Оценка    ________________________     

                                          (в баллах)        

Члены комиссии:

  _____________________       ____________________________

(подпись и дата подписания)                       (инициалы и фамилия)

  _____________________       ____________________________

(подпись и дата подписания)                       (инициалы и фамилия)

  _____________________       ____________________________

(подпись и дата подписания)                       (инициалы и фамилия)

Нормоконтролер ______________________________      _____________________________

(подпись, дата подписания)                                    (инициалы и фамилия)

                          

                          Волжский, 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 [THENELSE+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, ELSEENDIF+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 [ENDFORFOR+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 [UNTILREPEAT+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; CASEDEFAULT];

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">Т А Б Л И Ц А &nbsp; Л Е К С Е М</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>&nbsp;</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">МАССИВ ИДЕНТИФИКАТОРОВ&nbsp;</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">МАССИВ КОНСТАНТ&nbsp;</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 вер