xref: /csrg-svn/usr.bin/pascal/src/pas.y (revision 62234)
148119Sbostic /*-
2*62234Sbostic  * Copyright (c) 1979, 1980, 1993
3*62234Sbostic  *	The Regents of the University of California.  All rights reserved.
423620Smckusick  *
548119Sbostic  * %sccs.include.redist.c%
648119Sbostic  *
7*62234Sbostic  *	@(#)pas.y	8.1 (Berkeley) 06/06/93
822255Sdist  */
9798Speter 
10798Speter /*
11798Speter  * Yacc grammar for UNIX Pascal
12798Speter  *
13798Speter  * This grammar is processed by the commands in the shell script
14798Speter  * "gram" to yield parse tables and semantic routines in the file
15798Speter  * "y.tab.c" and a header defining the lexical tokens in "yy.h".
16798Speter  *
17798Speter  * In order for the syntactic error recovery possible with this
18798Speter  * grammar to work, the grammar must be processed by a yacc which
19798Speter  * has been modified to fully enumerate possibilities in states
20798Speter  * which involve the symbol "error".
21798Speter  * The parser used for Pascal also uses a different encoding of
22798Speter  * the test entries in the action table which speeds the parse.
23798Speter  * A version of yacc which will work for Pascal is included on
24798Speter  * the distribution table as "eyacc".
25798Speter  *
26798Speter  * The "gram" script also makes the following changes to the "y.tab.c"
27798Speter  * file:
28798Speter  *
29798Speter  *	1) Causes yyval to be declared int *.
30798Speter  *
31798Speter  *	2) Loads the variable yypv into a register as yyYpv so that
32798Speter  *	   the arguments $1, ... are available as yyYpv[1] etc.
33798Speter  *	   This produces much smaller code in the semantic actions.
34798Speter  *
35798Speter  *	3) Deletes the unused array yysterm.
36798Speter  *
37798Speter  *	4) Moves the declarations up to the flag line containing
38798Speter  *	   '##' to the file yy.h so that the routines which use
39798Speter  *	   these "magic numbers" don't have to all be compiled at
40798Speter  *	   the same time.
41798Speter  *
42798Speter  *	5) Creates the semantic restriction checking routine yyEactr
43804Speter  *	   by processing action lines containing `@@'.
44798Speter  *
45798Speter  * This compiler uses a different version of the yacc parser, a
46798Speter  * different yyerror which is called yerror, and requires more
47798Speter  * lookahead sets than normally provided by yacc.
48798Speter  *
49798Speter  * Source for the yacc used with this grammar is included on
50798Speter  * distribution tapes.
51798Speter  */
52798Speter 
53798Speter /*
54798Speter  * TERMINAL DECLARATIONS
55798Speter  *
56798Speter  * Some of the terminal declarations are out of the most natural
57798Speter  * alphabetic order because the error recovery
58798Speter  * will guess the first of equal cost non-terminals.
59798Speter  * This makes, e.g. YTO preferable to YDOWNTO.
60798Speter  */
61798Speter 
62798Speter %term
63798Speter 	YAND		YARRAY		YBEGIN		YCASE
64798Speter 	YCONST		YDIV		YDO		YDOTDOT
65798Speter 	YTO		YELSE		YEND		YFILE
6612932Speter 	YFOR		YFORWARD	YPROCEDURE	YGOTO
67798Speter 	YID		YIF		YIN		YINT
68798Speter 	YLABEL		YMOD		YNOT		YNUMB
69798Speter 	YOF		YOR		YPACKED		YNIL
7012932Speter 	YFUNCTION	YPROG		YRECORD		YREPEAT
71798Speter 	YSET		YSTRING		YTHEN		YDOWNTO
72798Speter 	YTYPE		YUNTIL		YVAR		YWHILE
73798Speter 	YWITH		YBINT		YOCT		YHEX
747927Smckusick 	YCASELAB	YILLCH		YEXTERN		YLAST
75798Speter 
76798Speter /*
77798Speter  * PRECEDENCE DECLARATIONS
78798Speter  *
79798Speter  * Highest precedence is the unary logical NOT.
80798Speter  * Next are the multiplying operators, signified by '*'.
81798Speter  * Lower still are the binary adding operators, signified by '+'.
82798Speter  * Finally, at lowest precedence and non-associative are the relationals.
83798Speter  */
84798Speter 
85798Speter %binary	'<'	'='	'>'	YIN
86798Speter %left	'+'	'-'	YOR	'|'
87798Speter %left	UNARYSIGN
88798Speter %left	'*'	'/'	YDIV	YMOD	YAND	'&'
89798Speter %left	YNOT
90798Speter 
91798Speter %{
92798Speter /*
93798Speter  * GLOBALS FOR ACTIONS
94798Speter  */
95798Speter 
96798Speter /* Copyright (c) 1979 Regents of the University of California */
97798Speter 
98*62234Sbostic /* static	char sccsid[] = "@(#)pas.y 8.1 06/06/93"; */
99798Speter 
100798Speter /*
101798Speter  * The following line marks the end of the yacc
102798Speter  * Constant definitions which are removed from
103798Speter  * y.tab.c and placed in the file y.tab.h.
104798Speter  */
105798Speter ##
106798Speter /* Copyright (c) 1979 Regents of the University of California */
107798Speter 
108*62234Sbostic static	char sccsid[] = "@(#)pas.y 8.1 06/06/93";
109798Speter 
110798Speter #include "whoami.h"
111798Speter #include "0.h"
11214752Sthien #include "tree_ty.h"		/* must be included for yy.h */
113798Speter #include "yy.h"
114798Speter #include "tree.h"
115798Speter 
116798Speter #ifdef PI
117798Speter #define	lineof(l)	l
118798Speter #define	line2of(l)	l
119798Speter #endif
120798Speter 
121798Speter %}
122798Speter 
123798Speter %%
124798Speter 
125798Speter /*
126798Speter  * PRODUCTIONS
127798Speter  */
128798Speter 
129798Speter goal:
130837Speter 	prog_hedr decls block '.'
13114752Sthien 		= funcend($1.nl_entry, $3.tr_entry, lineof($4.i_entry));
132798Speter 		|
133837Speter 	decls
134798Speter 		= segend();
135798Speter 		;
136798Speter 
137798Speter 
138798Speter prog_hedr:
139798Speter 	YPROG YID '(' id_list ')' ';'
14014752Sthien 		= $$.nl_entry = funcbody(funchdr(tree5(T_PROG, lineof($1.i_entry), $2.tr_entry, fixlist($4.tr_entry), TR_NIL)));
141798Speter 		|
1427953Speter 	YPROG YID ';'
14314752Sthien 		= $$.nl_entry = funcbody(funchdr(tree5(T_PROG, lineof($1.i_entry),  $2.tr_entry, TR_NIL, TR_NIL)));
1447953Speter 		|
145798Speter 	YPROG error
146798Speter 		= {
147798Speter 			yyPerror("Malformed program statement", PPROG);
148798Speter 			/*
149798Speter 			 * Should make a program statement
150798Speter 			 * with "input" and "output" here.
151798Speter 			 */
15214752Sthien 			$$.nl_entry = funcbody(funchdr(tree5(T_PROG, lineof($1.i_entry), TR_NIL, TR_NIL, TR_NIL)));
153798Speter 		  }
154798Speter 		;
155798Speter block:
156798Speter 	YBEGIN stat_list YEND
157798Speter 		= {
15814752Sthien 			$$.tr_entry = tree3(T_BSTL, lineof($1.i_entry), fixlist($2.tr_entry));
15914752Sthien 			if ($3.i_entry < 0)
16014752Sthien 				brerror($1.i_entry, "begin");
161798Speter 		  }
162798Speter 		;
163798Speter 
164798Speter 
165798Speter /*
166798Speter  * DECLARATION PART
167798Speter  */
168798Speter decls:
169798Speter 	decls decl
170798Speter 		= trfree();
171798Speter 		|
172798Speter 	decls error
173798Speter 		= {
174798Speter 			constend(), typeend(), varend(), trfree();
175798Speter 			yyPerror("Malformed declaration", PDECL);
176798Speter 		  }
177798Speter 		|
178798Speter 	/* lambda */
179798Speter 		= trfree();
180798Speter 		;
181798Speter 
182798Speter decl:
183798Speter 	labels
184798Speter 		|
185798Speter 	const_decl
186798Speter 		= constend();
187798Speter 		|
188798Speter 	type_decl
189798Speter 		= typeend();
190798Speter 		|
191798Speter 	var_decl
192798Speter 		= varend();
193837Speter 		|
194837Speter 	proc_decl
195798Speter 		;
196798Speter 
197798Speter /*
198798Speter  * LABEL PART
199798Speter  */
200798Speter 
201798Speter labels:
202798Speter 	YLABEL label_decl ';'
20314752Sthien 		= label(fixlist($2.tr_entry), lineof($1.i_entry));
204798Speter 		;
205798Speter label_decl:
206798Speter 	YINT
20714752Sthien 		= $$.tr_entry = newlist($1.i_entry == NIL ? TR_NIL :
20814752Sthien 					(struct tnode *) *hash($1.cptr, 1));
209798Speter 		|
210798Speter 	label_decl ',' YINT
21114752Sthien 		= $$.tr_entry = addlist($1.tr_entry, $3.i_entry == NIL ?
21214752Sthien 				TR_NIL : (struct tnode *) *hash($3.cptr, 1));
213798Speter 		;
214798Speter 
215798Speter /*
216798Speter  * CONST PART
217798Speter  */
218798Speter 
219798Speter const_decl:
220798Speter 	YCONST YID '=' const ';'
22132288Smckusick 		= constbeg($1.i_entry, lineof($1.i_entry)),
22233235Sbostic 		  constant(lineof($3.i_entry), $2.cptr, $4.tr_entry);
223798Speter 		|
224798Speter 	const_decl YID '=' const ';'
22533235Sbostic 		= constant(lineof($3.i_entry), $2.cptr, $4.tr_entry);
226798Speter 		|
227798Speter 	YCONST error
228798Speter 		= {
22914752Sthien 			constbeg($1.i_entry);
230798Speter Cerror:
231798Speter 			yyPerror("Malformed const declaration", PDECL);
232798Speter 		  }
233798Speter 		|
234798Speter 	const_decl error
235798Speter 		= goto Cerror;
236798Speter 		;
237798Speter 
238798Speter /*
239798Speter  * TYPE PART
240798Speter  */
241798Speter 
242798Speter type_decl:
243798Speter 	YTYPE YID '=' type ';'
24414752Sthien 		= typebeg($1.i_entry, line2of($2.i_entry)), type(lineof($3.i_entry), $2.cptr, $4.tr_entry);
245798Speter 		|
246798Speter 	type_decl YID '=' type ';'
24714752Sthien 		= type(lineof($3.i_entry), $2.cptr, $4.tr_entry);
248798Speter 		|
249798Speter 	YTYPE error
250798Speter 		= {
25114752Sthien 			typebeg($1.i_entry, line2of($1.i_entry));
252798Speter Terror:
253798Speter 			yyPerror("Malformed type declaration", PDECL);
254798Speter 		  }
255798Speter 		|
256798Speter 	type_decl error
257798Speter 		= goto Terror;
258798Speter 		;
259798Speter 
260798Speter /*
261798Speter  * VAR PART
262798Speter  */
263798Speter 
264798Speter var_decl:
265798Speter 	YVAR id_list ':' type ';'
26614752Sthien 		= varbeg($1.i_entry, line2of($3.i_entry)), var(lineof($3.i_entry), fixlist($2.tr_entry), $4.tr_entry);
267798Speter 		|
268798Speter 	var_decl id_list ':' type ';'
26914752Sthien 		= var(lineof($3.i_entry), fixlist($2.tr_entry), $4.tr_entry);
270798Speter 		|
271798Speter 	YVAR error
272798Speter 		= {
27314752Sthien 			varbeg($1.i_entry, line2of($1.i_entry));
274798Speter Verror:
275798Speter 			yyPerror("Malformed var declaration", PDECL);
276798Speter 		  }
277798Speter 		|
278798Speter 	var_decl error
279798Speter 		= goto Verror;
280798Speter 		;
281798Speter 
282798Speter /*
283798Speter  * PROCEDURE AND FUNCTION DECLARATION PART
284798Speter  */
285798Speter 
286837Speter proc_decl:
287798Speter 	phead YFORWARD ';'
28814752Sthien 		= funcfwd($1.nl_entry);
289798Speter 		|
290798Speter 	phead YEXTERN ';'
29114752Sthien 		= (void) funcext($1.nl_entry);
292798Speter 		|
293837Speter 	pheadres decls block ';'
29414752Sthien 		= funcend($1.nl_entry, $3.tr_entry, lineof($4.i_entry));
2958000Speter 		|
2968000Speter 	phead error
297798Speter 		;
298798Speter pheadres:
299798Speter 	phead
30014752Sthien 		= (void) funcbody($1.nl_entry);
301798Speter 		;
302798Speter phead:
303798Speter 	porf YID params ftype ';'
30414752Sthien 		= $$.nl_entry = funchdr(tree5($1.i_entry, lineof($5.i_entry),
30514752Sthien 				$2.tr_entry, $3.tr_entry, $4.tr_entry));
306798Speter 		;
307798Speter porf:
308798Speter 	YPROCEDURE
30914752Sthien 		= $$.i_entry = T_PDEC;
310798Speter 		|
311798Speter 	YFUNCTION
31214752Sthien 		= $$.i_entry = T_FDEC;
313798Speter 		;
314798Speter params:
315798Speter 	'(' param_list ')'
31614752Sthien 		= $$.tr_entry = fixlist($2.tr_entry);
317798Speter 		|
318798Speter 	/* lambda */
31914752Sthien 		= $$.tr_entry = TR_NIL;
320798Speter 		;
321798Speter 
322798Speter /*
323798Speter  * PARAMETERS
324798Speter  */
325798Speter 
326798Speter param:
327798Speter 	id_list ':' type
32814752Sthien 		= $$.tr_entry = tree3(T_PVAL, (int) fixlist($1.tr_entry), $3.tr_entry);
329798Speter 		|
33017695Smckusick 	YVAR id_list ':' type
33114752Sthien 		= $$.tr_entry = tree3(T_PVAR, (int) fixlist($2.tr_entry), $4.tr_entry);
332798Speter 		|
3333298Smckusic 	YFUNCTION id_list params ftype
33414752Sthien 		= $$.tr_entry = tree5(T_PFUNC, (int) fixlist($2.tr_entry),
33514752Sthien 				$4.tr_entry, $3.tr_entry,
33614752Sthien 				(struct tnode *) lineof($1.i_entry));
337798Speter 		|
3383298Smckusic 	YPROCEDURE id_list params ftype
33914752Sthien 		= $$.tr_entry = tree5(T_PPROC, (int) fixlist($2.tr_entry),
34014752Sthien 				$4.tr_entry, $3.tr_entry,
34114752Sthien 				(struct tnode *) lineof($1.i_entry));
342798Speter 		;
343798Speter ftype:
344798Speter 	':' type
345798Speter 		= $$ = $2;
346798Speter 		|
347798Speter 	/* lambda */
34814752Sthien 		= $$.tr_entry = TR_NIL;
349798Speter 		;
350798Speter param_list:
351798Speter 	param
35214752Sthien 		= $$.tr_entry = newlist($1.tr_entry);
353798Speter 		|
354798Speter 	param_list ';' param
35514752Sthien 		= $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
356798Speter 		;
357798Speter 
358798Speter /*
359798Speter  * CONSTANTS
360798Speter  */
361798Speter 
362798Speter const:
363798Speter 	YSTRING
36414752Sthien 		= $$.tr_entry = tree2(T_CSTRNG, $1.i_entry);
365798Speter 		|
366798Speter 	number
367798Speter 		|
368798Speter 	'+' number
36914752Sthien 		= $$.tr_entry = tree2(T_PLUSC, $2.i_entry);
370798Speter 		|
371798Speter 	'-' number
37214752Sthien 		= $$.tr_entry = tree2(T_MINUSC, $2.i_entry);
373798Speter 		;
374798Speter number:
375798Speter 	const_id
37614752Sthien 		= $$.tr_entry = tree2(T_ID, $1.i_entry);
377798Speter 		|
378798Speter 	YINT
37914752Sthien 		= $$.tr_entry = tree2(T_CINT, $1.i_entry);
380798Speter 		|
381798Speter 	YBINT
38214752Sthien 		= $$.tr_entry = tree2(T_CBINT, $1.i_entry);
383798Speter 		|
384798Speter 	YNUMB
38514752Sthien 		= $$.tr_entry = tree2(T_CFINT, $1.i_entry);
386798Speter 		;
387798Speter const_list:
388798Speter 	const
38914752Sthien 		= $$.tr_entry = newlist($1.tr_entry);
390798Speter 		|
391798Speter 	const_list ',' const
39214752Sthien 		= $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
393798Speter 		;
394798Speter 
395798Speter /*
396798Speter  * TYPES
397798Speter  */
398798Speter 
399798Speter type:
400798Speter 	simple_type
401798Speter 		|
402798Speter 	'^' YID
40314752Sthien 		= $$.tr_entry = tree3(T_TYPTR, lineof($1.i_entry), tree2(T_ID,
40414752Sthien 								$2.i_entry));
405798Speter 		|
406798Speter 	struct_type
407798Speter 		|
408798Speter 	YPACKED struct_type
40914752Sthien 		= $$.tr_entry = tree3(T_TYPACK, lineof($1.i_entry), $2.tr_entry);
410798Speter 		;
411798Speter simple_type:
412798Speter 	type_id
413798Speter 		|
414798Speter 	'(' id_list ')'
41514752Sthien 		= $$.tr_entry = tree3(T_TYSCAL, lineof($1.i_entry), fixlist($2.tr_entry));
416798Speter 		|
417798Speter 	const YDOTDOT const
41814752Sthien 		= $$.tr_entry = tree4(T_TYRANG, lineof($2.i_entry), $1.tr_entry,
41914752Sthien 				$3.tr_entry);
420798Speter 		;
421798Speter struct_type:
422798Speter 	YARRAY '[' simple_type_list ']' YOF type
42314752Sthien 		= $$.tr_entry = tree4(T_TYARY, lineof($1.i_entry),
42414752Sthien 					fixlist($3.tr_entry), $6.tr_entry);
425798Speter 		|
426798Speter 	YFILE YOF type
42714752Sthien 		= $$.tr_entry = tree3(T_TYFILE, lineof($1.i_entry), $3.tr_entry);
428798Speter 		|
429798Speter 	YSET YOF simple_type
43014752Sthien 		= $$.tr_entry = tree3(T_TYSET, lineof($1.i_entry), $3.tr_entry);
431798Speter 		|
432798Speter 	YRECORD field_list YEND
433798Speter 		= {
43414752Sthien 			$$.tr_entry = setuptyrec( lineof( $1.i_entry ) , $2.tr_entry);
43514752Sthien 			if ($3.i_entry < 0)
43614752Sthien 				brerror($1.i_entry, "record");
437798Speter 		  }
438798Speter 		;
439798Speter simple_type_list:
440798Speter 	simple_type
44114752Sthien 		= $$.tr_entry = newlist($1.tr_entry);
442798Speter 		|
443798Speter 	simple_type_list ',' simple_type
44414752Sthien 		= $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
445798Speter 		;
446798Speter 
447798Speter /*
448798Speter  * RECORD TYPE
449798Speter  */
450798Speter field_list:
451798Speter 	fixed_part variant_part
45214752Sthien 		= $$.tr_entry = tree4(T_FLDLST, lineof(NIL),
45314752Sthien 				fixlist($1.tr_entry), $2.tr_entry);
454798Speter 		;
455798Speter fixed_part:
456798Speter 	field
45714752Sthien 		= $$.tr_entry = newlist($1.tr_entry);
458798Speter 		|
459798Speter 	fixed_part ';' field
46014752Sthien 		= $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
461798Speter 		|
462798Speter 	fixed_part error
463798Speter 		= yyPerror("Malformed record declaration", PDECL);
464798Speter 		;
465798Speter field:
466798Speter 	/* lambda */
46714752Sthien 		= $$.tr_entry = TR_NIL;
468798Speter 		|
469798Speter 	id_list ':' type
47014752Sthien 		= $$.tr_entry = tree4(T_RFIELD, lineof($2.i_entry),
47114752Sthien 				fixlist($1.tr_entry), $3.tr_entry);
472798Speter 		;
473798Speter 
474798Speter variant_part:
475798Speter 	/* lambda */
47614752Sthien 		= $$.tr_entry = TR_NIL;
477798Speter 		|
478798Speter 	YCASE type_id YOF variant_list
47914752Sthien 		= $$.tr_entry = tree5(T_TYVARPT, lineof($1.i_entry), TR_NIL,
48014752Sthien 				$2.tr_entry, fixlist($4.tr_entry));
481798Speter 		|
482798Speter 	YCASE YID ':' type_id YOF variant_list
48314752Sthien 		= $$.tr_entry = tree5(T_TYVARPT, lineof($1.i_entry),
48414752Sthien 				$2.tr_entry, $4.tr_entry,
48514752Sthien 					fixlist($6.tr_entry));
486798Speter 		;
487798Speter variant_list:
488798Speter 	variant
48914752Sthien 		= $$.tr_entry = newlist($1.tr_entry);
490798Speter 		|
491798Speter 	variant_list ';' variant
49214752Sthien 		= $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
493798Speter 		|
494798Speter 	variant_list error
495798Speter 		= yyPerror("Malformed record declaration", PDECL);
496798Speter 		;
497798Speter variant:
498798Speter 	/* lambda */
49914752Sthien 		= $$.tr_entry = TR_NIL;
500798Speter 		|
501798Speter 	const_list ':' '(' field_list ')'
50214752Sthien 		= $$.tr_entry = tree4(T_TYVARNT,lineof($2.i_entry), fixlist($1.tr_entry),
50314752Sthien 				$4.tr_entry);
504798Speter 		;
505798Speter 
506798Speter /*
507798Speter  * STATEMENT LIST
508798Speter  */
509798Speter 
510798Speter stat_list:
511798Speter 	stat
51214752Sthien 		= $$.tr_entry = newlist($1.tr_entry);
513798Speter 		|
514798Speter 	stat_lsth stat
515798Speter 		= {
51614752Sthien 			if ((p = $1.tr_entry) != TR_NIL && (q = p->list_node.list)->tag == T_IFX) {
51714752Sthien 				q->tag = T_IFEL;
51814752Sthien 				q->if_node.else_stmnt = $2.tr_entry;
519798Speter 			} else
52014752Sthien 				$$.tr_entry= addlist($1.tr_entry, $2.tr_entry);
521798Speter 		  }
522798Speter 		;
523798Speter 
524798Speter stat_lsth:
525798Speter 	stat_list ';'
52614752Sthien 		= if ((q = $1.tr_entry) != TR_NIL && (p = q->list_node.list) != TR_NIL && p->tag == T_IF) {
527798Speter 			if (yychar < 0)
528798Speter 				yychar = yylex();
529798Speter 			if (yyshifts >= 2 && yychar == YELSE) {
530798Speter 				recovered();
53114752Sthien 				copy((char *) (&Y), (char *) (&OY), sizeof Y);
532798Speter 				yerror("Deleted ';' before keyword else");
533798Speter 				yychar = yylex();
53414752Sthien 				p->tag = T_IFX;
535798Speter 			}
536798Speter 		  }
537798Speter 		;
538798Speter 
539798Speter /*
540798Speter  * CASE STATEMENT LIST
541798Speter  */
542798Speter 
543798Speter cstat_list:
544798Speter 	cstat
54514752Sthien 		= $$.tr_entry = newlist($1.tr_entry);
546798Speter 		|
547798Speter 	cstat_list ';' cstat
54814752Sthien 		= $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
549798Speter 		|
550798Speter 	error
551798Speter 		= {
55214752Sthien 			$$.tr_entry = TR_NIL;
553798Speter Kerror:
554798Speter 			yyPerror("Malformed statement in case", PSTAT);
555798Speter 		  }
556798Speter 		|
557798Speter 	cstat_list error
558798Speter 		= goto Kerror;
559798Speter 		;
560798Speter 
561798Speter cstat:
562798Speter 	const_list ':' stat
56314752Sthien 		= $$.tr_entry = tree4(T_CSTAT, lineof($2.i_entry),
56414752Sthien 				fixlist($1.tr_entry), $3.tr_entry);
565798Speter 		|
566798Speter 	YCASELAB stat
56714752Sthien 		= $$.tr_entry = tree4(T_CSTAT, lineof($1.i_entry), TR_NIL,
56814752Sthien 					$2.tr_entry);
569798Speter 		|
570798Speter 	/* lambda */
57114752Sthien 		= $$.tr_entry = TR_NIL;
572798Speter 		;
573798Speter 
574798Speter /*
575798Speter  * STATEMENT
576798Speter  */
577798Speter 
578798Speter stat:
579798Speter 	/* lambda */
58014752Sthien 		= $$.tr_entry = TR_NIL;
581798Speter 		|
582798Speter 	YINT ':' stat
58314752Sthien 		= $$.tr_entry = tree4(T_LABEL, lineof($2.i_entry),
58414752Sthien 				$1.tr_entry == TR_NIL ? TR_NIL :
58514752Sthien 					    (struct tnode *) *hash($1.cptr, 1), $3.tr_entry);
586798Speter 		|
587798Speter 	proc_id
58814752Sthien 		= $$.tr_entry = tree4(T_PCALL, lineof(yyline), $1.tr_entry,
58914752Sthien 						TR_NIL);
590798Speter 		|
591798Speter 	proc_id '(' wexpr_list ')'
59214752Sthien 		= $$.tr_entry = tree4(T_PCALL, lineof($2.i_entry), $1.tr_entry,
59314752Sthien 					fixlist($3.tr_entry));
594798Speter 		|
595798Speter 	YID error
596798Speter 		= goto NSerror;
597798Speter 		|
598798Speter 	assign
599798Speter 		|
600798Speter 	YBEGIN stat_list YEND
601798Speter 		= {
60214752Sthien 			$$.tr_entry = tree3(T_BLOCK, lineof($1.i_entry),
60314752Sthien 						fixlist($2.tr_entry));
60414752Sthien 			if ($3.i_entry < 0)
60514752Sthien 				brerror($1.i_entry, "begin");
606798Speter 		  }
607798Speter 		|
608798Speter 	YCASE expr YOF cstat_list YEND
609798Speter 		= {
61014752Sthien 			$$.tr_entry = tree4(T_CASE, lineof($1.i_entry),
61114752Sthien 					$2.tr_entry, fixlist($4.tr_entry));
61214752Sthien 			if ($5.i_entry < 0)
61314752Sthien 				brerror($1.i_entry, "case");
614798Speter 		  }
615798Speter 		|
616798Speter 	YWITH var_list YDO stat
61714752Sthien 		= $$.tr_entry = tree4(T_WITH, lineof($1.i_entry),
61814752Sthien 				fixlist($2.tr_entry), $4.tr_entry);
619798Speter 		|
620798Speter 	YWHILE expr YDO stat
62114752Sthien 		= $$.tr_entry = tree4(T_WHILE, lineof($1.i_entry), $2.tr_entry,
62214752Sthien 					$4.tr_entry);
623798Speter 		|
624798Speter 	YREPEAT stat_list YUNTIL expr
62514752Sthien 		= $$.tr_entry = tree4(T_REPEAT, lineof($3.i_entry),
62614752Sthien 				fixlist($2.tr_entry), $4.tr_entry);
627798Speter 		|
628798Speter 	YFOR assign YTO expr YDO stat
62914752Sthien 		= $$.tr_entry = tree5(T_FORU, lineof($1.i_entry), $2.tr_entry,
63014752Sthien 				$4.tr_entry, $6.tr_entry);
631798Speter 		|
632798Speter 	YFOR assign YDOWNTO expr YDO stat
63314752Sthien 		= $$.tr_entry = tree5(T_FORD, lineof($1.i_entry), $2.tr_entry,
63414752Sthien 				$4.tr_entry, $6.tr_entry);
635798Speter 		|
636798Speter 	YGOTO YINT
63714752Sthien 		= $$.tr_entry = tree3(T_GOTO, lineof($1.i_entry),
63814752Sthien 				(struct tnode *) *hash($2.cptr, 1));
639798Speter 		|
640798Speter 	YIF expr YTHEN stat
64114752Sthien 		= $$.tr_entry = tree5(T_IF, lineof($1.i_entry), $2.tr_entry,
64214752Sthien 				$4.tr_entry, TR_NIL);
643798Speter 		|
644798Speter 	YIF expr YTHEN stat YELSE stat
64514752Sthien 		= $$.tr_entry = tree5(T_IFEL, lineof($1.i_entry), $2.tr_entry,
64614752Sthien 					$4.tr_entry, $6.tr_entry);
647798Speter 		|
648798Speter 	error
649798Speter 		= {
650798Speter NSerror:
65114752Sthien 			$$.tr_entry = TR_NIL;
652798Speter 			yyPerror("Malformed statement", PSTAT);
653798Speter 		  }
654798Speter 		;
655798Speter assign:
656798Speter 	variable ':' '=' expr
65714752Sthien 		= $$.tr_entry = tree4(T_ASGN, lineof($2.i_entry), $1.tr_entry,
65814752Sthien 				    $4.tr_entry);
659798Speter 		;
660798Speter 
661798Speter /*
662798Speter  * EXPRESSION
663798Speter  */
664798Speter 
665798Speter expr:
666798Speter 	error
667798Speter 		= {
668798Speter NEerror:
66914752Sthien 			$$.tr_entry = TR_NIL;
670798Speter 			yyPerror("Missing/malformed expression", PEXPR);
671798Speter 		  }
672798Speter 		|
673798Speter 	expr relop expr			%prec '<'
67414752Sthien 		= $$.tr_entry = tree4($2.i_entry,
67514752Sthien 			$1.tr_entry->expr_node.const_tag == SAWCON ?
67614752Sthien 			$3.tr_entry->expr_node.const_tag :
67714752Sthien 			$1.tr_entry->expr_node.const_tag,
67814752Sthien 			$1.tr_entry, $3.tr_entry);
679798Speter 		|
680798Speter 	'+' expr			%prec UNARYSIGN
68114752Sthien 		= $$.tr_entry = tree3(T_PLUS, $2.tr_entry->expr_node.const_tag,
68214752Sthien 				$2.tr_entry);
683798Speter 		|
684798Speter 	'-' expr			%prec UNARYSIGN
68514752Sthien 		= $$.tr_entry = tree3(T_MINUS, $2.tr_entry->expr_node.const_tag,
68614752Sthien 				$2.tr_entry);
687798Speter 		|
688798Speter 	expr addop expr			%prec '+'
68914752Sthien 		= $$.tr_entry = tree4($2.i_entry,
69014752Sthien 			$1.tr_entry->expr_node.const_tag == SAWCON ?
69114752Sthien 			$3.tr_entry->expr_node.const_tag :
69214752Sthien 			$1.tr_entry->expr_node.const_tag, $1.tr_entry,
69314752Sthien 			$3.tr_entry);
694798Speter 		|
695798Speter 	expr divop expr			%prec '*'
69614752Sthien 		= $$.tr_entry = tree4($2.i_entry,
69714752Sthien 			$1.tr_entry->expr_node.const_tag == SAWCON ?
69814752Sthien 			$3.tr_entry->expr_node.const_tag :
69914752Sthien 			$1.tr_entry->expr_node.const_tag, $1.tr_entry,
70014752Sthien 			$3.tr_entry);
701798Speter 		|
702798Speter 	YNIL
70314752Sthien 		= $$.tr_entry = tree2(T_NIL, NOCON);
704798Speter 		|
705798Speter 	YSTRING
70614752Sthien 		= $$.tr_entry = tree3(T_STRNG, SAWCON, $1.tr_entry);
707798Speter 		|
708798Speter 	YINT
70914752Sthien 		= $$.tr_entry = tree3(T_INT, NOCON, $1.tr_entry);
710798Speter 		|
711798Speter 	YBINT
71214752Sthien 		= $$.tr_entry = tree3(T_BINT, NOCON, $1.tr_entry);
713798Speter 		|
714798Speter 	YNUMB
71514752Sthien 		= $$.tr_entry = tree3(T_FINT, NOCON, $1.tr_entry);
716798Speter 		|
717798Speter 	variable
718798Speter 		|
719798Speter 	YID error
720798Speter 		= goto NEerror;
721798Speter 		|
722798Speter 	func_id '(' wexpr_list ')'
72314752Sthien 		= $$.tr_entry = tree4(T_FCALL, NOCON, $1.tr_entry,
72414752Sthien 			fixlist($3.tr_entry));
725798Speter 		|
726798Speter 	'(' expr ')'
72714752Sthien 		= $$.tr_entry = $2.tr_entry;
728798Speter 		|
729798Speter 	negop expr			%prec YNOT
73014752Sthien 		= $$.tr_entry = tree3(T_NOT, NOCON, $2.tr_entry);
731798Speter 		|
732798Speter 	'[' element_list ']'
73314752Sthien 		= $$.tr_entry = tree3(T_CSET, SAWCON, fixlist($2.tr_entry));
734798Speter 		|
735798Speter 	'[' ']'
73614752Sthien 		= $$.tr_entry = tree3(T_CSET, SAWCON, TR_NIL);
737798Speter 		;
738798Speter 
739798Speter element_list:
740798Speter 	element
74114752Sthien 		= $$.tr_entry = newlist($1.tr_entry);
742798Speter 		|
743798Speter 	element_list ',' element
74414752Sthien 		= $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
745798Speter 		;
746798Speter element:
747798Speter 	expr
748798Speter 		|
749798Speter 	expr YDOTDOT expr
75014752Sthien 		= $$.tr_entry = tree3(T_RANG, $1.i_entry, $3.tr_entry);
751798Speter 		;
752798Speter 
753798Speter /*
754798Speter  * QUALIFIED VARIABLES
755798Speter  */
756798Speter 
757798Speter variable:
758798Speter 	YID
759798Speter 		= {
760804Speter 			@@ return (identis(var, VAR));
76114752Sthien 			$$.tr_entry = setupvar($1.cptr, TR_NIL);
762798Speter 		  }
763798Speter 		|
764798Speter 	qual_var
76514752Sthien 		= $1.tr_entry->var_node.qual =
76614752Sthien 					fixlist($1.tr_entry->var_node.qual);
767798Speter 		;
768798Speter qual_var:
769798Speter 	array_id '[' expr_list ']'
77014752Sthien 		= $$.tr_entry = setupvar($1.cptr, tree2(T_ARY,
77114752Sthien 				(int) fixlist($3.tr_entry)));
772798Speter 		|
773798Speter 	qual_var '[' expr_list ']'
77414752Sthien 		= $1.tr_entry->var_node.qual =
77514752Sthien 				addlist($1.tr_entry->var_node.qual,
77614752Sthien 				tree2(T_ARY, (int) fixlist($3.tr_entry)));
777798Speter 		|
778798Speter 	record_id '.' field_id
77914752Sthien 		= $$.tr_entry = setupvar($1.cptr, setupfield($3.tr_entry,
78014752Sthien 							TR_NIL));
781798Speter 		|
782798Speter 	qual_var '.' field_id
78314752Sthien 		= $1.tr_entry->var_node.qual =
78414752Sthien 		    addlist($1.tr_entry->var_node.qual,
78514752Sthien 		    setupfield($3.tr_entry, TR_NIL));
786798Speter 		|
787798Speter 	ptr_id '^'
78814752Sthien 		= $$.tr_entry = setupvar($1.cptr, tree1(T_PTR));
789798Speter 		|
790798Speter 	qual_var '^'
79114752Sthien 		= $1.tr_entry->var_node.qual =
79214752Sthien 			addlist($1.tr_entry->var_node.qual, tree1(T_PTR));
793798Speter 		;
794798Speter 
795798Speter /*
796798Speter  * Expression with write widths
797798Speter  */
798798Speter wexpr:
799798Speter 	expr
800798Speter 		|
801798Speter 	expr ':' expr
80214752Sthien 		= $$.tr_entry = tree4(T_WEXP, $1.i_entry, $3.tr_entry, TR_NIL);
803798Speter 		|
804798Speter 	expr ':' expr ':' expr
80514752Sthien 		= $$.tr_entry = tree4(T_WEXP, $1.i_entry, $3.tr_entry,
80614752Sthien 						$5.tr_entry);
807798Speter 		|
808798Speter 	expr octhex
80914752Sthien 		= $$.tr_entry = tree4(T_WEXP, $1.i_entry, TR_NIL, $2.tr_entry);
810798Speter 		|
811798Speter 	expr ':' expr octhex
81214752Sthien 		= $$.tr_entry = tree4(T_WEXP, $1.i_entry, $3.tr_entry,
81314752Sthien 					$4.tr_entry);
814798Speter 		;
815798Speter octhex:
816798Speter 	YOCT
81714752Sthien 		= $$.i_entry = OCT;
818798Speter 		|
819798Speter 	YHEX
82014752Sthien 		= $$.i_entry = HEX;
821798Speter 		;
822798Speter 
823798Speter expr_list:
824798Speter 	expr
82514752Sthien 		= $$.tr_entry = newlist($1.tr_entry);
826798Speter 		|
827798Speter 	expr_list ',' expr
82814752Sthien 		= $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
829798Speter 		;
830798Speter 
831798Speter wexpr_list:
832798Speter 	wexpr
83314752Sthien 		= $$.tr_entry = newlist($1.tr_entry);
834798Speter 		|
835798Speter 	wexpr_list ',' wexpr
83614752Sthien 		= $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
837798Speter 		;
838798Speter 
839798Speter /*
840798Speter  * OPERATORS
841798Speter  */
842798Speter 
843798Speter relop:
84414752Sthien 	'='	= $$.i_entry = T_EQ;
845798Speter 		|
84614752Sthien 	'<'	= $$.i_entry = T_LT;
847798Speter 		|
84814752Sthien 	'>'	= $$.i_entry = T_GT;
849798Speter 		|
85014752Sthien 	'<' '>'	= $$.i_entry = T_NE;
851798Speter 		|
85214752Sthien 	'<' '='	= $$.i_entry = T_LE;
853798Speter 		|
85414752Sthien 	'>' '='	= $$.i_entry = T_GE;
855798Speter 		|
85614752Sthien 	YIN	= $$.i_entry = T_IN;
857798Speter 		;
858798Speter addop:
85914752Sthien 	'+'	= $$.i_entry = T_ADD;
860798Speter 		|
86114752Sthien 	'-'	= $$.i_entry = T_SUB;
862798Speter 		|
86314752Sthien 	YOR	= $$.i_entry = T_OR;
864798Speter 		|
86514752Sthien 	'|'	= $$.i_entry = T_OR;
866798Speter 		;
867798Speter divop:
86814752Sthien 	'*'	= $$.i_entry = T_MULT;
869798Speter 		|
87014752Sthien 	'/'	= $$.i_entry = T_DIVD;
871798Speter 		|
87214752Sthien 	YDIV	= $$.i_entry = T_DIV;
873798Speter 		|
87414752Sthien 	YMOD	= $$.i_entry = T_MOD;
875798Speter 		|
87614752Sthien 	YAND	= $$.i_entry = T_AND;
877798Speter 		|
87814752Sthien 	'&'	= $$.i_entry = T_AND;
879798Speter 		;
880798Speter 
881798Speter negop:
882798Speter 	YNOT
883798Speter 		|
884798Speter 	'~'
885798Speter 		;
886798Speter 
887798Speter /*
888798Speter  * LISTS
889798Speter  */
890798Speter 
891798Speter var_list:
892798Speter 	variable
89314752Sthien 		= $$.tr_entry = newlist($1.tr_entry);
894798Speter 		|
895798Speter 	var_list ',' variable
89614752Sthien 		= $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
897798Speter 		;
898798Speter 
899798Speter id_list:
900798Speter 	YID
90114752Sthien 		= $$.tr_entry = newlist($1.tr_entry);
902798Speter 		|
903798Speter 	id_list ',' YID
90414752Sthien 		= $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
905798Speter 		;
906798Speter 
907798Speter /*
908798Speter  * Identifier productions with semantic restrictions
909798Speter  *
910804Speter  * For these productions, the characters @@ signify
911798Speter  * that the associated C statement is to provide
912798Speter  * the semantic restriction for this reduction.
913798Speter  * These lines are made into a procedure yyEactr, similar to
914798Speter  * yyactr, which determines whether the corresponding reduction
915798Speter  * is permitted, or whether an error is to be signaled.
916798Speter  * A zero return from yyEactr is considered an error.
917798Speter  * YyEactr is called with an argument "var" giving the string
918798Speter  * name of the variable in question, essentially $1, although
919798Speter  * $1 will not work because yyEactr is called from loccor in
920798Speter  * the recovery routines.
921798Speter  */
922798Speter 
923798Speter const_id:
924798Speter 	YID
925804Speter 		= @@ return (identis(var, CONST));
926798Speter 		;
927798Speter type_id:
928798Speter 	YID
929798Speter 		= {
930804Speter 			@@ return (identis(var, TYPE));
93114752Sthien 			$$.tr_entry = tree3(T_TYID, lineof(yyline), $1.tr_entry);
932798Speter 		  }
933798Speter 		;
934798Speter var_id:
935798Speter 	YID
936804Speter 		= @@ return (identis(var, VAR));
937798Speter 		;
938798Speter array_id:
939798Speter 	YID
940804Speter 		= @@ return (identis(var, ARRAY));
941798Speter 		;
942798Speter ptr_id:
943798Speter 	YID
944804Speter 		= @@ return (identis(var, PTRFILE));
945798Speter 		;
946798Speter record_id:
947798Speter 	YID
948804Speter 		= @@ return (identis(var, RECORD));
949798Speter 		;
950798Speter field_id:
951798Speter 	YID
952804Speter 		= @@ return (identis(var, FIELD));
953798Speter 		;
954798Speter proc_id:
955798Speter 	YID
956804Speter 		= @@ return (identis(var, PROC));
957798Speter 		;
958798Speter func_id:
959798Speter 	YID
960804Speter 		= @@ return (identis(var, FUNC));
961798Speter 		;
962