xref: /inferno-os/lib/yaccpar (revision 46439007cf417cbd9ac8049bb4122c890097a0fa)
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