1*46439007SCharles.Forsyth 2*46439007SCharles.ForsythYYSys: module 3*46439007SCharles.Forsyth{ 4*46439007SCharles.Forsyth FD: adt 5*46439007SCharles.Forsyth { 6*46439007SCharles.Forsyth fd: int; 7*46439007SCharles.Forsyth }; 8*46439007SCharles.Forsyth fildes: fn(fd: int): ref FD; 9*46439007SCharles.Forsyth fprint: fn(fd: ref FD, s: string, *): int; 10*46439007SCharles.Forsyth}; 11*46439007SCharles.Forsyth 12*46439007SCharles.Forsythyysys: YYSys; 13*46439007SCharles.Forsythyystderr: ref YYSys->FD; 14*46439007SCharles.Forsyth 15*46439007SCharles.ForsythYYFLAG: con -1000; 16*46439007SCharles.Forsyth 17*46439007SCharles.Forsyth# parser for yacc output 18*46439007SCharles.Forsyth 19*46439007SCharles.Forsythyytokname(yyc: int): string 20*46439007SCharles.Forsyth{ 21*46439007SCharles.Forsyth if(yyc > 0 && yyc <= len yytoknames && yytoknames[yyc-1] != nil) 22*46439007SCharles.Forsyth return yytoknames[yyc-1]; 23*46439007SCharles.Forsyth return "<"+string yyc+">"; 24*46439007SCharles.Forsyth} 25*46439007SCharles.Forsyth 26*46439007SCharles.Forsythyystatname(yys: int): string 27*46439007SCharles.Forsyth{ 28*46439007SCharles.Forsyth if(yys >= 0 && yys < len yystates && yystates[yys] != nil) 29*46439007SCharles.Forsyth return yystates[yys]; 30*46439007SCharles.Forsyth return "<"+string yys+">\n"; 31*46439007SCharles.Forsyth} 32*46439007SCharles.Forsyth 33*46439007SCharles.Forsythyylex1(yylex: ref YYLEX): int 34*46439007SCharles.Forsyth{ 35*46439007SCharles.Forsyth c : int; 36*46439007SCharles.Forsyth yychar := yylex.lex(); 37*46439007SCharles.Forsyth if(yychar <= 0) 38*46439007SCharles.Forsyth c = yytok1[0]; 39*46439007SCharles.Forsyth else if(yychar < len yytok1) 40*46439007SCharles.Forsyth c = yytok1[yychar]; 41*46439007SCharles.Forsyth else if(yychar >= YYPRIVATE && yychar < YYPRIVATE+len yytok2) 42*46439007SCharles.Forsyth c = yytok2[yychar-YYPRIVATE]; 43*46439007SCharles.Forsyth else{ 44*46439007SCharles.Forsyth n := len yytok3; 45*46439007SCharles.Forsyth c = 0; 46*46439007SCharles.Forsyth for(i := 0; i < n; i+=2) { 47*46439007SCharles.Forsyth if(yytok3[i+0] == yychar) { 48*46439007SCharles.Forsyth c = yytok3[i+1]; 49*46439007SCharles.Forsyth break; 50*46439007SCharles.Forsyth } 51*46439007SCharles.Forsyth } 52*46439007SCharles.Forsyth if(c == 0) 53*46439007SCharles.Forsyth c = yytok2[1]; # unknown char 54*46439007SCharles.Forsyth } 55*46439007SCharles.Forsyth if(yydebug >= 3) 56*46439007SCharles.Forsyth yysys->fprint(yystderr, "lex %.4ux %s\n", yychar, yytokname(c)); 57*46439007SCharles.Forsyth return c; 58*46439007SCharles.Forsyth} 59*46439007SCharles.Forsyth 60*46439007SCharles.ForsythYYS: adt 61*46439007SCharles.Forsyth{ 62*46439007SCharles.Forsyth yyv: YYSTYPE; 63*46439007SCharles.Forsyth yys: int; 64*46439007SCharles.Forsyth}; 65*46439007SCharles.Forsyth 66*46439007SCharles.Forsythyyparse(yylex: ref YYLEX): int 67*46439007SCharles.Forsyth{ 68*46439007SCharles.Forsyth if(yydebug >= 1 && yysys == nil) { 69*46439007SCharles.Forsyth yysys = load YYSys "$Sys"; 70*46439007SCharles.Forsyth yystderr = yysys->fildes(2); 71*46439007SCharles.Forsyth } 72*46439007SCharles.Forsyth 73*46439007SCharles.Forsyth yys := array[YYMAXDEPTH] of YYS; 74*46439007SCharles.Forsyth 75*46439007SCharles.Forsyth yyval: YYSTYPE; 76*46439007SCharles.Forsyth yystate := 0; 77*46439007SCharles.Forsyth yychar := -1; 78*46439007SCharles.Forsyth yynerrs := 0; # number of errors 79*46439007SCharles.Forsyth yyerrflag := 0; # error recovery flag 80*46439007SCharles.Forsyth yyp := -1; 81*46439007SCharles.Forsyth yyn := 0; 82*46439007SCharles.Forsyth 83*46439007SCharles.Forsythyystack: 84*46439007SCharles.Forsyth for(;;){ 85*46439007SCharles.Forsyth # put a state and value onto the stack 86*46439007SCharles.Forsyth if(yydebug >= 4) 87*46439007SCharles.Forsyth yysys->fprint(yystderr, "char %s in %s", yytokname(yychar), yystatname(yystate)); 88*46439007SCharles.Forsyth 89*46439007SCharles.Forsyth yyp++; 90*46439007SCharles.Forsyth if(yyp >= len yys) 91*46439007SCharles.Forsyth yys = (array[len yys * 2] of YYS)[0:] = yys; 92*46439007SCharles.Forsyth yys[yyp].yys = yystate; 93*46439007SCharles.Forsyth yys[yyp].yyv = yyval; 94*46439007SCharles.Forsyth 95*46439007SCharles.Forsyth for(;;){ 96*46439007SCharles.Forsyth yyn = yypact[yystate]; 97*46439007SCharles.Forsyth if(yyn > YYFLAG) { # simple state 98*46439007SCharles.Forsyth if(yychar < 0) 99*46439007SCharles.Forsyth yychar = yylex1(yylex); 100*46439007SCharles.Forsyth yyn += yychar; 101*46439007SCharles.Forsyth if(yyn >= 0 && yyn < YYLAST) { 102*46439007SCharles.Forsyth yyn = yyact[yyn]; 103*46439007SCharles.Forsyth if(yychk[yyn] == yychar) { # valid shift 104*46439007SCharles.Forsyth yychar = -1; 105*46439007SCharles.Forsyth yyp++; 106*46439007SCharles.Forsyth if(yyp >= len yys) 107*46439007SCharles.Forsyth yys = (array[len yys * 2] of YYS)[0:] = yys; 108*46439007SCharles.Forsyth yystate = yyn; 109*46439007SCharles.Forsyth yys[yyp].yys = yystate; 110*46439007SCharles.Forsyth yys[yyp].yyv = yylex.lval; 111*46439007SCharles.Forsyth if(yyerrflag > 0) 112*46439007SCharles.Forsyth yyerrflag--; 113*46439007SCharles.Forsyth if(yydebug >= 4) 114*46439007SCharles.Forsyth yysys->fprint(yystderr, "char %s in %s", yytokname(yychar), yystatname(yystate)); 115*46439007SCharles.Forsyth continue; 116*46439007SCharles.Forsyth } 117*46439007SCharles.Forsyth } 118*46439007SCharles.Forsyth } 119*46439007SCharles.Forsyth 120*46439007SCharles.Forsyth # default state action 121*46439007SCharles.Forsyth yyn = yydef[yystate]; 122*46439007SCharles.Forsyth if(yyn == -2) { 123*46439007SCharles.Forsyth if(yychar < 0) 124*46439007SCharles.Forsyth yychar = yylex1(yylex); 125*46439007SCharles.Forsyth 126*46439007SCharles.Forsyth # look through exception table 127*46439007SCharles.Forsyth for(yyxi:=0;; yyxi+=2) 128*46439007SCharles.Forsyth if(yyexca[yyxi] == -1 && yyexca[yyxi+1] == yystate) 129*46439007SCharles.Forsyth break; 130*46439007SCharles.Forsyth for(yyxi += 2;; yyxi += 2) { 131*46439007SCharles.Forsyth yyn = yyexca[yyxi]; 132*46439007SCharles.Forsyth if(yyn < 0 || yyn == yychar) 133*46439007SCharles.Forsyth break; 134*46439007SCharles.Forsyth } 135*46439007SCharles.Forsyth yyn = yyexca[yyxi+1]; 136*46439007SCharles.Forsyth if(yyn < 0){ 137*46439007SCharles.Forsyth yyn = 0; 138*46439007SCharles.Forsyth break yystack; 139*46439007SCharles.Forsyth } 140*46439007SCharles.Forsyth } 141*46439007SCharles.Forsyth 142*46439007SCharles.Forsyth if(yyn != 0) 143*46439007SCharles.Forsyth break; 144*46439007SCharles.Forsyth 145*46439007SCharles.Forsyth # error ... attempt to resume parsing 146*46439007SCharles.Forsyth if(yyerrflag == 0) { # brand new error 147*46439007SCharles.Forsyth yylex.error("syntax error"); 148*46439007SCharles.Forsyth yynerrs++; 149*46439007SCharles.Forsyth if(yydebug >= 1) { 150*46439007SCharles.Forsyth yysys->fprint(yystderr, "%s", yystatname(yystate)); 151*46439007SCharles.Forsyth yysys->fprint(yystderr, "saw %s\n", yytokname(yychar)); 152*46439007SCharles.Forsyth } 153*46439007SCharles.Forsyth } 154*46439007SCharles.Forsyth 155*46439007SCharles.Forsyth if(yyerrflag != 3) { # incompletely recovered error ... try again 156*46439007SCharles.Forsyth yyerrflag = 3; 157*46439007SCharles.Forsyth 158*46439007SCharles.Forsyth # find a state where "error" is a legal shift action 159*46439007SCharles.Forsyth while(yyp >= 0) { 160*46439007SCharles.Forsyth yyn = yypact[yys[yyp].yys] + YYERRCODE; 161*46439007SCharles.Forsyth if(yyn >= 0 && yyn < YYLAST) { 162*46439007SCharles.Forsyth yystate = yyact[yyn]; # simulate a shift of "error" 163*46439007SCharles.Forsyth if(yychk[yystate] == YYERRCODE) 164*46439007SCharles.Forsyth continue yystack; 165*46439007SCharles.Forsyth } 166*46439007SCharles.Forsyth 167*46439007SCharles.Forsyth # the current yyp has no shift onn "error", pop stack 168*46439007SCharles.Forsyth if(yydebug >= 2) 169*46439007SCharles.Forsyth yysys->fprint(yystderr, "error recovery pops state %d, uncovers %d\n", 170*46439007SCharles.Forsyth yys[yyp].yys, yys[yyp-1].yys ); 171*46439007SCharles.Forsyth yyp--; 172*46439007SCharles.Forsyth } 173*46439007SCharles.Forsyth # there is no state on the stack with an error shift ... abort 174*46439007SCharles.Forsyth yyn = 1; 175*46439007SCharles.Forsyth break yystack; 176*46439007SCharles.Forsyth } 177*46439007SCharles.Forsyth 178*46439007SCharles.Forsyth # no shift yet; clobber input char 179*46439007SCharles.Forsyth if(yydebug >= 2) 180*46439007SCharles.Forsyth yysys->fprint(yystderr, "error recovery discards %s\n", yytokname(yychar)); 181*46439007SCharles.Forsyth if(yychar == YYEOFCODE) { 182*46439007SCharles.Forsyth yyn = 1; 183*46439007SCharles.Forsyth break yystack; 184*46439007SCharles.Forsyth } 185*46439007SCharles.Forsyth yychar = -1; 186*46439007SCharles.Forsyth # try again in the same state 187*46439007SCharles.Forsyth } 188*46439007SCharles.Forsyth 189*46439007SCharles.Forsyth # reduction by production yyn 190*46439007SCharles.Forsyth if(yydebug >= 2) 191*46439007SCharles.Forsyth yysys->fprint(yystderr, "reduce %d in:\n\t%s", yyn, yystatname(yystate)); 192*46439007SCharles.Forsyth 193*46439007SCharles.Forsyth yypt := yyp; 194*46439007SCharles.Forsyth yyp -= yyr2[yyn]; 195*46439007SCharles.Forsyth# yyval = yys[yyp+1].yyv; 196*46439007SCharles.Forsyth yym := yyn; 197*46439007SCharles.Forsyth 198*46439007SCharles.Forsyth # consult goto table to find next state 199*46439007SCharles.Forsyth yyn = yyr1[yyn]; 200*46439007SCharles.Forsyth yyg := yypgo[yyn]; 201*46439007SCharles.Forsyth yyj := yyg + yys[yyp].yys + 1; 202*46439007SCharles.Forsyth 203*46439007SCharles.Forsyth if(yyj >= YYLAST || yychk[yystate=yyact[yyj]] != -yyn) 204*46439007SCharles.Forsyth yystate = yyact[yyg]; 205*46439007SCharles.Forsyth case yym { 206*46439007SCharles.Forsyth $A 207*46439007SCharles.Forsyth } 208*46439007SCharles.Forsyth } 209*46439007SCharles.Forsyth 210*46439007SCharles.Forsyth return yyn; 211*46439007SCharles.Forsyth} 212