
Приложение а (обязательное) Модуль лексического анализатора
Файл LexKRModul.pas
unit LexKRModul;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ActnList, StdCtrls, TypInfo;
type
TState = (S0, S1, S2, S3, S4, S15, S5, S6, S7, S8, S9, S10, S11, S12, S13, S14, S16, S17, S18, SN, SId, S19, S20, err);
TInput_Signal = (D, L, dps, tzs, zpts, tchks, pluss, minuss, mults, divisions, oss, zss, eqvs, BM, Space, other, endf);
Tlexeme_class = (id, num, dp, tz, zpt, tchk, sign, plus, minus, mult, division, os, zs, prisv, spa, key_var, key_begin, key_end, key_read, key_write, key_while, key_do, key_if, key_then, key_else, key_or, key_and, typ, error);
function recognize: TInput_Signal;
const
next_state: array [D..Other,S0..S15] of TState =
( (S2, S1, S2, S4, S4, err),
(S1, S1, err, err, err, err),
(S15, SId, err, err, err, err),
(S14, SId, SN, err, SN, err),
(S6, SId, S3, err, err, err),
(S5, SId, S3, err, err, err),
(S7, SId, SN, err, SN, err),
(S8, SId, SN, err, SN, err),
(S9, SId, SN, err, SN, err),
(S10, SId, SN, err, SN, err),
(S11, SId, SN, err, SN, err),
(S12, SId, SN, err, SN, err),
(S13, SId, SN, err, SN, S16),
(S13, SId, SN, err, SN, err),
(S18, SId, S20, err, SN, S17),
(err, err, err, err, err, err) );
var
symb: string; TestResult: Boolean; Entry, lex_znach: string;
implementation
function recognize: TInput_Signal;
begin
if entry=''
then begin
result:=endf;
end
else begin
case Entry[1] of
'0'..'9': Result:=D;
'a'..'z', 'A'..'Z': Result:=L;
':': Result:=dps;
';': Result:=tzs;
',': Result:=zpts;
'.': Result:=tchks;
'+': Result:=pluss;
'-': Result:=minuss;
'*': Result:=mults;
'/': Result:=divisions;
'(': Result:=oss;
')': Result:=zss;
'=': Result:=eqvs;
'>','<': Result:=BM;
' ': Result:= Space;
else Result:=other;
end;
if result <> space then
begin
lex_znach:=lex_znach+entry[1];
entry:=copy(entry, 2,length(entry)-1);
symb:=entry[1];
end
else entry:=copy(entry, 2,length(entry)-1);
end;
end;
end.
Файл ILex.pas
function lex : Integer;
var cur_state: TState; cur_input: TInput_Signal;
flag: Boolean;
begin
lex_znach:=''; cur_state:=s0; cur_input:=recognize; flag:=false;
while (cur_state<>S17) and (cur_state<>S5) and (cur_state<>S6) and
(cur_state<>S7) and (cur_state<>S8) and (cur_state<>S9) and
(cur_state<>S10) and (cur_state<>S13) and (cur_state<>S14)and
(cur_state<>S16) and (cur_state<>S11) and (cur_state<>S12)and
(cur_state<>S18) and (cur_state<>SN) and (cur_state<>SId) and
(cur_state<>S19) and (cur_state<>S20) and
(cur_input<>endf) do
begin
cur_state:=next_state[cur_input, cur_state];
if cur_state=err then
raise exception.create('Лексическая ошибка');
if (cur_state=SN) or (cur_state=SId)
then begin
case cur_state of
SN: cur_state:=S19;
SId: cur_state:=S20;
end;
If symb<>' ' then begin
symb:=copy(lex_znach,length(lex_znach),1);
entry:=symb+entry;
lex_znach:=copy(lex_znach,0, length(lex_znach)-1); end;
end
else
if (cur_state<>S17) and (cur_state<>S5) and (cur_state<>S6) and
(cur_state<>S7) and (cur_state<>S8) and (cur_state<>S9) and
(cur_state<>S10) and (cur_state<>S13) and (cur_state<>S14)and
(cur_state<>S16) and (cur_state<>S11) and (cur_state<>S12)and
(cur_state<>S18) and (cur_state<>SN) and (cur_state<>SId) and
(cur_state<>S19) and (cur_state<>S20)
then cur_input:=recognize;
end;
if (cur_state<>S17) and (cur_state<>S5) and (cur_state<>S6) and
(cur_state<>S7) and (cur_state<>S8) and (cur_state<>S9) and
(cur_state<>S10) and (cur_state<>S13) and (cur_state<>S14)and
(cur_state<>S16) and (cur_state<>S11) and (cur_state<>S12)and
(cur_state<>S18) and (cur_state<>SN) and (cur_state<>SId) and
(cur_state<>S19) and (cur_state<>S20) and
(cur_input=endf)
then raise exception.create('Лексическая ошибка. Автомат не дошел до конечного состояния, а входная последовательность разобрана')
else begin
case cur_state of
SId,S20: begin
Result:=id; yylval.yyidtype := lex_znach;
if lex_znach='var' then begin yylval.yyst3 := lex_znach; Result:=key_var end;
if (lex_znach='integer') or (lex_znach='real') or (lex_znach='boolean') then begin yylval.yyst7 := lex_znach; Result:=typ end;
if lex_znach='begin' then begin yylval.yyst5 := lex_znach; Result:=key_begin end;
if lex_znach='end' then begin yylval.yyst3 := lex_znach; Result:=key_end end;
if lex_znach='read' then begin yylval.yyst4 := lex_znach; Result:=key_read end;
if lex_znach='write' then begin yylval.yyst5 := lex_znach; Result:=key_write end;
if lex_znach='while' then begin yylval.yyst5 := lex_znach; Result:=key_while end;
if lex_znach='do' then begin yylval.yyst2 := lex_znach; Result:=key_do end;
if lex_znach='if' then begin yylval.yyst2 := lex_znach; Result:=key_if end;
if lex_znach='then' then begin yylval.yyst4 := lex_znach; Result:=key_then end;
if lex_znach='else' then begin yylval.yyst4 := lex_znach; Result:=key_else end;
if lex_znach='or' then begin yylval.yyst2 := lex_znach; Result:=key_or end;
if lex_znach='and' then begin yylval.yyst3 := lex_znach; Result:=key_and end;
end;
SN,S19: begin yylval.yyreal := strtofloat(lex_znach); Result := num end;
S16: begin yylval.yyst2 := lex_znach; Result:=prisv end;
S17: begin yylval.yyst1 := lex_znach; Result:=dp end;
S14: begin yylval.yyst1 := lex_znach; Result:=tz end;
S6: begin yylval.yyst1 := lex_znach; Result:=zpt end;
S5: begin yylval.yyst1 := lex_znach; Result:=tchk end;
S13: begin yylval.yyst1 := lex_znach; showmessage('<>='); Result:=sign end;
S7: begin yylval.yyst1 := lex_znach; Result:=plus end;
S8: begin yylval.yyst1 := lex_znach; Result:=minus end;
S9: begin yylval.yyst1 := lex_znach; Result:=mult end;
S10: begin yylval.yyst1 := lex_znach; Result:=division end;
S11: begin yylval.yyst1 := lex_znach; Result:=os end;
S12: begin yylval.yyst1 := lex_znach; Result:=zs end;
end;
if cur_input = endf then result := 0; end;
end;
end.