⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 expressiony2.pas

📁 语法分析 语法分析
💻 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 + -