xref: /csrg-svn/usr.bin/pascal/src/pas.y (revision 17695)
1798Speter /* Copyright (c) 1979 Regents of the University of California */
2798Speter 
3798Speter /*
4798Speter  * Yacc grammar for UNIX Pascal
5798Speter  *
6798Speter  * This grammar is processed by the commands in the shell script
7798Speter  * "gram" to yield parse tables and semantic routines in the file
8798Speter  * "y.tab.c" and a header defining the lexical tokens in "yy.h".
9798Speter  *
10798Speter  * In order for the syntactic error recovery possible with this
11798Speter  * grammar to work, the grammar must be processed by a yacc which
12798Speter  * has been modified to fully enumerate possibilities in states
13798Speter  * which involve the symbol "error".
14798Speter  * The parser used for Pascal also uses a different encoding of
15798Speter  * the test entries in the action table which speeds the parse.
16798Speter  * A version of yacc which will work for Pascal is included on
17798Speter  * the distribution table as "eyacc".
18798Speter  *
19798Speter  * The "gram" script also makes the following changes to the "y.tab.c"
20798Speter  * file:
21798Speter  *
22798Speter  *	1) Causes yyval to be declared int *.
23798Speter  *
24798Speter  *	2) Loads the variable yypv into a register as yyYpv so that
25798Speter  *	   the arguments $1, ... are available as yyYpv[1] etc.
26798Speter  *	   This produces much smaller code in the semantic actions.
27798Speter  *
28798Speter  *	3) Deletes the unused array yysterm.
29798Speter  *
30798Speter  *	4) Moves the declarations up to the flag line containing
31798Speter  *	   '##' to the file yy.h so that the routines which use
32798Speter  *	   these "magic numbers" don't have to all be compiled at
33798Speter  *	   the same time.
34798Speter  *
35798Speter  *	5) Creates the semantic restriction checking routine yyEactr
36804Speter  *	   by processing action lines containing `@@'.
37798Speter  *
38798Speter  * This compiler uses a different version of the yacc parser, a
39798Speter  * different yyerror which is called yerror, and requires more
40798Speter  * lookahead sets than normally provided by yacc.
41798Speter  *
42798Speter  * Source for the yacc used with this grammar is included on
43798Speter  * distribution tapes.
44798Speter  */
45798Speter 
46798Speter /*
47798Speter  * TERMINAL DECLARATIONS
48798Speter  *
49798Speter  * Some of the terminal declarations are out of the most natural
50798Speter  * alphabetic order because the error recovery
51798Speter  * will guess the first of equal cost non-terminals.
52798Speter  * This makes, e.g. YTO preferable to YDOWNTO.
53798Speter  */
54798Speter 
55798Speter %term
56798Speter 	YAND		YARRAY		YBEGIN		YCASE
57798Speter 	YCONST		YDIV		YDO		YDOTDOT
58798Speter 	YTO		YELSE		YEND		YFILE
5912932Speter 	YFOR		YFORWARD	YPROCEDURE	YGOTO
60798Speter 	YID		YIF		YIN		YINT
61798Speter 	YLABEL		YMOD		YNOT		YNUMB
62798Speter 	YOF		YOR		YPACKED		YNIL
6312932Speter 	YFUNCTION	YPROG		YRECORD		YREPEAT
64798Speter 	YSET		YSTRING		YTHEN		YDOWNTO
65798Speter 	YTYPE		YUNTIL		YVAR		YWHILE
66798Speter 	YWITH		YBINT		YOCT		YHEX
677927Smckusick 	YCASELAB	YILLCH		YEXTERN		YLAST
68798Speter 
69798Speter /*
70798Speter  * PRECEDENCE DECLARATIONS
71798Speter  *
72798Speter  * Highest precedence is the unary logical NOT.
73798Speter  * Next are the multiplying operators, signified by '*'.
74798Speter  * Lower still are the binary adding operators, signified by '+'.
75798Speter  * Finally, at lowest precedence and non-associative are the relationals.
76798Speter  */
77798Speter 
78798Speter %binary	'<'	'='	'>'	YIN
79798Speter %left	'+'	'-'	YOR	'|'
80798Speter %left	UNARYSIGN
81798Speter %left	'*'	'/'	YDIV	YMOD	YAND	'&'
82798Speter %left	YNOT
83798Speter 
84798Speter %{
85798Speter /*
86798Speter  * GLOBALS FOR ACTIONS
87798Speter  */
88798Speter 
89798Speter /* Copyright (c) 1979 Regents of the University of California */
90798Speter 
91*17695Smckusick /* static	char sccsid[] = "@(#)pas.y 2.2 01/10/85"; */
92798Speter 
93798Speter /*
94798Speter  * The following line marks the end of the yacc
95798Speter  * Constant definitions which are removed from
96798Speter  * y.tab.c and placed in the file y.tab.h.
97798Speter  */
98798Speter ##
99798Speter /* Copyright (c) 1979 Regents of the University of California */
100798Speter 
101*17695Smckusick static	char sccsid[] = "@(#)pas.y 2.2 01/10/85";
102798Speter 
103798Speter #include "whoami.h"
104798Speter #include "0.h"
10514752Sthien #include "tree_ty.h"		/* must be included for yy.h */
106798Speter #include "yy.h"
107798Speter #include "tree.h"
108798Speter 
109798Speter #ifdef PI
110798Speter #define	lineof(l)	l
111798Speter #define	line2of(l)	l
112798Speter #endif
113798Speter 
114798Speter %}
115798Speter 
116798Speter %%
117798Speter 
118798Speter /*
119798Speter  * PRODUCTIONS
120798Speter  */
121798Speter 
122798Speter goal:
123837Speter 	prog_hedr decls block '.'
12414752Sthien 		= funcend($1.nl_entry, $3.tr_entry, lineof($4.i_entry));
125798Speter 		|
126837Speter 	decls
127798Speter 		= segend();
128798Speter 		;
129798Speter 
130798Speter 
131798Speter prog_hedr:
132798Speter 	YPROG YID '(' id_list ')' ';'
13314752Sthien 		= $$.nl_entry = funcbody(funchdr(tree5(T_PROG, lineof($1.i_entry), $2.tr_entry, fixlist($4.tr_entry), TR_NIL)));
134798Speter 		|
1357953Speter 	YPROG YID ';'
13614752Sthien 		= $$.nl_entry = funcbody(funchdr(tree5(T_PROG, lineof($1.i_entry),  $2.tr_entry, TR_NIL, TR_NIL)));
1377953Speter 		|
138798Speter 	YPROG error
139798Speter 		= {
140798Speter 			yyPerror("Malformed program statement", PPROG);
141798Speter 			/*
142798Speter 			 * Should make a program statement
143798Speter 			 * with "input" and "output" here.
144798Speter 			 */
14514752Sthien 			$$.nl_entry = funcbody(funchdr(tree5(T_PROG, lineof($1.i_entry), TR_NIL, TR_NIL, TR_NIL)));
146798Speter 		  }
147798Speter 		;
148798Speter block:
149798Speter 	YBEGIN stat_list YEND
150798Speter 		= {
15114752Sthien 			$$.tr_entry = tree3(T_BSTL, lineof($1.i_entry), fixlist($2.tr_entry));
15214752Sthien 			if ($3.i_entry < 0)
15314752Sthien 				brerror($1.i_entry, "begin");
154798Speter 		  }
155798Speter 		;
156798Speter 
157798Speter 
158798Speter /*
159798Speter  * DECLARATION PART
160798Speter  */
161798Speter decls:
162798Speter 	decls decl
163798Speter 		= trfree();
164798Speter 		|
165798Speter 	decls error
166798Speter 		= {
167798Speter 			constend(), typeend(), varend(), trfree();
168798Speter 			yyPerror("Malformed declaration", PDECL);
169798Speter 		  }
170798Speter 		|
171798Speter 	/* lambda */
172798Speter 		= trfree();
173798Speter 		;
174798Speter 
175798Speter decl:
176798Speter 	labels
177798Speter 		|
178798Speter 	const_decl
179798Speter 		= constend();
180798Speter 		|
181798Speter 	type_decl
182798Speter 		= typeend();
183798Speter 		|
184798Speter 	var_decl
185798Speter 		= varend();
186837Speter 		|
187837Speter 	proc_decl
188798Speter 		;
189798Speter 
190798Speter /*
191798Speter  * LABEL PART
192798Speter  */
193798Speter 
194798Speter labels:
195798Speter 	YLABEL label_decl ';'
19614752Sthien 		= label(fixlist($2.tr_entry), lineof($1.i_entry));
197798Speter 		;
198798Speter label_decl:
199798Speter 	YINT
20014752Sthien 		= $$.tr_entry = newlist($1.i_entry == NIL ? TR_NIL :
20114752Sthien 					(struct tnode *) *hash($1.cptr, 1));
202798Speter 		|
203798Speter 	label_decl ',' YINT
20414752Sthien 		= $$.tr_entry = addlist($1.tr_entry, $3.i_entry == NIL ?
20514752Sthien 				TR_NIL : (struct tnode *) *hash($3.cptr, 1));
206798Speter 		;
207798Speter 
208798Speter /*
209798Speter  * CONST PART
210798Speter  */
211798Speter 
212798Speter const_decl:
213798Speter 	YCONST YID '=' const ';'
21414752Sthien 		= constbeg($1.i_entry), const(lineof($3.i_entry), $2.cptr,
21514752Sthien 						$4.tr_entry);
216798Speter 		|
217798Speter 	const_decl YID '=' const ';'
21814752Sthien 		= const(lineof($3.i_entry), $2.cptr, $4.tr_entry);
219798Speter 		|
220798Speter 	YCONST error
221798Speter 		= {
22214752Sthien 			constbeg($1.i_entry);
223798Speter Cerror:
224798Speter 			yyPerror("Malformed const declaration", PDECL);
225798Speter 		  }
226798Speter 		|
227798Speter 	const_decl error
228798Speter 		= goto Cerror;
229798Speter 		;
230798Speter 
231798Speter /*
232798Speter  * TYPE PART
233798Speter  */
234798Speter 
235798Speter type_decl:
236798Speter 	YTYPE YID '=' type ';'
23714752Sthien 		= typebeg($1.i_entry, line2of($2.i_entry)), type(lineof($3.i_entry), $2.cptr, $4.tr_entry);
238798Speter 		|
239798Speter 	type_decl YID '=' type ';'
24014752Sthien 		= type(lineof($3.i_entry), $2.cptr, $4.tr_entry);
241798Speter 		|
242798Speter 	YTYPE error
243798Speter 		= {
24414752Sthien 			typebeg($1.i_entry, line2of($1.i_entry));
245798Speter Terror:
246798Speter 			yyPerror("Malformed type declaration", PDECL);
247798Speter 		  }
248798Speter 		|
249798Speter 	type_decl error
250798Speter 		= goto Terror;
251798Speter 		;
252798Speter 
253798Speter /*
254798Speter  * VAR PART
255798Speter  */
256798Speter 
257798Speter var_decl:
258798Speter 	YVAR id_list ':' type ';'
25914752Sthien 		= varbeg($1.i_entry, line2of($3.i_entry)), var(lineof($3.i_entry), fixlist($2.tr_entry), $4.tr_entry);
260798Speter 		|
261798Speter 	var_decl id_list ':' type ';'
26214752Sthien 		= var(lineof($3.i_entry), fixlist($2.tr_entry), $4.tr_entry);
263798Speter 		|
264798Speter 	YVAR error
265798Speter 		= {
26614752Sthien 			varbeg($1.i_entry, line2of($1.i_entry));
267798Speter Verror:
268798Speter 			yyPerror("Malformed var declaration", PDECL);
269798Speter 		  }
270798Speter 		|
271798Speter 	var_decl error
272798Speter 		= goto Verror;
273798Speter 		;
274798Speter 
275798Speter /*
276798Speter  * PROCEDURE AND FUNCTION DECLARATION PART
277798Speter  */
278798Speter 
279837Speter proc_decl:
280798Speter 	phead YFORWARD ';'
28114752Sthien 		= funcfwd($1.nl_entry);
282798Speter 		|
283798Speter 	phead YEXTERN ';'
28414752Sthien 		= (void) funcext($1.nl_entry);
285798Speter 		|
286837Speter 	pheadres decls block ';'
28714752Sthien 		= funcend($1.nl_entry, $3.tr_entry, lineof($4.i_entry));
2888000Speter 		|
2898000Speter 	phead error
290798Speter 		;
291798Speter pheadres:
292798Speter 	phead
29314752Sthien 		= (void) funcbody($1.nl_entry);
294798Speter 		;
295798Speter phead:
296798Speter 	porf YID params ftype ';'
29714752Sthien 		= $$.nl_entry = funchdr(tree5($1.i_entry, lineof($5.i_entry),
29814752Sthien 				$2.tr_entry, $3.tr_entry, $4.tr_entry));
299798Speter 		;
300798Speter porf:
301798Speter 	YPROCEDURE
30214752Sthien 		= $$.i_entry = T_PDEC;
303798Speter 		|
304798Speter 	YFUNCTION
30514752Sthien 		= $$.i_entry = T_FDEC;
306798Speter 		;
307798Speter params:
308798Speter 	'(' param_list ')'
30914752Sthien 		= $$.tr_entry = fixlist($2.tr_entry);
310798Speter 		|
311798Speter 	/* lambda */
31214752Sthien 		= $$.tr_entry = TR_NIL;
313798Speter 		;
314798Speter 
315798Speter /*
316798Speter  * PARAMETERS
317798Speter  */
318798Speter 
319798Speter param:
320798Speter 	id_list ':' type
32114752Sthien 		= $$.tr_entry = tree3(T_PVAL, (int) fixlist($1.tr_entry), $3.tr_entry);
322798Speter 		|
323*17695Smckusick 	YVAR id_list ':' type
32414752Sthien 		= $$.tr_entry = tree3(T_PVAR, (int) fixlist($2.tr_entry), $4.tr_entry);
325798Speter 		|
3263298Smckusic 	YFUNCTION id_list params ftype
32714752Sthien 		= $$.tr_entry = tree5(T_PFUNC, (int) fixlist($2.tr_entry),
32814752Sthien 				$4.tr_entry, $3.tr_entry,
32914752Sthien 				(struct tnode *) lineof($1.i_entry));
330798Speter 		|
3313298Smckusic 	YPROCEDURE id_list params ftype
33214752Sthien 		= $$.tr_entry = tree5(T_PPROC, (int) fixlist($2.tr_entry),
33314752Sthien 				$4.tr_entry, $3.tr_entry,
33414752Sthien 				(struct tnode *) lineof($1.i_entry));
335798Speter 		;
336798Speter ftype:
337798Speter 	':' type
338798Speter 		= $$ = $2;
339798Speter 		|
340798Speter 	/* lambda */
34114752Sthien 		= $$.tr_entry = TR_NIL;
342798Speter 		;
343798Speter param_list:
344798Speter 	param
34514752Sthien 		= $$.tr_entry = newlist($1.tr_entry);
346798Speter 		|
347798Speter 	param_list ';' param
34814752Sthien 		= $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
349798Speter 		;
350798Speter 
351798Speter /*
352798Speter  * CONSTANTS
353798Speter  */
354798Speter 
355798Speter const:
356798Speter 	YSTRING
35714752Sthien 		= $$.tr_entry = tree2(T_CSTRNG, $1.i_entry);
358798Speter 		|
359798Speter 	number
360798Speter 		|
361798Speter 	'+' number
36214752Sthien 		= $$.tr_entry = tree2(T_PLUSC, $2.i_entry);
363798Speter 		|
364798Speter 	'-' number
36514752Sthien 		= $$.tr_entry = tree2(T_MINUSC, $2.i_entry);
366798Speter 		;
367798Speter number:
368798Speter 	const_id
36914752Sthien 		= $$.tr_entry = tree2(T_ID, $1.i_entry);
370798Speter 		|
371798Speter 	YINT
37214752Sthien 		= $$.tr_entry = tree2(T_CINT, $1.i_entry);
373798Speter 		|
374798Speter 	YBINT
37514752Sthien 		= $$.tr_entry = tree2(T_CBINT, $1.i_entry);
376798Speter 		|
377798Speter 	YNUMB
37814752Sthien 		= $$.tr_entry = tree2(T_CFINT, $1.i_entry);
379798Speter 		;
380798Speter const_list:
381798Speter 	const
38214752Sthien 		= $$.tr_entry = newlist($1.tr_entry);
383798Speter 		|
384798Speter 	const_list ',' const
38514752Sthien 		= $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
386798Speter 		;
387798Speter 
388798Speter /*
389798Speter  * TYPES
390798Speter  */
391798Speter 
392798Speter type:
393798Speter 	simple_type
394798Speter 		|
395798Speter 	'^' YID
39614752Sthien 		= $$.tr_entry = tree3(T_TYPTR, lineof($1.i_entry), tree2(T_ID,
39714752Sthien 								$2.i_entry));
398798Speter 		|
399798Speter 	struct_type
400798Speter 		|
401798Speter 	YPACKED struct_type
40214752Sthien 		= $$.tr_entry = tree3(T_TYPACK, lineof($1.i_entry), $2.tr_entry);
403798Speter 		;
404798Speter simple_type:
405798Speter 	type_id
406798Speter 		|
407798Speter 	'(' id_list ')'
40814752Sthien 		= $$.tr_entry = tree3(T_TYSCAL, lineof($1.i_entry), fixlist($2.tr_entry));
409798Speter 		|
410798Speter 	const YDOTDOT const
41114752Sthien 		= $$.tr_entry = tree4(T_TYRANG, lineof($2.i_entry), $1.tr_entry,
41214752Sthien 				$3.tr_entry);
413798Speter 		;
414798Speter struct_type:
415798Speter 	YARRAY '[' simple_type_list ']' YOF type
41614752Sthien 		= $$.tr_entry = tree4(T_TYARY, lineof($1.i_entry),
41714752Sthien 					fixlist($3.tr_entry), $6.tr_entry);
418798Speter 		|
419798Speter 	YFILE YOF type
42014752Sthien 		= $$.tr_entry = tree3(T_TYFILE, lineof($1.i_entry), $3.tr_entry);
421798Speter 		|
422798Speter 	YSET YOF simple_type
42314752Sthien 		= $$.tr_entry = tree3(T_TYSET, lineof($1.i_entry), $3.tr_entry);
424798Speter 		|
425798Speter 	YRECORD field_list YEND
426798Speter 		= {
42714752Sthien 			$$.tr_entry = setuptyrec( lineof( $1.i_entry ) , $2.tr_entry);
42814752Sthien 			if ($3.i_entry < 0)
42914752Sthien 				brerror($1.i_entry, "record");
430798Speter 		  }
431798Speter 		;
432798Speter simple_type_list:
433798Speter 	simple_type
43414752Sthien 		= $$.tr_entry = newlist($1.tr_entry);
435798Speter 		|
436798Speter 	simple_type_list ',' simple_type
43714752Sthien 		= $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
438798Speter 		;
439798Speter 
440798Speter /*
441798Speter  * RECORD TYPE
442798Speter  */
443798Speter field_list:
444798Speter 	fixed_part variant_part
44514752Sthien 		= $$.tr_entry = tree4(T_FLDLST, lineof(NIL),
44614752Sthien 				fixlist($1.tr_entry), $2.tr_entry);
447798Speter 		;
448798Speter fixed_part:
449798Speter 	field
45014752Sthien 		= $$.tr_entry = newlist($1.tr_entry);
451798Speter 		|
452798Speter 	fixed_part ';' field
45314752Sthien 		= $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
454798Speter 		|
455798Speter 	fixed_part error
456798Speter 		= yyPerror("Malformed record declaration", PDECL);
457798Speter 		;
458798Speter field:
459798Speter 	/* lambda */
46014752Sthien 		= $$.tr_entry = TR_NIL;
461798Speter 		|
462798Speter 	id_list ':' type
46314752Sthien 		= $$.tr_entry = tree4(T_RFIELD, lineof($2.i_entry),
46414752Sthien 				fixlist($1.tr_entry), $3.tr_entry);
465798Speter 		;
466798Speter 
467798Speter variant_part:
468798Speter 	/* lambda */
46914752Sthien 		= $$.tr_entry = TR_NIL;
470798Speter 		|
471798Speter 	YCASE type_id YOF variant_list
47214752Sthien 		= $$.tr_entry = tree5(T_TYVARPT, lineof($1.i_entry), TR_NIL,
47314752Sthien 				$2.tr_entry, fixlist($4.tr_entry));
474798Speter 		|
475798Speter 	YCASE YID ':' type_id YOF variant_list
47614752Sthien 		= $$.tr_entry = tree5(T_TYVARPT, lineof($1.i_entry),
47714752Sthien 				$2.tr_entry, $4.tr_entry,
47814752Sthien 					fixlist($6.tr_entry));
479798Speter 		;
480798Speter variant_list:
481798Speter 	variant
48214752Sthien 		= $$.tr_entry = newlist($1.tr_entry);
483798Speter 		|
484798Speter 	variant_list ';' variant
48514752Sthien 		= $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
486798Speter 		|
487798Speter 	variant_list error
488798Speter 		= yyPerror("Malformed record declaration", PDECL);
489798Speter 		;
490798Speter variant:
491798Speter 	/* lambda */
49214752Sthien 		= $$.tr_entry = TR_NIL;
493798Speter 		|
494798Speter 	const_list ':' '(' field_list ')'
49514752Sthien 		= $$.tr_entry = tree4(T_TYVARNT,lineof($2.i_entry), fixlist($1.tr_entry),
49614752Sthien 				$4.tr_entry);
497798Speter 		;
498798Speter 
499798Speter /*
500798Speter  * STATEMENT LIST
501798Speter  */
502798Speter 
503798Speter stat_list:
504798Speter 	stat
50514752Sthien 		= $$.tr_entry = newlist($1.tr_entry);
506798Speter 		|
507798Speter 	stat_lsth stat
508798Speter 		= {
50914752Sthien 			if ((p = $1.tr_entry) != TR_NIL && (q = p->list_node.list)->tag == T_IFX) {
51014752Sthien 				q->tag = T_IFEL;
51114752Sthien 				q->if_node.else_stmnt = $2.tr_entry;
512798Speter 			} else
51314752Sthien 				$$.tr_entry= addlist($1.tr_entry, $2.tr_entry);
514798Speter 		  }
515798Speter 		;
516798Speter 
517798Speter stat_lsth:
518798Speter 	stat_list ';'
51914752Sthien 		= if ((q = $1.tr_entry) != TR_NIL && (p = q->list_node.list) != TR_NIL && p->tag == T_IF) {
520798Speter 			if (yychar < 0)
521798Speter 				yychar = yylex();
522798Speter 			if (yyshifts >= 2 && yychar == YELSE) {
523798Speter 				recovered();
52414752Sthien 				copy((char *) (&Y), (char *) (&OY), sizeof Y);
525798Speter 				yerror("Deleted ';' before keyword else");
526798Speter 				yychar = yylex();
52714752Sthien 				p->tag = T_IFX;
528798Speter 			}
529798Speter 		  }
530798Speter 		;
531798Speter 
532798Speter /*
533798Speter  * CASE STATEMENT LIST
534798Speter  */
535798Speter 
536798Speter cstat_list:
537798Speter 	cstat
53814752Sthien 		= $$.tr_entry = newlist($1.tr_entry);
539798Speter 		|
540798Speter 	cstat_list ';' cstat
54114752Sthien 		= $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
542798Speter 		|
543798Speter 	error
544798Speter 		= {
54514752Sthien 			$$.tr_entry = TR_NIL;
546798Speter Kerror:
547798Speter 			yyPerror("Malformed statement in case", PSTAT);
548798Speter 		  }
549798Speter 		|
550798Speter 	cstat_list error
551798Speter 		= goto Kerror;
552798Speter 		;
553798Speter 
554798Speter cstat:
555798Speter 	const_list ':' stat
55614752Sthien 		= $$.tr_entry = tree4(T_CSTAT, lineof($2.i_entry),
55714752Sthien 				fixlist($1.tr_entry), $3.tr_entry);
558798Speter 		|
559798Speter 	YCASELAB stat
56014752Sthien 		= $$.tr_entry = tree4(T_CSTAT, lineof($1.i_entry), TR_NIL,
56114752Sthien 					$2.tr_entry);
562798Speter 		|
563798Speter 	/* lambda */
56414752Sthien 		= $$.tr_entry = TR_NIL;
565798Speter 		;
566798Speter 
567798Speter /*
568798Speter  * STATEMENT
569798Speter  */
570798Speter 
571798Speter stat:
572798Speter 	/* lambda */
57314752Sthien 		= $$.tr_entry = TR_NIL;
574798Speter 		|
575798Speter 	YINT ':' stat
57614752Sthien 		= $$.tr_entry = tree4(T_LABEL, lineof($2.i_entry),
57714752Sthien 				$1.tr_entry == TR_NIL ? TR_NIL :
57814752Sthien 					    (struct tnode *) *hash($1.cptr, 1), $3.tr_entry);
579798Speter 		|
580798Speter 	proc_id
58114752Sthien 		= $$.tr_entry = tree4(T_PCALL, lineof(yyline), $1.tr_entry,
58214752Sthien 						TR_NIL);
583798Speter 		|
584798Speter 	proc_id '(' wexpr_list ')'
58514752Sthien 		= $$.tr_entry = tree4(T_PCALL, lineof($2.i_entry), $1.tr_entry,
58614752Sthien 					fixlist($3.tr_entry));
587798Speter 		|
588798Speter 	YID error
589798Speter 		= goto NSerror;
590798Speter 		|
591798Speter 	assign
592798Speter 		|
593798Speter 	YBEGIN stat_list YEND
594798Speter 		= {
59514752Sthien 			$$.tr_entry = tree3(T_BLOCK, lineof($1.i_entry),
59614752Sthien 						fixlist($2.tr_entry));
59714752Sthien 			if ($3.i_entry < 0)
59814752Sthien 				brerror($1.i_entry, "begin");
599798Speter 		  }
600798Speter 		|
601798Speter 	YCASE expr YOF cstat_list YEND
602798Speter 		= {
60314752Sthien 			$$.tr_entry = tree4(T_CASE, lineof($1.i_entry),
60414752Sthien 					$2.tr_entry, fixlist($4.tr_entry));
60514752Sthien 			if ($5.i_entry < 0)
60614752Sthien 				brerror($1.i_entry, "case");
607798Speter 		  }
608798Speter 		|
609798Speter 	YWITH var_list YDO stat
61014752Sthien 		= $$.tr_entry = tree4(T_WITH, lineof($1.i_entry),
61114752Sthien 				fixlist($2.tr_entry), $4.tr_entry);
612798Speter 		|
613798Speter 	YWHILE expr YDO stat
61414752Sthien 		= $$.tr_entry = tree4(T_WHILE, lineof($1.i_entry), $2.tr_entry,
61514752Sthien 					$4.tr_entry);
616798Speter 		|
617798Speter 	YREPEAT stat_list YUNTIL expr
61814752Sthien 		= $$.tr_entry = tree4(T_REPEAT, lineof($3.i_entry),
61914752Sthien 				fixlist($2.tr_entry), $4.tr_entry);
620798Speter 		|
621798Speter 	YFOR assign YTO expr YDO stat
62214752Sthien 		= $$.tr_entry = tree5(T_FORU, lineof($1.i_entry), $2.tr_entry,
62314752Sthien 				$4.tr_entry, $6.tr_entry);
624798Speter 		|
625798Speter 	YFOR assign YDOWNTO expr YDO stat
62614752Sthien 		= $$.tr_entry = tree5(T_FORD, lineof($1.i_entry), $2.tr_entry,
62714752Sthien 				$4.tr_entry, $6.tr_entry);
628798Speter 		|
629798Speter 	YGOTO YINT
63014752Sthien 		= $$.tr_entry = tree3(T_GOTO, lineof($1.i_entry),
63114752Sthien 				(struct tnode *) *hash($2.cptr, 1));
632798Speter 		|
633798Speter 	YIF expr YTHEN stat
63414752Sthien 		= $$.tr_entry = tree5(T_IF, lineof($1.i_entry), $2.tr_entry,
63514752Sthien 				$4.tr_entry, TR_NIL);
636798Speter 		|
637798Speter 	YIF expr YTHEN stat YELSE stat
63814752Sthien 		= $$.tr_entry = tree5(T_IFEL, lineof($1.i_entry), $2.tr_entry,
63914752Sthien 					$4.tr_entry, $6.tr_entry);
640798Speter 		|
641798Speter 	error
642798Speter 		= {
643798Speter NSerror:
64414752Sthien 			$$.tr_entry = TR_NIL;
645798Speter 			yyPerror("Malformed statement", PSTAT);
646798Speter 		  }
647798Speter 		;
648798Speter assign:
649798Speter 	variable ':' '=' expr
65014752Sthien 		= $$.tr_entry = tree4(T_ASGN, lineof($2.i_entry), $1.tr_entry,
65114752Sthien 				    $4.tr_entry);
652798Speter 		;
653798Speter 
654798Speter /*
655798Speter  * EXPRESSION
656798Speter  */
657798Speter 
658798Speter expr:
659798Speter 	error
660798Speter 		= {
661798Speter NEerror:
66214752Sthien 			$$.tr_entry = TR_NIL;
663798Speter 			yyPerror("Missing/malformed expression", PEXPR);
664798Speter 		  }
665798Speter 		|
666798Speter 	expr relop expr			%prec '<'
66714752Sthien 		= $$.tr_entry = tree4($2.i_entry,
66814752Sthien 			$1.tr_entry->expr_node.const_tag == SAWCON ?
66914752Sthien 			$3.tr_entry->expr_node.const_tag :
67014752Sthien 			$1.tr_entry->expr_node.const_tag,
67114752Sthien 			$1.tr_entry, $3.tr_entry);
672798Speter 		|
673798Speter 	'+' expr			%prec UNARYSIGN
67414752Sthien 		= $$.tr_entry = tree3(T_PLUS, $2.tr_entry->expr_node.const_tag,
67514752Sthien 				$2.tr_entry);
676798Speter 		|
677798Speter 	'-' expr			%prec UNARYSIGN
67814752Sthien 		= $$.tr_entry = tree3(T_MINUS, $2.tr_entry->expr_node.const_tag,
67914752Sthien 				$2.tr_entry);
680798Speter 		|
681798Speter 	expr addop expr			%prec '+'
68214752Sthien 		= $$.tr_entry = tree4($2.i_entry,
68314752Sthien 			$1.tr_entry->expr_node.const_tag == SAWCON ?
68414752Sthien 			$3.tr_entry->expr_node.const_tag :
68514752Sthien 			$1.tr_entry->expr_node.const_tag, $1.tr_entry,
68614752Sthien 			$3.tr_entry);
687798Speter 		|
688798Speter 	expr divop 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 	YNIL
69614752Sthien 		= $$.tr_entry = tree2(T_NIL, NOCON);
697798Speter 		|
698798Speter 	YSTRING
69914752Sthien 		= $$.tr_entry = tree3(T_STRNG, SAWCON, $1.tr_entry);
700798Speter 		|
701798Speter 	YINT
70214752Sthien 		= $$.tr_entry = tree3(T_INT, NOCON, $1.tr_entry);
703798Speter 		|
704798Speter 	YBINT
70514752Sthien 		= $$.tr_entry = tree3(T_BINT, NOCON, $1.tr_entry);
706798Speter 		|
707798Speter 	YNUMB
70814752Sthien 		= $$.tr_entry = tree3(T_FINT, NOCON, $1.tr_entry);
709798Speter 		|
710798Speter 	variable
711798Speter 		|
712798Speter 	YID error
713798Speter 		= goto NEerror;
714798Speter 		|
715798Speter 	func_id '(' wexpr_list ')'
71614752Sthien 		= $$.tr_entry = tree4(T_FCALL, NOCON, $1.tr_entry,
71714752Sthien 			fixlist($3.tr_entry));
718798Speter 		|
719798Speter 	'(' expr ')'
72014752Sthien 		= $$.tr_entry = $2.tr_entry;
721798Speter 		|
722798Speter 	negop expr			%prec YNOT
72314752Sthien 		= $$.tr_entry = tree3(T_NOT, NOCON, $2.tr_entry);
724798Speter 		|
725798Speter 	'[' element_list ']'
72614752Sthien 		= $$.tr_entry = tree3(T_CSET, SAWCON, fixlist($2.tr_entry));
727798Speter 		|
728798Speter 	'[' ']'
72914752Sthien 		= $$.tr_entry = tree3(T_CSET, SAWCON, TR_NIL);
730798Speter 		;
731798Speter 
732798Speter element_list:
733798Speter 	element
73414752Sthien 		= $$.tr_entry = newlist($1.tr_entry);
735798Speter 		|
736798Speter 	element_list ',' element
73714752Sthien 		= $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
738798Speter 		;
739798Speter element:
740798Speter 	expr
741798Speter 		|
742798Speter 	expr YDOTDOT expr
74314752Sthien 		= $$.tr_entry = tree3(T_RANG, $1.i_entry, $3.tr_entry);
744798Speter 		;
745798Speter 
746798Speter /*
747798Speter  * QUALIFIED VARIABLES
748798Speter  */
749798Speter 
750798Speter variable:
751798Speter 	YID
752798Speter 		= {
753804Speter 			@@ return (identis(var, VAR));
75414752Sthien 			$$.tr_entry = setupvar($1.cptr, TR_NIL);
755798Speter 		  }
756798Speter 		|
757798Speter 	qual_var
75814752Sthien 		= $1.tr_entry->var_node.qual =
75914752Sthien 					fixlist($1.tr_entry->var_node.qual);
760798Speter 		;
761798Speter qual_var:
762798Speter 	array_id '[' expr_list ']'
76314752Sthien 		= $$.tr_entry = setupvar($1.cptr, tree2(T_ARY,
76414752Sthien 				(int) fixlist($3.tr_entry)));
765798Speter 		|
766798Speter 	qual_var '[' expr_list ']'
76714752Sthien 		= $1.tr_entry->var_node.qual =
76814752Sthien 				addlist($1.tr_entry->var_node.qual,
76914752Sthien 				tree2(T_ARY, (int) fixlist($3.tr_entry)));
770798Speter 		|
771798Speter 	record_id '.' field_id
77214752Sthien 		= $$.tr_entry = setupvar($1.cptr, setupfield($3.tr_entry,
77314752Sthien 							TR_NIL));
774798Speter 		|
775798Speter 	qual_var '.' field_id
77614752Sthien 		= $1.tr_entry->var_node.qual =
77714752Sthien 		    addlist($1.tr_entry->var_node.qual,
77814752Sthien 		    setupfield($3.tr_entry, TR_NIL));
779798Speter 		|
780798Speter 	ptr_id '^'
78114752Sthien 		= $$.tr_entry = setupvar($1.cptr, tree1(T_PTR));
782798Speter 		|
783798Speter 	qual_var '^'
78414752Sthien 		= $1.tr_entry->var_node.qual =
78514752Sthien 			addlist($1.tr_entry->var_node.qual, tree1(T_PTR));
786798Speter 		;
787798Speter 
788798Speter /*
789798Speter  * Expression with write widths
790798Speter  */
791798Speter wexpr:
792798Speter 	expr
793798Speter 		|
794798Speter 	expr ':' expr
79514752Sthien 		= $$.tr_entry = tree4(T_WEXP, $1.i_entry, $3.tr_entry, TR_NIL);
796798Speter 		|
797798Speter 	expr ':' expr ':' expr
79814752Sthien 		= $$.tr_entry = tree4(T_WEXP, $1.i_entry, $3.tr_entry,
79914752Sthien 						$5.tr_entry);
800798Speter 		|
801798Speter 	expr octhex
80214752Sthien 		= $$.tr_entry = tree4(T_WEXP, $1.i_entry, TR_NIL, $2.tr_entry);
803798Speter 		|
804798Speter 	expr ':' expr octhex
80514752Sthien 		= $$.tr_entry = tree4(T_WEXP, $1.i_entry, $3.tr_entry,
80614752Sthien 					$4.tr_entry);
807798Speter 		;
808798Speter octhex:
809798Speter 	YOCT
81014752Sthien 		= $$.i_entry = OCT;
811798Speter 		|
812798Speter 	YHEX
81314752Sthien 		= $$.i_entry = HEX;
814798Speter 		;
815798Speter 
816798Speter expr_list:
817798Speter 	expr
81814752Sthien 		= $$.tr_entry = newlist($1.tr_entry);
819798Speter 		|
820798Speter 	expr_list ',' expr
82114752Sthien 		= $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
822798Speter 		;
823798Speter 
824798Speter wexpr_list:
825798Speter 	wexpr
82614752Sthien 		= $$.tr_entry = newlist($1.tr_entry);
827798Speter 		|
828798Speter 	wexpr_list ',' wexpr
82914752Sthien 		= $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
830798Speter 		;
831798Speter 
832798Speter /*
833798Speter  * OPERATORS
834798Speter  */
835798Speter 
836798Speter relop:
83714752Sthien 	'='	= $$.i_entry = T_EQ;
838798Speter 		|
83914752Sthien 	'<'	= $$.i_entry = T_LT;
840798Speter 		|
84114752Sthien 	'>'	= $$.i_entry = T_GT;
842798Speter 		|
84314752Sthien 	'<' '>'	= $$.i_entry = T_NE;
844798Speter 		|
84514752Sthien 	'<' '='	= $$.i_entry = T_LE;
846798Speter 		|
84714752Sthien 	'>' '='	= $$.i_entry = T_GE;
848798Speter 		|
84914752Sthien 	YIN	= $$.i_entry = T_IN;
850798Speter 		;
851798Speter addop:
85214752Sthien 	'+'	= $$.i_entry = T_ADD;
853798Speter 		|
85414752Sthien 	'-'	= $$.i_entry = T_SUB;
855798Speter 		|
85614752Sthien 	YOR	= $$.i_entry = T_OR;
857798Speter 		|
85814752Sthien 	'|'	= $$.i_entry = T_OR;
859798Speter 		;
860798Speter divop:
86114752Sthien 	'*'	= $$.i_entry = T_MULT;
862798Speter 		|
86314752Sthien 	'/'	= $$.i_entry = T_DIVD;
864798Speter 		|
86514752Sthien 	YDIV	= $$.i_entry = T_DIV;
866798Speter 		|
86714752Sthien 	YMOD	= $$.i_entry = T_MOD;
868798Speter 		|
86914752Sthien 	YAND	= $$.i_entry = T_AND;
870798Speter 		|
87114752Sthien 	'&'	= $$.i_entry = T_AND;
872798Speter 		;
873798Speter 
874798Speter negop:
875798Speter 	YNOT
876798Speter 		|
877798Speter 	'~'
878798Speter 		;
879798Speter 
880798Speter /*
881798Speter  * LISTS
882798Speter  */
883798Speter 
884798Speter var_list:
885798Speter 	variable
88614752Sthien 		= $$.tr_entry = newlist($1.tr_entry);
887798Speter 		|
888798Speter 	var_list ',' variable
88914752Sthien 		= $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
890798Speter 		;
891798Speter 
892798Speter id_list:
893798Speter 	YID
89414752Sthien 		= $$.tr_entry = newlist($1.tr_entry);
895798Speter 		|
896798Speter 	id_list ',' YID
89714752Sthien 		= $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
898798Speter 		;
899798Speter 
900798Speter /*
901798Speter  * Identifier productions with semantic restrictions
902798Speter  *
903804Speter  * For these productions, the characters @@ signify
904798Speter  * that the associated C statement is to provide
905798Speter  * the semantic restriction for this reduction.
906798Speter  * These lines are made into a procedure yyEactr, similar to
907798Speter  * yyactr, which determines whether the corresponding reduction
908798Speter  * is permitted, or whether an error is to be signaled.
909798Speter  * A zero return from yyEactr is considered an error.
910798Speter  * YyEactr is called with an argument "var" giving the string
911798Speter  * name of the variable in question, essentially $1, although
912798Speter  * $1 will not work because yyEactr is called from loccor in
913798Speter  * the recovery routines.
914798Speter  */
915798Speter 
916798Speter const_id:
917798Speter 	YID
918804Speter 		= @@ return (identis(var, CONST));
919798Speter 		;
920798Speter type_id:
921798Speter 	YID
922798Speter 		= {
923804Speter 			@@ return (identis(var, TYPE));
92414752Sthien 			$$.tr_entry = tree3(T_TYID, lineof(yyline), $1.tr_entry);
925798Speter 		  }
926798Speter 		;
927798Speter var_id:
928798Speter 	YID
929804Speter 		= @@ return (identis(var, VAR));
930798Speter 		;
931798Speter array_id:
932798Speter 	YID
933804Speter 		= @@ return (identis(var, ARRAY));
934798Speter 		;
935798Speter ptr_id:
936798Speter 	YID
937804Speter 		= @@ return (identis(var, PTRFILE));
938798Speter 		;
939798Speter record_id:
940798Speter 	YID
941804Speter 		= @@ return (identis(var, RECORD));
942798Speter 		;
943798Speter field_id:
944798Speter 	YID
945804Speter 		= @@ return (identis(var, FIELD));
946798Speter 		;
947798Speter proc_id:
948798Speter 	YID
949804Speter 		= @@ return (identis(var, PROC));
950798Speter 		;
951798Speter func_id:
952798Speter 	YID
953804Speter 		= @@ return (identis(var, FUNC));
954798Speter 		;
955