Автор: Пользователь скрыл имя, 10 Мая 2011 в 21:35, лабораторная работа
Цель работы:
Изучение основных понятий теории грамматик простого и операторного предшествования, ознакомление с алгоритмами синтаксического анализа (разбора) для некоторых классов КС-грамматик, получение практических навыков создания простейшего синтаксического анализатора для заданной грамматики операторного предшествования.
begin
{ Позиция начала лексемы - первый символ }
iStart := 1;
{ Запоминаем текущую строку }
sCurStr := listFile[i];
{ Цикл
по всем символам текущей
iStr := Length(sCurStr);
for j:=1 to iStr do
begin
{ Увеличиваем общий счетчик
Inc(iAll);
{ Моделируем работу КА в зависимости от состояния
автомата и текущего символа входной строки }
case posCur of
AP_START:
begin
{ В начальном состоянии запоминаем позицию
начала лексемы }
iStart := j;
iStComm := iAll-1;
case sCurStr[j] of
'i': posCur := AP_IF1;
't': posCur := AP_THEN1;
'e': posCur := AP_ELSE1;
':': posCur := AP_ASSIGN;
';': listLex.Add(TLexem.CreateKey(
'=': AddKeyToList(LEX_EQ,AP_START);
'>': AddKeyToList(LEX_GT,AP_START);
'<': AddKeyToList(LEX_LT,AP_START);
'0'..'9': posCur := AP_CONST;
'A'..'Z','a'..'d','f'..'h','j'
'u'..'z','_': posCur := AP_VAR;
'{': begin posCur := AP_COMM;comm_pos:=i;end;
' ',#10,#13,#9: ;
else posCur := AP_ERR;
end{case list};
end;
AP_IF1: KeyLetter('f',AP_IF2);
AP_IF2: KeyFinish(LEX_IF);
AP_THEN1: KeyLetter('h',AP_THEN2);
AP_THEN2: KeyLetter('e',AP_THEN3);
AP_THEN3: KeyLetter('n',AP_THEN4);
AP_THEN4: KeyFinish(LEX_THEN);
AP_ELSE1: KeyLetter('l',AP_ELSE2);
AP_ELSE2: KeyLetter('s',AP_ELSE3);
AP_ELSE3: KeyLetter('e',AP_ELSE4);
AP_ELSE4: KeyFinish(LEX_ELSE);
AP_ASSIGN:
case sCurStr[j] of
'=': AddKeyToList(LEX_ASSIGN,AP_
else posCur := AP_ERR;
end{case list};
AP_VAR:
case sCurStr[j] of
':': AddVarToList(AP_ASSIGN,j);
'=': AddVarKeyToList(LEX_EQ,AP_
'>': AddVarKeyToList(LEX_GT,AP_
'<': AddVarKeyToList(LEX_LT,AP_
';': AddVarKeyToList(LEX_SEMI,AP_
'0'..'9','A'..'Z','a'..'z','_'
posCur := AP_VAR;
'{': begin AddVarToList(AP_COMM,j);comm_
' ',#10,#13,#9: AddVarToList(AP_START,j);
else posCur := AP_ERR;
end{case list};
AP_CONST:
case sCurStr[j] of
':': AddConstToList(AP_ASSIGN,j);
'=': AddConstKeyToList(LEX_EQ,AP_
'>': AddConstKeyToList(LEX_GT,AP_
'<': AddConstKeyToList(LEX_LT,AP_
';': AddConstKeyToList(LEX_SEMI,AP_
'0'..'9': posCur := AP_CONST;
'{': begin AddConstToList(AP_COMM,j);
' ',#10,#13,#9: AddConstToList(AP_START,j);
else posCur := AP_ERR;
end{case list};
AP_COMM:
case sCurStr[j] of
'}': posCur := AP_START;
end{case list};
end{case pos};
{ Проверяем, не достигнут ли конец строки }
if j = iStr then
begin
{ Конец строки - это конец текущей лексемы }
case posCur of
AP_IF2: AddKeyToList(LEX_IF,AP_START);
AP_THEN4: AddKeyToList(LEX_THEN,AP_
AP_ELSE4: AddKeyToList(LEX_ELSE,AP_
AP_CONST: AddConstToList(AP_START,j+1);
AP_ASSIGN: posCur := AP_ERR;
AP_IF1,AP_THEN1,AP_THEN2,AP_
AP_ELSE1,AP_ELSE2,AP_ELSE3,AP_
AddVarToList(AP_START,j+1);
end{case pos2};
end;
{ Проверяем не была ли ошибка в лексемах }
if posCur = AP_ERR then
begin
{ Если была ошибка, вычисляем позицию
ошибочной лексемы }
iStart := (j - iStart)+1;
{ и запоминаем ее в виде фиктивной лексемы в начале
списка для детальной
listLex.Insert(0,
TLexem.CreateInfo('
{ Если ошибка, прерываем цикл }
Break;
end;
end{for j};
{ В конце строки увеличиваем общий счетчик символов
на 2: конец строки и возврат каретки }
Inc(iAll,2);
{ Если ошибка, запоминаем номер ошибочной строки
и прерываем цикл }
if posCur = AP_ERR then
begin
Result := i+1;
Break;
end;
end{for i};
{ Если комментарий не был закрыт, то это ошибка }
if posCur = AP_COMM then
begin
listLex.Insert(0,
TLexem.CreateInfo('Незакрытый комментарий',
iStComm,iCnt,iAll-iStComm));
Result := comm_pos+1;
end
else
if not (posCur in [AP_START,AP_ERR]) then
{ Если КА не в начальном состоянии-это неверная лексема }
begin
listLex.Insert(0,
TLexem.CreateInfo('
Result := iCnt;
end;
end;
end.
Вывод:
В
ходе лабораторной работы были изучены
основные понятия грамматик простого
и операторного предшествования, а
также алгоритмы