diff options
| author | Charles.Forsyth <devnull@localhost> | 2006-12-22 17:07:39 +0000 |
|---|---|---|
| committer | Charles.Forsyth <devnull@localhost> | 2006-12-22 17:07:39 +0000 |
| commit | 37da2899f40661e3e9631e497da8dc59b971cbd0 (patch) | |
| tree | cbc6d4680e347d906f5fa7fca73214418741df72 /appl/cmd/disk/prep/calc.tab.b | |
| parent | 54bc8ff236ac10b3eaa928fd6bcfc0cdb2ba46ae (diff) | |
20060303a
Diffstat (limited to 'appl/cmd/disk/prep/calc.tab.b')
| -rw-r--r-- | appl/cmd/disk/prep/calc.tab.b | 454 |
1 files changed, 454 insertions, 0 deletions
diff --git a/appl/cmd/disk/prep/calc.tab.b b/appl/cmd/disk/prep/calc.tab.b new file mode 100644 index 00000000..25f81487 --- /dev/null +++ b/appl/cmd/disk/prep/calc.tab.b @@ -0,0 +1,454 @@ +implement Calc; + +#line 2 "calc.y" +# +# from Plan 9. subject to the Lucent Public License 1.02 +# + +include "sys.m"; + sys: Sys; + +include "draw.m"; + + NUM, + DOT, + DOLLAR, + ADD, + SUB, + MUL, + DIV, + FRAC, + NEG: con iota; + +Exp: adt { + ty: int; + n: big; + e1, e2: cyclic ref Exp; +}; + +YYSTYPE: adt { + e: ref Exp; +}; +yyexp: ref Exp; + +YYLEX: adt { + s: string; + n: int; + lval: YYSTYPE; + lex: fn(l: self ref YYLEX): int; + error: fn(l: self ref YYLEX, msg: string); +}; +Calc: module { + + parseexpr: fn(s: string, a, b, c: big): (big, string); + init: fn(nil: ref Draw->Context, nil: list of string); +NUMBER: con 57346; +UNARYMINUS: con 57347; + +}; +YYEOFCODE: con 1; +YYERRCODE: con 2; +YYMAXDEPTH: con 200; + +#line 68 "calc.y" + + +mkNUM(x: big): ref Exp +{ + return ref Exp(NUM, x, nil, nil); +} + +mkOP(ty: int, e1: ref Exp, e2: ref Exp): ref Exp +{ + return ref Exp(ty, big 0, e1, e2); +} + +dot, size, dollar: big; + +YYLEX.lex(l: self ref YYLEX): int +{ + while(l.n < len l.s && isspace(l.s[l.n])) + l.n++; + + if(l.n == len l.s) + return -1; + + if(isdigit(l.s[l.n])){ + for(o := l.n; o < len l.s && isdigit(l.s[o]); o++) + ; + l.lval.e = mkNUM(big l.s[l.n:o]); + l.n = o; + return NUMBER; + } + + return l.s[l.n++]; +} + +isdigit(c: int): int +{ + return c >= '0' && c <= '9'; +} + +isspace(c: int): int +{ + return c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\v' || c == '\f'; +} + +YYLEX.error(nil: self ref YYLEX, s: string) +{ + raise s; +} + +eval(e: ref Exp): big +{ + case e.ty { + NUM => + return e.n; + DOT => + return dot; + DOLLAR => + return dollar; + ADD => + return eval(e.e1)+eval(e.e2); + SUB => + return eval(e.e1)-eval(e.e2); + MUL => + return eval(e.e1)*eval(e.e2); + DIV => + i := eval(e.e2); + if(i == big 0) + raise "division by zero"; + return eval(e.e1)/i; + FRAC => + return (size*eval(e.e1))/big 100; + NEG => + return -eval(e.e1); + * => + raise "invalid operator"; + } +} + +parseexpr(s: string, xdot: big, xdollar: big, xsize: big): (big, string) +{ + dot = xdot; + size = xsize; + dollar = xdollar; + l := ref YYLEX(s, 0, YYSTYPE(nil)); + { + yyparse(l); + if(yyexp == nil) + return (big 0, "nil yylval?"); + return (eval(yyexp), nil); + }exception e{ + "*" => + return (big 0, e); + } +} + +init(nil: ref Draw->Context, args: list of string) +{ + sys = load Sys Sys->PATH; + + while((args = tl args) != nil){ + (r, e) := parseexpr(hd args, big 1000, big 1000000, big 1000000); + if(e != nil) + sys->print("%s\n", e); + else + sys->print("%bd\n", r); + } +} + +yyexca := array[] of {-1, 1, + 1, -1, + -2, 0, +}; +YYNPROD: con 12; +YYPRIVATE: con 57344; +yytoknames: array of string; +yystates: array of string; +yydebug: con 0; +YYLAST: con 30; +yyact := array[] of { + 8, 9, 10, 11, 3, 12, 7, 2, 12, 19, + 1, 4, 5, 6, 13, 14, 15, 16, 17, 18, + 8, 9, 10, 11, 0, 12, 10, 11, 0, 12, +}; +yypact := array[] of { + 0,-1000, 15,-1000,-1000,-1000, 0, 0, 0, 0, + 0, 0,-1000, -5,-1000, 19, 19, -2, -2,-1000, +}; +yypgo := array[] of { + 0, 7, 10, +}; +yyr1 := array[] of { + 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, +}; +yyr2 := array[] of { + 0, 1, 1, 1, 1, 3, 3, 3, 3, 3, + 2, 2, +}; +yychk := array[] of { +-1000, -2, -1, 4, 11, 12, 13, 6, 5, 6, + 7, 8, 10, -1, -1, -1, -1, -1, -1, 14, +}; +yydef := array[] of { + 0, -2, 1, 2, 3, 4, 0, 0, 0, 0, + 0, 0, 10, 0, 11, 6, 7, 8, 9, 5, +}; +yytok1 := array[] of { + 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 12, 10, 3, 3, + 13, 14, 7, 5, 3, 6, 11, 8, +}; +yytok2 := array[] of { + 2, 3, 4, 9, +}; +yytok3 := array[] of { + 0 +}; + +YYSys: module +{ + FD: adt + { + fd: int; + }; + fildes: fn(fd: int): ref FD; + fprint: fn(fd: ref FD, s: string, *): int; +}; + +yysys: YYSys; +yystderr: ref YYSys->FD; + +YYFLAG: con -1000; + +# parser for yacc output + +yytokname(yyc: int): string +{ + if(yyc > 0 && yyc <= len yytoknames && yytoknames[yyc-1] != nil) + return yytoknames[yyc-1]; + return "<"+string yyc+">"; +} + +yystatname(yys: int): string +{ + if(yys >= 0 && yys < len yystates && yystates[yys] != nil) + return yystates[yys]; + return "<"+string yys+">\n"; +} + +yylex1(yylex: ref YYLEX): int +{ + c : int; + yychar := yylex.lex(); + if(yychar <= 0) + c = yytok1[0]; + else if(yychar < len yytok1) + c = yytok1[yychar]; + else if(yychar >= YYPRIVATE && yychar < YYPRIVATE+len yytok2) + c = yytok2[yychar-YYPRIVATE]; + else{ + n := len yytok3; + c = 0; + for(i := 0; i < n; i+=2) { + if(yytok3[i+0] == yychar) { + c = yytok3[i+1]; + break; + } + } + if(c == 0) + c = yytok2[1]; # unknown char + } + if(yydebug >= 3) + yysys->fprint(yystderr, "lex %.4ux %s\n", yychar, yytokname(c)); + return c; +} + +YYS: adt +{ + yyv: YYSTYPE; + yys: int; +}; + +yyparse(yylex: ref YYLEX): int +{ + if(yydebug >= 1 && yysys == nil) { + yysys = load YYSys "$Sys"; + yystderr = yysys->fildes(2); + } + + yys := array[YYMAXDEPTH] of YYS; + + yyval: YYSTYPE; + yystate := 0; + yychar := -1; + yynerrs := 0; # number of errors + yyerrflag := 0; # error recovery flag + yyp := -1; + yyn := 0; + +yystack: + for(;;){ + # put a state and value onto the stack + if(yydebug >= 4) + yysys->fprint(yystderr, "char %s in %s", yytokname(yychar), yystatname(yystate)); + + yyp++; + if(yyp >= len yys) + yys = (array[len yys * 2] of YYS)[0:] = yys; + yys[yyp].yys = yystate; + yys[yyp].yyv = yyval; + + for(;;){ + yyn = yypact[yystate]; + if(yyn > YYFLAG) { # simple state + if(yychar < 0) + yychar = yylex1(yylex); + yyn += yychar; + if(yyn >= 0 && yyn < YYLAST) { + yyn = yyact[yyn]; + if(yychk[yyn] == yychar) { # valid shift + yychar = -1; + yyp++; + if(yyp >= len yys) + yys = (array[len yys * 2] of YYS)[0:] = yys; + yystate = yyn; + yys[yyp].yys = yystate; + yys[yyp].yyv = yylex.lval; + if(yyerrflag > 0) + yyerrflag--; + if(yydebug >= 4) + yysys->fprint(yystderr, "char %s in %s", yytokname(yychar), yystatname(yystate)); + continue; + } + } + } + + # default state action + yyn = yydef[yystate]; + if(yyn == -2) { + if(yychar < 0) + yychar = yylex1(yylex); + + # look through exception table + for(yyxi:=0;; yyxi+=2) + if(yyexca[yyxi] == -1 && yyexca[yyxi+1] == yystate) + break; + for(yyxi += 2;; yyxi += 2) { + yyn = yyexca[yyxi]; + if(yyn < 0 || yyn == yychar) + break; + } + yyn = yyexca[yyxi+1]; + if(yyn < 0){ + yyn = 0; + break yystack; + } + } + + if(yyn != 0) + break; + + # error ... attempt to resume parsing + if(yyerrflag == 0) { # brand new error + yylex.error("syntax error"); + yynerrs++; + if(yydebug >= 1) { + yysys->fprint(yystderr, "%s", yystatname(yystate)); + yysys->fprint(yystderr, "saw %s\n", yytokname(yychar)); + } + } + + if(yyerrflag != 3) { # incompletely recovered error ... try again + yyerrflag = 3; + + # find a state where "error" is a legal shift action + while(yyp >= 0) { + yyn = yypact[yys[yyp].yys] + YYERRCODE; + if(yyn >= 0 && yyn < YYLAST) { + yystate = yyact[yyn]; # simulate a shift of "error" + if(yychk[yystate] == YYERRCODE) + continue yystack; + } + + # the current yyp has no shift onn "error", pop stack + if(yydebug >= 2) + yysys->fprint(yystderr, "error recovery pops state %d, uncovers %d\n", + yys[yyp].yys, yys[yyp-1].yys ); + yyp--; + } + # there is no state on the stack with an error shift ... abort + yyn = 1; + break yystack; + } + + # no shift yet; clobber input char + if(yydebug >= 2) + yysys->fprint(yystderr, "error recovery discards %s\n", yytokname(yychar)); + if(yychar == YYEOFCODE) { + yyn = 1; + break yystack; + } + yychar = -1; + # try again in the same state + } + + # reduction by production yyn + if(yydebug >= 2) + yysys->fprint(yystderr, "reduce %d in:\n\t%s", yyn, yystatname(yystate)); + + yypt := yyp; + yyp -= yyr2[yyn]; +# yyval = yys[yyp+1].yyv; + yym := yyn; + + # consult goto table to find next state + yyn = yyr1[yyn]; + yyg := yypgo[yyn]; + yyj := yyg + yys[yyp].yys + 1; + + if(yyj >= YYLAST || yychk[yystate=yyact[yyj]] != -yyn) + yystate = yyact[yyg]; + case yym { + +1=> +#line 54 "calc.y" +{ yyexp = yys[yypt-0].yyv.e; return 0; } +2=> +yyval.e = yys[yyp+1].yyv.e; +3=> +#line 57 "calc.y" +{ yyval.e = mkOP(DOT, nil, nil); } +4=> +#line 58 "calc.y" +{ yyval.e = mkOP(DOLLAR, nil, nil); } +5=> +#line 59 "calc.y" +{ yyval.e = yys[yypt-1].yyv.e; } +6=> +#line 60 "calc.y" +{ yyval.e = mkOP(ADD, yys[yypt-2].yyv.e, yys[yypt-0].yyv.e); } +7=> +#line 61 "calc.y" +{ yyval.e = mkOP(SUB, yys[yypt-2].yyv.e, yys[yypt-0].yyv.e); } +8=> +#line 62 "calc.y" +{ yyval.e = mkOP(MUL, yys[yypt-2].yyv.e, yys[yypt-0].yyv.e); } +9=> +#line 63 "calc.y" +{ yyval.e = mkOP(DIV, yys[yypt-2].yyv.e, yys[yypt-0].yyv.e); } +10=> +#line 64 "calc.y" +{ yyval.e = mkOP(FRAC, yys[yypt-1].yyv.e, nil); } +11=> +#line 65 "calc.y" +{ yyval.e = mkOP(NEG, yys[yypt-0].yyv.e, nil); } + } + } + + return yyn; +} |
