AP_NOT3: AddKeyToList(LEX_AND,AP_SIGN);
AP_LT: AddKeyToList(LEX_LT,AP_SIGN);
AP_FIN: AddKeyToList(LEX_FIN,AP_START);
AP_CONST: AddConstToList(AP_START,j+1);
AP_ASSIGN: posCur:= AP_ERR;
AP_IF1,AP_PROG1,AP_PROG2,AP_PROG3,
AP_ELSE1,AP_ELSE2,AP_ELSE3,AP_XOR1,AP_XOR2,
AP_OR1,AP_DO1,AP_AND1,AP_AND2,AP_NOT1,AP_NOT2,
AP_WHILE1,AP_WHILE2,AP_WHILE3,AP_WHILE4,
AP_END2,AP_BEGIN1,AP_BEGIN2,AP_BEGIN3,AP_BEGIN4,
AP_VAR: AddVarToList(AP_START,j+1);
end{case pos2};
end;
if posCur = AP_ERR then {Проверяем, не было ли ошибки}
begin { Вычисляем позицию ошибочной лексемы }
iStart:= (j – iStart)+1; { Запоминаем ее в виде
фиктивной лексемы в начале списка }
listLex.Insert(0,{для детальной диагностики ошибки}
TLexem.CreateInfo('Недопустимая лексема',
iAll-iStart,i,iStart));
Break; { Если ошибка, прерываем цикл }
end;
end{for j};
Inc(iAll,2); { В конце строки увеличиваем общий счетчик
cимволов на 2: конец строки и возврат каретки }
if posCur = AP_ERR then {Если ошибка, запоминаем номер}
begin { ошибочной строки и прерываем цикл }
Result:= i+1; Break;
end;
end{for i};
if posCur in [AP_COMM,AP_COMMSG] then
begin { Если комментарий не был закрыт, то это ошибка }
listLex.Insert(0,
TLexem.CreateInfo('Незакрытый комментарий',
iStComm,iCnt,iAll-iStComm));
Result:= iCnt;
end
else
if not (posCur in [AP_START,AP_SIGN,AP_ERR]) then
begin {Если КА не в начальном состоянии – }
listLex.Insert(0, {это неверная лексема}
TLexem.CreateInfo('Незавершенная лексема',
iAll-iStart,iCnt,iStart));
Result:= iCnt;
end;
end;
end.
Модуль описания матрицы предшествования и правил исходной грамматики
unit SyntRule; {!!! Зависит от входного языка!!!}
interface
{ Модуль, содержащий описание матрицы предшествования
и правил грамматики }
uses LexType, Classes;
const { Максимальная длина правила }
RULE_LENGTH = 7; { (в расчете на символы грамматики) }
RULE_NUM = 28; { Общее количество правил грамматики }
Var { Матрица операторного предшествования }
GramMatrix: array[TLexType,TLexType] of char =
({pr. end.; if () else beg end whl do a c:= or xor and < > = <> not – + um! }
{pr.} ( , = , <, <, ,', ,'<, ,'<, ,'<, ,', ,', ,', ,', ,
', , , , ),
{end.}( , , , , , , , , , , , , , , , , , , , , ,
', , , , >),
{;} ( , >, >, <, ,', ,'<, >, <, ,'<, ,', ,', ,', ,', ,
', , , , ),
{if} ( , , , , = , , , , , , , , , , , , , , , , ,
', , , , ),
{(} ( , , , , <, =, ,', ,', ,'<, <,
', <, <, <, <, <, <, <, <, <, <, <, ),
{)} ( , >, >, <, ,'>, =, <, >, <, =, <, ,', >, >, >, >, >, >, >,
', >, >, ,'),
{else}( , >, >, <, ,', >, <, >, <, ,'<, ,', ,', ,', ,', ,
', , , , ),
{beg.}( , , <, <, ,', ,'<, =, <, ,'<, ,', ,', ,', ,', ,
', , , , ),
{end} ( , >, >, ,', ,'>, ,'>, ,', ,', ,', ,', ,', ,',
', , , , ),
{whil}( , , , , = , , , , , , , , , , , , , , , , ,
', , , , ),
{do} ( , >, >, <, ,', >, <, <, <, ,'<, ,', ,', ,', ,', ,
', , , , ),
{a} ( , >, >, ,', >, >, ,'>, ,', ,', =, >, >, >, >, >, >, >,
', >, >, ,'),
{c} ( , >, >, ,', >, >, ,'>, ,', ,', ,'>, >, >, >, >, >, >,
', >, >, ,'),
{:=} ( , >, >, ,'<, ,'>, ,'>, ,', <, <, ,', ,', ,', ,',
', <, <, <, ),
{or} ( , , , , <, >, ,', ,', ,'<, <,
', >, >, <, <, <, <, <, <, <, <, <, ),
{xor} ( , , , , <, >, ,', ,', ,'<, <,
', >, >, <, <, <, <, <, <, <, <, <, ),
{and} ( , , , , <, >, ,', ,', ,'<, <,
', >, >, >, <, <, <, <, <, <, <, <, ),
{<} ( , , , , <, >, ,', ,', ,'<, <, ,'>, >, >, ,', ,',
', <, <, <, ),
{>} ( , , , , <, >, ,', ,', ,'<, <, ,'>, >, >, ,', ,',
', <, <, <, ),
{=} ( , , , , <, >, ,', ,', ,'<, <, ,'>, >, >, ,', ,',
', <, <, <, ),
{<>} ( , , , , <, >, ,', ,', ,'<, <, ,'>, >, >, ,', ,',
', <, <, <, ),
{not} ( , , , , = , , , , , , , , , , , , , , , , ,
', , , , ),
{-} ( , >, >, ,'<, >, >, ,'>, ,', <, <, ,'>, >, >, >, >, >, >,
', >, >, <, ),
{+} ( , >, >, ,'<, >, >, ,'>, ,', <, <, ,'>, >, >, >, >, >, >,
', >, >, <, ),
{um} ( , >, >, ,'<, >, >, ,'>, ,', <, <, ,'>, >, >, >, >, >, >,
', >, >, <, ),
{!} (<, ,', ,', ,', ,', ,', ,', ,', ,', ,', ,',
', , , , ));
{ Правила исходной грамматики }
GramRules: array[1..RULE_NUM] of string =
('progEend.,'E','E;E','E;,'if(B)EelseE','if(B)E',
'beginEend','while(B)doE','a:=E','BorB','BxorB','B',
'BandB','B','E
'E-E','E+E','E', -E','E', (E),'a','c');
{ Функция имени нетерминала для каждого правила }
function MakeSymbolStr(iRuleNum: integer): string;
{ Функция корректировки отношений предшествования
для расширения матрицы предшествования }
function CorrectRule(cRule: char; lexTop,lexCur: TLexType;
symbStack: TList): char;
implementation
uses SyntSymb;
function MakeSymbolStr(iRuleNum: integer): string;
begin
if iRuleNum in [10..20] then Result:= 'B'
else Result:= 'E';
end;
function CorrectRule(cRule: char; lexTop,lexCur: TLexType;
symbStack: TList): char;
var j: integer;
begin { Корректируем отношение для символа «else»,
если в стеке не логическое выражение }
Result:= cRule;
if (cRule = = ) and (lexTop = LEX_CLOSE)
and (lexCur = LEX_ELSE) then
begin
j:= TSymbStack(symbStack). Count-1;
if (j > 2)
and (TSymbStack(symbStack)[j-2].SymbolStr <> 'B')