Создание синтаксического анализатора простого языка программирования

Материал из Вики ИТ мехмата ЮФУ
Версия от 09:28, 15 марта 2012; Admin (обсуждение | вклад) (Модуль синтаксического анализатора (парсера))

Перейти к: навигация, поиск

К основной странице курса

Модуль синтаксического анализатора (парсера)

// Распознавание программы на простом языке. Распознаватель грамматики (парсер)
{ Грамматика:
  progr -> stlist 
  stlist -> st ; stlist | st
  st -> assign | comp | cycl
  assign -> id signa expr
  signa -> := | += | -= | *=
  expr -> id | num
  comp -> begin stlist end
  cycl -> cycle expr st   
}
unit SimpleLangParser1;

interface

procedure Expr;
procedure Assign;
procedure StList;
procedure St; 
procedure Comp;
procedure Cycle;
procedure Progr;
procedure error(message: string := '');

implementation

uses 
  System.Collections.Generic,
  System.IO, 
  SimpleLangLexer1;

procedure Progr;
begin
  StList
end;

procedure StList;
begin
  St;
  while Lex=lexSemicolon do
  begin
    NextLexem;
    St;
  end
end;

procedure St;
begin
  case Lex of
lexBegin: Comp; 
lexCycle: Cycle;
lexId: Assign;
else error('Ожидался оператор');
  end;
end;

procedure Comp;
begin
  NextLexem;
  StList;
  if Lex=lexEnd then
    NextLexem
  else error('Ожидалось end');    
end;

procedure Cycle;
begin
  NextLexem;
  Expr;
  St;
end;

procedure Assign;
begin
  NextLexem;
  if Lex in [lexAssign,lexAssignPlus,lexAssignMinus,lexAssignMult] then
    NextLexem
  else error('Ожидалось :=');  
  Expr;  
end;

procedure Expr;
begin
  if lex in [lexId,lexNum] then
    NextLexem 
  else error('Ожидалось выражение');  
end;

procedure error(message: string);
begin
  var ss := System.IO.File.ReadLines(fname).Skip(LexRow-1).First(); // Строка row файла
  writeln('Синтаксическая ошибка в строке ',LexRow,':');
  writeln(ss);
  writeln('^':LexCol-1);
  if message<>'' then 
    writeln(message);
  Done;  
  halt;
end;
 
end.

Основная программа:

uses SimpleLangLexer1,SimpleLangParser1;

begin 
  Init('progr.txt');
  Progr;
  if Lex=lexEot then
    writeln('программа распознана правильно ')
  else error('ожидался конец файла'); 
end.