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