kursovik / прогам реализация
.docx
/* функция у11: формирование лексемы */
$Current_Lexem->Code=20;
$Current_Lexem->Value=$Number_Constants;
}
else
/* Превышение максимального количества констант */
$Code_Error=2;
global $Position;
if ($Code_Error==-1)
$Position=$Position+$Position_;
return 0;
} /* End Digit */
/************************************************************************/
/* Setup_Refference */
/* Процедура расстановки ссылок: */
/* DO-->ENDDO+1, ENDDO-->WHILE+1 */
/* THEN-->ELSE+1 */
/* THEN-->ENDIF+1, ELSE-->ENDIF+1 */
/* {-->CASE */
/* :-->CASE, :-->DEFAUT, :-->} */
/* FOR --> ENDFOR+1 */
/* ENDFOR --> TO+1 */
/* Аргументы: Массив лексем. */
/* Результат: Массив лексем с расставленными ссылками. */
/************************************************************************/
function Setup_Refference()
{
/* функция y0: подготовка (инициализация стеков и переменных), */
/* номер очередной лексемы Number_Lexem=1, прочитать лексему с номером */
/* Number_Lexem */
//Глобальные переменные
global $Number_Lexem;
global $Tab_Lexems;
global $Code_Error;
global $Number_Lexems_Programm;
//Локальные переменные
$r=0;
$s=0;
$Top_do = 0;
$Top_if = 0;
$Top_case= 0;
$Top_to = 0;
$Stek_if = Array();
$Stek_do = Array();
$Stek_case=Array();
$Stek_to =Array();
$Number_Lexem = 1;
Stek_Integer(0,$Stek_do,$Top_do,$r);
Stek_Integer(0,$Stek_if,$Top_if,$s);
Stek_Integer(0,$Stek_case,$Top_case,$s);
Stek_Integer(0,$Stek_to, $Top_to, $s);
do
{
switch($Tab_Lexems[$Number_Lexem]->Code):
Case _COLON_ :
/* функция у8: занести значение $Number_Lexem в стек*/
/* $Stek_case ($Number_Lexem-->$Stek_case) */
if (!Stek_Integer(2,$Stek_case,$Top_case,$Number_Lexem))
{
/* Переполнение стека CASE*/
$Code_Error=45;
return 0;
}
break;
Case _BRACE_OPEN_ :
/* функция у8: занести значение $Number_Lexem в стек*/
/* $Stek_case ($Number_Lexem-->$Stek_case) */
if (!Stek_Integer(2,$Stek_case,$Top_case,$Number_Lexem))
{
/* Переполнение стека CASE*/
$Code_Error=45;
return 0;
}
break;
Case _CASE_ :
/* функция у9: снять вершину стека $Stek_case в переменную */
/* $r ($r<$Stek_case), присвоить значение $Number_Lexem */
/* лексеме c номером $r [:>CASE, :>DEFAUT, :>} ] */
/* ($Tab_Lexems[$r]->Value=$Number_Lexem). */
if (!Stek_Integer(1,$Stek_case,$Top_case,$r))
{
/* Недостача элементов в стеке $Stek_case*/
$Code_Error=46;
return 0;
}
$Tab_Lexems[$r]->Value=$Number_Lexem;
break;
Case _DEFAUT_ :
/* функция у9: снять вершину стека $Stek_case в переменную */
/* $r ($r<$Stek_case), присвоить значение $Number_Lexem */
/* лексеме c номером $r [:>CASE, :>DEFAUT, :>} ] */
/* ($Tab_Lexems[$r]->Value=$Number_Lexem). */
if (!Stek_Integer(1,$Stek_case,$Top_case,$r))
{
/* Недостача элементов в стеке $Stek_case*/
$Code_Error=46;
return 0;
}
$Tab_Lexems[$r]->Value=$Number_Lexem;
break;
Case _BRACE_CLOSE_ :
/* функция у9: снять вершину стека $Stek_case в переменную */
/* $r ($r<$Stek_case), присвоить значение $Number_Lexem */
/* лексеме c номером $r [:>CASE, :>DEFAUT, :>} ] */
/* ($Tab_Lexems[$r]->Value=$Number_Lexem). */
if (!Stek_Integer(1,$Stek_case,$Top_case,$r))
{
/* Недостача элементов в стеке $Stek_case*/
$Code_Error=46;
return 0;
}
$Tab_Lexems[$r]->Value=$Number_Lexem;
break;
Case _WHILE_ :
/* функция y1: значение $Number_Lexem занести */
/* стек $Stek_do ($Number_Lexem-->$Stek_do) */
if (!Stek_Integer(2,$Stek_do,$Top_do,$Number_Lexem))
{
/* Переполнение стека DO*/
$Code_Error=4;
return 0;
}
/* функция y7: $Number_Lexem++, */
/* прочитать очередную лексему с номером $Number_Lexem */
$Number_Lexem++;
while ($Tab_Lexems[$Number_Lexem]->Code!=_DO_):
/* функция y7: Number_Lexem=Number_Lexem+1, */
/* прочитать очередную лексему с номером $Number_Lexem */
$Number_Lexem++;
if ($Number_Lexem>$Number_Lexems_Programm)
{
/* Несоответствие в операторах WHILE-DO-OD */
$Code_Error=10;
return 0;
}
endwhile;
/* функция y1: значение $Number_Lexem занести */
/* стек $Stek_do ($Number_Lexem-->$Stek_do) */
if (!Stek_Integer(2,$Stek_do,$Top_do,$Number_Lexem))
{
/* Переполнение стека DO */
$Code_Error=4;
return 0;
}
break;
Case _ENDDO_ :
/* функция y2: снять вершину стека $Stek_do в */
/* переменную $s ($s<--$Stek_do), снять вершину */
/* стека $Stek_do в переменную $r ($r<--$Stek_do), */
/* значение $r+1 присвоить лексеме */
/* с номером $Number_Lexem [ENDDO-->WHILE+1] */
/* ($Tab_Lexems[$Number_Lexem]->Value=r+1), */
/* значение Number_Lexem+1 присвоить лексеме */
/* с номером s [DO-->ENDDO+1] */
/* ($Tab_Lexems[$s]->Value=$Number_Lexem+1. */
if (!Stek_Integer(1,$Stek_do,$Top_do,$s))
{
/* Нехватка элементов в стеке DO */
$Code_Error=5;
return 0;
}
if (!Stek_Integer(1,$Stek_do,$Top_do,$r))
{
/* Нехватка элементов в стеке DO */
$Code_Error=5;
return 0;
}
/* ENDDO-->WHILE+1*/
$Tab_Lexems[$Number_Lexem]->Value=$r+1;
/* DO-->ENDDO+1 */
$Tab_Lexems[$s]->Value=$Number_Lexem+1;
break;
Case _IF_ :
/* функция y7: $Number_Lexem++, */
/* прочитать очередную лексему с номером $Number_Lexem */
$Number_Lexem++;
while ($Tab_Lexems[$Number_Lexem]->Code!=_THEN_):
/* функция y7: $Number_Lexem++, */
/* прочитать очередную лексему с номером $Number_Lexem */
$Number_Lexem++;
if ($Number_Lexem>$Number_Lexems_Programm)
{
/* Несоответствие операторах IF-THEN-ELSE-ENDIF */
$Code_Error=11;
return 0;
}
endwhile;
/* функция y3: значение $Number_Lexem занести */
/* стек $Stek_if ($Number_Lexem-->$Stek_if) */
if (!Stek_Integer(2,$Stek_if,$Top_if,$Number_Lexem))
{
/* Переполнение стека IF */
$Code_Error=7;
return 0;
}
break;
Case _ELSE_ :
/* функция y4: снять вершину стека $Stek_if в */
/* переменную $r ($r<--$Stek_if), присвоить */
/* значение $Number_Lexem+1 лексеме c номером */
/* r [THEN-->ELSE+1] */
/* ($Tab_Lexems[$r]->Value=$Number_Lexem+1), */
/* занести в $Stek_ if значение Number_Lexem */
/* ($Number_Lexem-->$Stek_if) */
if (!Stek_Integer(1,$Stek_if,$Top_if,$r))
{
/* Нехватка элементов в стеке IF */
$Code_Error=8;
return 0;
}
/* THEN-->ELSE+1 */
$Tab_Lexems[$r]->Value=$Number_Lexem+1;
if (!Stek_Integer(2,$Stek_if,$Top_if,$Number_Lexem))
{
/* Переполнение стека IF */
$Code_Error=7;
return 0;
}
break;
Case _ENDIF_ :
/* функция y5: снять вершину стека $Stek_if в */
/* переменную $r ($r<--$Stek_if), присвоить */
/* значение $Number_Lexem+1 лексеме c номером */
/* $r [THEN-->ENDIF+1, ELSE-->ENDIF+1] */
/* ($Tab_Lexems[$r]->Value=$Number_Lexem+1) */
/* занести в $Stek_ if значение Number_Lexem */
/* ($Number_Lexem-->$Stek_if) */
if (!Stek_Integer(1,$Stek_if,$Top_if,$r))
{
/* Нехватка элементов в стеке IF */
$Code_Error=8;
return 0;
}
/* THEN-->ENDIF+1, ELSE -->ENDIF+1 */
$Tab_Lexems[$r]->Value=$Number_Lexem+1;
break;
Case _TO_ :
/* функция y10: */
if (!Stek_Integer(2,$Stek_to,$Top_to,$Number_Lexem))
{
/* Переполнение стека TO*/
$Code_Error=55;
return 0;
}
break;
Case _ENDFOR_ :
/* функция y11: */
if (!Stek_Integer(1,$Stek_to,$Top_to,$r))
{
/* Нехватка элементов в стеке TO*/
$Code_Error=56;
return 0;
}
$Tab_Lexems[$r]->Value=$Number_Lexem+1;
$Tab_Lexems[$Number_Lexem]->Value=$r+1;
break;
endswitch;
/* функция y7: $Number_Lexem++, */
/* прочитать очередную лексему с номером */
$Number_Lexem++;
}
while ($Number_Lexem<=$Number_Lexems_Programm);
if ($Top_if!=0)
{
/* Несоответствие в операторах IF-THEN-ELSE-ENDIF */
$Code_Error=11;
}
if ($Top_do!=0)
{
/* Несоответствие в операторах WHILE-DO-OD */
$Code_Error=10;
}
if ($Top_case!=0)
{
/* Несоответствие в операторах SWITH-CASE-DEFAUT */
$Code_Error=47;
}
if ($Top_to!=0)
{
/* Несоответствие в операторах FOR-TO-ENDFOR */
$Code_Error=54;
}
} /* End Setup_Refference */
/************************************************************************/
/* Print_Tab_Lexems */
/* Процедура печати таблицы массива лексем. */
/* Аргументы: нет аргументов. */
/* Результат: Высвечивание на экране таблицы. */
/************************************************************************/
Function Print_Tab_Lexems()
{
$Number = '';
$Number_ = '';
$Zastav = ''; /* Шапка таблицы массива лексем */
$TabLex = ''; /* Таблица массива лексем */
global $Number_Lexems_Programm;
global $Tab_Lexems;
global $ct_TabLEX_Code_str;
global $ct_TabLEX_Value_str;
echo '<br><H2> <div align="center">РЕЗУЛЬТАТ РАБОТЫ ЛЕКСИЧЕСКОГО АНАЛИЗАТОРА</div></H2><br><hr><br>';
/* Начало процедуры Print_Tab_Lexems */
/* Формирование шапки таблицы массива лексем */
$Zastav = '<table border=1 width="450" align="center"><tr><td colspan=19><div align="center">Т А Б Л И Ц А Л Е К С Е М</div></td></tr>';
$Zastav .= '<tr><td> Номер </td>';
$End=intval($Number_Lexems_Programm /10)+1;
for ($i=0;$i<=9;$i++)
{
$Zastav .='<td align="center"> ' . $i . '</td>';
}
$Zastav .= '</tr>';
/* печать таблицы массива лексем */
/* Вывод содержимого таблицы */
for ($i=1; $i<=$End;$i++)
{
$ct_Pos=($i-1)*10;
$TabLex= '<tr><td align="center">'. strval($ct_Pos) . '</td>';
for ($j=0;$j<=9;$j++)
{
if ((($i==1) && ($j==0)) || ($Tab_Lexems[$ct_Pos+$j]->Code)=='')
$TabLex .='<td> </td>';
else
{
$Number = $Tab_Lexems[$ct_Pos+$j]->Code;
$Number_= $Tab_Lexems[$ct_Pos+$j]->Value;
$ct_TabLEX_Code_str.= $Number.'%';
$ct_TabLEX_Value_str.= $Number_.'%';
$TabLex .='<td align="center">' . Space(2-strlen($Number)) . $Number . ',' . Space(2-strlen($Number_)) . $Number_ . '</td>';
}
}
$Zastav .= $TabLex .'</tr>';
}
$Zastav .= '</table>';
echo ($Zastav);
} /* End Print_Tab_Lexems */
/************************************************************************/
/* Print_Tab_Identifiers_Constants */
/* Процедура печати таблицы массивов идентификаторов и констант. */
/* Аргументы: нет аргументов. */
/* Результат: Высвечивание на экране таблиц. */
/************************************************************************/
Function Print_Tab_Identifiers_Constants()
{
$Number='';
$Number_='';
/* Таблица массивов идентификаторов и констант */
$Tab_Identifiers_Constants = '';
global $Tab_Constants;
global $Tab_Identifiers;
global $Number_Identifiers;
global $Number_Constants;
/* Начало процедуры Print_Tab_Identifiers_Constatns */
/* Формирование таблицы массива идентификаторов */
$Tab_Identifiers_Constants = '<br><br><table border=1 width="450" align="center"><tr><td colspan=2 align="center">МАССИВ ИДЕНТИФИКАТОРОВ </td></tr>';
$Tab_Identifiers_Constants .= '<tr><td align="center"> Номер </td><td align="center"> ИДЕНТИФИКАТОР </td></tr>';
for($i=1;$i<=$Number_Identifiers;$i++)
{
$Tab_Identifiers_Constants .= '<tr><td align="center">' . $i . '</td><td align="center">' . $Tab_Identifiers[$i] . '</td></tr>';
}
/* Формирование таблицы массива констант */
$Tab_Identifiers_Constants .= '</table><br><br><table border=1 width="450" align="center"><tr><td colspan=2 align="center">МАССИВ КОНСТАНТ </td></tr>';
$Tab_Identifiers_Constants .= '<tr><td align="center"> Номер </td><td align="center"> КОНСТАНТА </td></tr>';
for($i=1;$i<=$Number_Constants;$i++)
{
$Tab_Identifiers_Constants .= '<tr><td align="center">' . $i . '</td><td align="center">' . $Tab_Constants[$i] . '</td></tr>';
}
$Tab_Identifiers_Constants .= '</table>';
echo($Tab_Identifiers_Constants);
} /* Print_Tab_Identifiers_Constants */
/* Основной блок Лексического Анализатора */
/* функция у0: подготовка (инициализация таблиц и переменных) */
global $Code_Error;
global $Tab_Lexems;
global $Input_Letter;
global $Number_Lexems_Programm;
global $Number_Lexem;
global $Number_Identifiers;
global $Number_Constants;
global $Number_String;
global $Position;
global $Current_Lexem;
/* функция у1: чтение следующего символа программы на языке МИЛАН */
if (Read($Input_Letter)==0)
{
echo('ОШИБКА: Отсутствуют данные для разбора.');
exit; // Завершение работы интерпретатора
}
$Position=0;
$Number_String=1;
$ct_spec= '['.Chr(9). Chr(10).Chr(13). Chr(32).']';
do
{
/* Игнорирование спец. символов и пробела */
while (ereg($ct_spec,$Input_Letter{0}) )
{
switch (ord($Input_Letter{0})):
case 9 : /* функция y2: увеличение счётчика текущей позиции */
/* ($Position=$Position+1) */
$Position++;
break;
case 13 :
/* функция y3: переход на новую строку в программе, */
/* увеличение счётчика текущей строки, и сброс */
/* счётчика позиции ( $Number_String=$Number_String+1,*/
/* Position=0) */
$Number_String++;
$Position=0;
break;
case 32 : /* функция y2: увеличение счётчика текущей позиции $Position++ */
$Position++;
break;
endswitch;
/* функция у1: чтение следующего символа программы на языке МИЛАН */
Read($Input_Letter);
}
if(isAlpha($Input_Letter{0})) // если введённый символ является буквой
Letter();
elseif(isDigit($Input_Letter{0})) // если введённый символ является цифрой
Digit();
else
{
switch ($Input_Letter{0}):
Case ';' :
/* функция у11: формирование лексемы */
$Current_Lexem->Code=12;
$Current_Lexem->Value=0;
/* функция у1: чтение следующего символа */
Read($Input_Letter);
$Position++;
break;
Case '=' :
/* функция у11: формирование лексемы */
$Current_Lexem->Code=13;
$Current_Lexem->Value=0;
/* функция у1: чтение следующего символа */
Read($Input_Letter);
$Position++;
break;
Case '>' :
/* функция у1: чтение следующего символа */
Read($Input_Letter);
$Position++;
if ($Input_Letter=='=')
{
/* функция у11: формирование лексемы */
$Current_Lexem->Code=13;
$Current_Lexem->Value=4;
/* функция у1: чтение следующего символа */
Read($Input_Letter);
$Position++;
}
else
{
/* функция у11: формирование лексемы */
$Current_Lexem->Code=13;
$Current_Lexem->Value=2;
}
break;
Case '<' :
/* функция у1: чтение следующего символа */
Read($Input_Letter);
$Position++;
switch ($Input_Letter):
case '>' :
/* функция у11: формирование лексемы */
$Current_Lexem->Code=13;
$Current_Lexem->Value=1;
/* функция у1: чтение следующего символа */
Read($Input_Letter);
$Position=$Position+1;
break;
case '=' :
/* функция у11: формирование лексемы */
$Current_Lexem->Code=13;
$Current_Lexem->Value=5;
/* функция у1: чтение следующего символа */
Read($Input_Letter);
$Position=$Position+1;
break;
default:
/* функция у11: формирование лексемы */
$Current_Lexem->Code=13;
$Current_Lexem->Value=3;
break;
endswitch;
break;
Case '+' :/* функция у1: чтение следующего символа */
Read($Input_Letter);
$Position++;
switch ($Input_Letter):
case '+' :
/* функция у11: формирование лексемы */
$Current_Lexem->Code=33;
$Current_Lexem->Value=0;
/* функция у1: чтение следующего символа */
Read($Input_Letter);
$Position=$Position+1;
break;
default:
/* функция у11: формирование лексемы */
$Current_Lexem->Code=14;
$Current_Lexem->Value=0;
break;
endswitch;
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=0;
/* функция у1: чтение следующего символа */
Read($Input_Letter);
$Position++;
break;
Case '/' :
/* функция у1: чтение следующего символа */
Read($Input_Letter);
$Position++;
switch ($Input_Letter):
case '/' :
Read($Input_Letter);
$Position++;
while($Input_Letter!='Chr(26)'):
/* функция у11: формирование лексемы */
Read($Input_Letter);
$Position++;
endwhile;
Read($Input_Letter);
$Position++;
break;
default:
/* функция у11: формирование лексемы */
$Current_Lexem->Code=15;
$Current_Lexem->Value=1;
break;
endswitch;
break;
Case '{' :
/* функция у11: формирование лексемы */
$Current_Lexem->Code=29;
$Current_Lexem->Value=0;
/* функция у1: чтение следующего символа */
Read($Input_Letter);
$Position++;
break;
Case '}' :
/* функция у11: формирование лексемы */
$Current_Lexem->Code=30;
$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 */
/* Процедура синтаксического анализа, совмещенная со стадией */
/* генерации действий. */
/* Входные данные: массив лексем (после сканера), */
/* массив идентификаторов (после сканера), */
/* массив констант (после сканера). */
/* */
/* Выходные данные: Выполнение программы на языке МИЛАН. */