📄 expressiony2.pas
字号:
(* Yacc parser template (TP Yacc V3.0), V1.2 6-17-91 AG *)
(* global definitions: *)
{*
计算简单的数学表达式的yacc程序
编译:yacc Expression ExpressionY
*}
unit ExpressionY2;
interface
uses
SysUtils, LexLib, YaccLib, ExpressionL2;
{指定不同于整数的类型时,一定要使用%type <Real> expression 指定表达式的类型}
{同时要使用 %token <Real> Number来指定token的类型}
const
NAME = 257;
const
NUMBER = 258;
const
UMINUS = 259;
type
YYSType = record case Integer of
1: (yyReal: Real);
end (*YYSType*);
var
yylval: YYSType;
function yyparse: integer;
implementation
function yyparse: Integer;
var
yystate, yysp, yyn: Integer;
yys: array[1..yymaxdepth] of Integer;
yyv: array[1..yymaxdepth] of YYSType;
yyval: YYSType;
procedure yyaction(yyruleno: Integer);
(* local definitions: *)
begin
(* actions: *)
case yyruleno of
1:
begin
yyval := yyv[yysp - 2];
end;
2:
begin
writeln(format('= %f', [yyv[yysp - 0].yyReal]));
end;
3:
begin
yyval.yyReal := yyv[yysp - 2].yyReal + yyv[yysp - 0].yyReal;
end;
4:
begin
yyval.yyReal := yyv[yysp - 2].yyReal - yyv[yysp - 0].yyReal;
end;
5:
begin
yyval.yyReal := yyv[yysp - 2].yyReal * yyv[yysp - 0].yyReal;
end;
6:
begin
if (yyv[yysp - 0].yyReal = 0) then
yyerror('除零错误')
else
yyval.yyReal := yyv[yysp - 2].yyReal / yyv[yysp - 0].yyReal;
end;
7:
begin
yyval.yyReal := -yyv[yysp - 0].yyReal;
end;
8:
begin
yyval.yyReal := yyv[yysp - 1].yyReal;
end;
9:
begin
yyval.yyReal := yyv[yysp - 0].yyReal;
end;
end;
end (*yyaction*);
(* parse table: *)
type
YYARec = record
sym, act: Integer;
end;
YYRRec = record
len, sym: Integer;
end;
const
yynacts = 54;
yyngotos = 9;
yynstates = 20;
yynrules = 9;
yya: array[1..yynacts] of YYARec = (
{ 0: }
(sym: 40; act: 3),
(sym: 45; act: 4),
(sym: 257; act: 5),
(sym: 258; act: 6),
{ 1: }
(sym: 0; act: 0),
{ 2: }
(sym: 42; act: 7),
(sym: 43; act: 8),
(sym: 45; act: 9),
(sym: 47; act: 10),
(sym: 0; act: - 2),
{ 3: }
(sym: 40; act: 3),
(sym: 45; act: 4),
(sym: 258; act: 6),
{ 4: }
(sym: 40; act: 3),
(sym: 45; act: 4),
(sym: 258; act: 6),
{ 5: }
(sym: 61; act: 13),
{ 6: }
{ 7: }
(sym: 40; act: 3),
(sym: 45; act: 4),
(sym: 258; act: 6),
{ 8: }
(sym: 40; act: 3),
(sym: 45; act: 4),
(sym: 258; act: 6),
{ 9: }
(sym: 40; act: 3),
(sym: 45; act: 4),
(sym: 258; act: 6),
{ 10: }
(sym: 40; act: 3),
(sym: 45; act: 4),
(sym: 258; act: 6),
{ 11: }
(sym: 41; act: 18),
(sym: 42; act: 7),
(sym: 43; act: 8),
(sym: 45; act: 9),
(sym: 47; act: 10),
{ 12: }
{ 13: }
(sym: 40; act: 3),
(sym: 45; act: 4),
(sym: 258; act: 6),
{ 14: }
{ 15: }
(sym: 42; act: 7),
(sym: 47; act: 10),
(sym: 0; act: - 3),
(sym: 41; act: - 3),
(sym: 43; act: - 3),
(sym: 45; act: - 3),
{ 16: }
(sym: 42; act: 7),
(sym: 47; act: 10),
(sym: 0; act: - 4),
(sym: 41; act: - 4),
(sym: 43; act: - 4),
(sym: 45; act: - 4),
{ 17: }
{ 18: }
{ 19: }
(sym: 42; act: 7),
(sym: 43; act: 8),
(sym: 45; act: 9),
(sym: 47; act: 10),
(sym: 0; act: - 1)
);
yyg: array[1..yyngotos] of YYARec = (
{ 0: }
(sym: - 3; act: 1),
(sym: - 2; act: 2),
{ 1: }
{ 2: }
{ 3: }
(sym: - 2; act: 11),
{ 4: }
(sym: - 2; act: 12),
{ 5: }
{ 6: }
{ 7: }
(sym: - 2; act: 14),
{ 8: }
(sym: - 2; act: 15),
{ 9: }
(sym: - 2; act: 16),
{ 10: }
(sym: - 2; act: 17),
{ 11: }
{ 12: }
{ 13: }
(sym: - 2; act: 19)
{ 14: }
{ 15: }
{ 16: }
{ 17: }
{ 18: }
{ 19: }
);
yyd: array[0..yynstates - 1] of Integer = (
{ 0: } 0,
{ 1: } 0,
{ 2: } 0,
{ 3: } 0,
{ 4: } 0,
{ 5: } 0,
{ 6: }-9,
{ 7: } 0,
{ 8: } 0,
{ 9: } 0,
{ 10: } 0,
{ 11: } 0,
{ 12: }-7,
{ 13: } 0,
{ 14: }-5,
{ 15: } 0,
{ 16: } 0,
{ 17: }-6,
{ 18: }-8,
{ 19: } 0
);
yyal: array[0..yynstates - 1] of Integer = (
{ 0: } 1,
{ 1: } 5,
{ 2: } 6,
{ 3: } 11,
{ 4: } 14,
{ 5: } 17,
{ 6: } 18,
{ 7: } 18,
{ 8: } 21,
{ 9: } 24,
{ 10: } 27,
{ 11: } 30,
{ 12: } 35,
{ 13: } 35,
{ 14: } 38,
{ 15: } 38,
{ 16: } 44,
{ 17: } 50,
{ 18: } 50,
{ 19: } 50
);
yyah: array[0..yynstates - 1] of Integer = (
{ 0: } 4,
{ 1: } 5,
{ 2: } 10,
{ 3: } 13,
{ 4: } 16,
{ 5: } 17,
{ 6: } 17,
{ 7: } 20,
{ 8: } 23,
{ 9: } 26,
{ 10: } 29,
{ 11: } 34,
{ 12: } 34,
{ 13: } 37,
{ 14: } 37,
{ 15: } 43,
{ 16: } 49,
{ 17: } 49,
{ 18: } 49,
{ 19: } 54
);
yygl: array[0..yynstates - 1] of Integer = (
{ 0: } 1,
{ 1: } 3,
{ 2: } 3,
{ 3: } 3,
{ 4: } 4,
{ 5: } 5,
{ 6: } 5,
{ 7: } 5,
{ 8: } 6,
{ 9: } 7,
{ 10: } 8,
{ 11: } 9,
{ 12: } 9,
{ 13: } 9,
{ 14: } 10,
{ 15: } 10,
{ 16: } 10,
{ 17: } 10,
{ 18: } 10,
{ 19: } 10
);
yygh: array[0..yynstates - 1] of Integer = (
{ 0: } 2,
{ 1: } 2,
{ 2: } 2,
{ 3: } 3,
{ 4: } 4,
{ 5: } 4,
{ 6: } 4,
{ 7: } 5,
{ 8: } 6,
{ 9: } 7,
{ 10: } 8,
{ 11: } 8,
{ 12: } 8,
{ 13: } 9,
{ 14: } 9,
{ 15: } 9,
{ 16: } 9,
{ 17: } 9,
{ 18: } 9,
{ 19: } 9
);
yyr: array[1..yynrules] of YYRRec = (
{ 1: }(len: 3; sym: - 3),
{ 2: }(len: 1; sym: - 3),
{ 3: }(len: 3; sym: - 2),
{ 4: }(len: 3; sym: - 2),
{ 5: }(len: 3; sym: - 2),
{ 6: }(len: 3; sym: - 2),
{ 7: }(len: 2; sym: - 2),
{ 8: }(len: 3; sym: - 2),
{ 9: }(len: 1; sym: - 2)
);
const
_error = 256; (* error token *)
function yyact(state, sym: Integer; var act: Integer): Boolean;
(* search action table *)
var
k: Integer;
begin
k := yyal[state];
while (k <= yyah[state]) and (yya[k].sym <> sym) do
inc(k);
if k > yyah[state] then
yyact := false
else
begin
act := yya[k].act;
yyact := true;
end;
end (*yyact*);
function yygoto(state, sym: Integer; var nstate: Integer): Boolean;
(* search goto table *)
var
k: Integer;
begin
k := yygl[state];
while (k <= yygh[state]) and (yyg[k].sym <> sym) do
inc(k);
if k > yygh[state] then
yygoto := false
else
begin
nstate := yyg[k].act;
yygoto := true;
end;
end (*yygoto*);
label
parse, next, error, errlab, shift, reduce, accept, abort;
begin (*yyparse*)
(* initialize: *)
yystate := 0;
yychar := -1;
yynerrs := 0;
yyerrflag := 0;
yysp := 0;
{$IFDEF yydebug}
yydebug := true;
{$ELSE}
yydebug := false;
{$ENDIF}
parse:
(* push state and value: *)
inc(yysp);
if yysp > yymaxdepth then
begin
yyerror('yyparse stack overflow');
goto abort;
end;
yys[yysp] := yystate;
yyv[yysp] := yyval;
next:
if (yyd[yystate] = 0) and (yychar = -1) then
(* get next symbol *)
begin
yychar := yylex;
if yychar < 0 then
yychar := 0;
end;
if yydebug then
writeln('state ', yystate, ', char ', yychar);
(* determine parse action: *)
yyn := yyd[yystate];
if yyn <> 0 then
goto reduce; (* simple state *)
(* no default action; search parse table *)
if not yyact(yystate, yychar, yyn) then
goto error
else if yyn > 0 then
goto shift
else if yyn < 0 then
goto reduce
else
goto accept;
error:
(* error; start error recovery: *)
if yyerrflag = 0 then
yyerror('syntax error');
errlab:
if yyerrflag = 0 then
inc(yynerrs); (* new error *)
if yyerrflag <= 2 then (* incomplete recovery; try again *)
begin
yyerrflag := 3;
(* uncover a state with shift action on error token *)
while (yysp > 0) and not (yyact(yys[yysp], _error, yyn) and
(yyn > 0)) do
begin
if yydebug then
if yysp > 1 then
writeln('error recovery pops state ', yys[yysp], ', uncovers ',
yys[yysp - 1])
else
writeln('error recovery fails ... abort');
dec(yysp);
end;
if yysp = 0 then
goto abort; (* parser has fallen from stack; abort *)
yystate := yyn; (* simulate shift on error *)
goto parse;
end
else (* no shift yet; discard symbol *)
begin
if yydebug then
writeln('error recovery discards char ', yychar);
if yychar = 0 then
goto abort; (* end of input; abort *)
yychar := -1;
goto next; (* clear lookahead char and try again *)
end;
shift:
(* go to new state, clear lookahead character: *)
yystate := yyn;
yychar := -1;
yyval := yylval;
if yyerrflag > 0 then
dec(yyerrflag);
goto parse;
reduce:
(* execute action, pop rule from stack, and go to next state: *)
if yydebug then
writeln('reduce ', -yyn);
yyflag := yyfnone;
yyaction(-yyn);
dec(yysp, yyr[-yyn].len);
if yygoto(yys[yysp], yyr[-yyn].sym, yyn) then
yystate := yyn;
(* handle action calls to yyaccept, yyabort and yyerror: *)
case yyflag of
yyfaccept: goto accept;
yyfabort: goto abort;
yyferror: goto errlab;
end;
goto parse;
accept:
yyparse := 0;
exit;
abort:
yyparse := 1;
exit;
end (*yyparse*);
end.
d.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -