xref: /csrg-svn/usr.bin/pascal/src/pas.y (revision 804)
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
36*804Speter  *	   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
59798Speter 	YFOR		YFORWARD	YFUNCTION	YGOTO
60798Speter 	YID		YIF		YIN		YINT
61798Speter 	YLABEL		YMOD		YNOT		YNUMB
62798Speter 	YOF		YOR		YPACKED		YNIL
63798Speter 	YPROCEDURE	YPROG		YRECORD		YREPEAT
64798Speter 	YSET		YSTRING		YTHEN		YDOWNTO
65798Speter 	YTYPE		YUNTIL		YVAR		YWHILE
66798Speter 	YWITH		YBINT		YOCT		YHEX
67798Speter 	YASSERT		YCASELAB	YILLCH		YLAST
68798Speter 	YEXTERN
69798Speter 
70798Speter /*
71798Speter  * PRECEDENCE DECLARATIONS
72798Speter  *
73798Speter  * Highest precedence is the unary logical NOT.
74798Speter  * Next are the multiplying operators, signified by '*'.
75798Speter  * Lower still are the binary adding operators, signified by '+'.
76798Speter  * Finally, at lowest precedence and non-associative are the relationals.
77798Speter  */
78798Speter 
79798Speter %binary	'<'	'='	'>'	YIN
80798Speter %left	'+'	'-'	YOR	'|'
81798Speter %left	UNARYSIGN
82798Speter %left	'*'	'/'	YDIV	YMOD	YAND	'&'
83798Speter %left	YNOT
84798Speter 
85798Speter %{
86798Speter /*
87798Speter  * GLOBALS FOR ACTIONS
88798Speter  */
89798Speter 
90798Speter /* Copyright (c) 1979 Regents of the University of California */
91798Speter 
92*804Speter /* static	char sccsid[] = "@(#)pas.y 1.2 08/27/80"; */
93798Speter 
94798Speter /*
95798Speter  * The following line marks the end of the yacc
96798Speter  * Constant definitions which are removed from
97798Speter  * y.tab.c and placed in the file y.tab.h.
98798Speter  */
99798Speter ##
100798Speter /* Copyright (c) 1979 Regents of the University of California */
101798Speter 
102*804Speter static	char sccsid[] = "@(#)pas.y 1.2 08/27/80";
103798Speter 
104798Speter #include "whoami.h"
105798Speter #include "0.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:
123798Speter 	prog_hedr decls procs block '.'
124798Speter 		= funcend($1, $4, lineof($5));
125798Speter 		|
126798Speter 	decls procs
127798Speter 		= segend();
128798Speter 		;
129798Speter 
130798Speter 
131798Speter prog_hedr:
132798Speter 	YPROG YID '(' id_list ')' ';'
133798Speter 		= $$ = funcbody(funchdr(tree5(T_PROG, lineof($1), $2, fixlist($4), NIL)));
134798Speter 		|
135798Speter 	YPROG error
136798Speter 		= {
137798Speter 			yyPerror("Malformed program statement", PPROG);
138798Speter 			/*
139798Speter 			 * Should make a program statement
140798Speter 			 * with "input" and "output" here.
141798Speter 			 */
142798Speter 			$$ = funcbody(funchdr(tree5(T_PROG, lineof($1), NIL, NIL, NIL)));
143798Speter 		  }
144798Speter 		;
145798Speter block:
146798Speter 	YBEGIN stat_list YEND
147798Speter 		= {
148798Speter 			$$ = tree3(T_BSTL, lineof($1), fixlist($2));
149798Speter 			if ($3 < 0)
150798Speter 				brerror($1, "begin");
151798Speter 		  }
152798Speter 		;
153798Speter 
154798Speter 
155798Speter /*
156798Speter  * DECLARATION PART
157798Speter  */
158798Speter decls:
159798Speter 	decls decl
160798Speter 		= trfree();
161798Speter 		|
162798Speter 	decls error
163798Speter 		= {
164798Speter Derror:
165798Speter 			constend(), typeend(), varend(), trfree();
166798Speter 			yyPerror("Malformed declaration", PDECL);
167798Speter 		  }
168798Speter 		|
169798Speter 	/* lambda */
170798Speter 		= trfree();
171798Speter 		;
172798Speter 
173798Speter decl:
174798Speter 	labels
175798Speter 		|
176798Speter 	const_decl
177798Speter 		= constend();
178798Speter 		|
179798Speter 	type_decl
180798Speter 		= typeend();
181798Speter 		|
182798Speter 	var_decl
183798Speter 		= varend();
184798Speter 		;
185798Speter 
186798Speter /*
187798Speter  * LABEL PART
188798Speter  */
189798Speter 
190798Speter labels:
191798Speter 	YLABEL label_decl ';'
192798Speter 		= label(fixlist($2), lineof($1));
193798Speter 		;
194798Speter label_decl:
195798Speter 	YINT
196798Speter 		= $$ = newlist($1 == NIL ? NIL : *hash($1, 1));
197798Speter 		|
198798Speter 	label_decl ',' YINT
199798Speter 		= $$ = addlist($1, $3 == NIL ? NIL : *hash($3, 1));
200798Speter 		;
201798Speter 
202798Speter /*
203798Speter  * CONST PART
204798Speter  */
205798Speter 
206798Speter const_decl:
207798Speter 	YCONST YID '=' const ';'
208798Speter 		= constbeg($1, line2of($2)), const(lineof($3), $2, $4);
209798Speter 		|
210798Speter 	const_decl YID '=' const ';'
211798Speter 		= const(lineof($3), $2, $4);
212798Speter 		|
213798Speter 	YCONST error
214798Speter 		= {
215798Speter 			constbeg($1, line2of($1));
216798Speter Cerror:
217798Speter 			yyPerror("Malformed const declaration", PDECL);
218798Speter 		  }
219798Speter 		|
220798Speter 	const_decl error
221798Speter 		= goto Cerror;
222798Speter 		;
223798Speter 
224798Speter /*
225798Speter  * TYPE PART
226798Speter  */
227798Speter 
228798Speter type_decl:
229798Speter 	YTYPE YID '=' type ';'
230798Speter 		= typebeg($1, line2of($2)), type(lineof($3), $2, $4);
231798Speter 		|
232798Speter 	type_decl YID '=' type ';'
233798Speter 		= type(lineof($3), $2, $4);
234798Speter 		|
235798Speter 	YTYPE error
236798Speter 		= {
237798Speter 			typebeg($1, line2of($1));
238798Speter Terror:
239798Speter 			yyPerror("Malformed type declaration", PDECL);
240798Speter 		  }
241798Speter 		|
242798Speter 	type_decl error
243798Speter 		= goto Terror;
244798Speter 		;
245798Speter 
246798Speter /*
247798Speter  * VAR PART
248798Speter  */
249798Speter 
250798Speter var_decl:
251798Speter 	YVAR id_list ':' type ';'
252798Speter 		= varbeg($1, line2of($3)), var(lineof($3), fixlist($2), $4);
253798Speter 		|
254798Speter 	var_decl id_list ':' type ';'
255798Speter 		= var(lineof($3), fixlist($2), $4);
256798Speter 		|
257798Speter 	YVAR error
258798Speter 		= {
259798Speter 			varbeg($1, line2of($1));
260798Speter Verror:
261798Speter 			yyPerror("Malformed var declaration", PDECL);
262798Speter 		  }
263798Speter 		|
264798Speter 	var_decl error
265798Speter 		= goto Verror;
266798Speter 		;
267798Speter 
268798Speter /*
269798Speter  * PROCEDURE AND FUNCTION DECLARATION PART
270798Speter  */
271798Speter 
272798Speter procs:
273798Speter 	/* lambda */
274798Speter 		|
275798Speter 	procs proc
276798Speter 		= trfree();
277798Speter 		;
278798Speter proc:
279798Speter 	phead YFORWARD ';'
280798Speter 		= funcfwd($1);
281798Speter 		|
282798Speter 	phead YEXTERN ';'
283798Speter 		= funcext($1);
284798Speter 		|
285798Speter 	pheadres decls procs block ';'
286798Speter 		= funcend($1, $4, lineof($5));
287798Speter 		;
288798Speter pheadres:
289798Speter 	phead
290798Speter 		= funcbody($1);
291798Speter 		;
292798Speter phead:
293798Speter 	porf YID params ftype ';'
294798Speter 		= $$ = funchdr(tree5($1, lineof($5), $2, $3, $4));
295798Speter 		;
296798Speter porf:
297798Speter 	YPROCEDURE
298798Speter 		= $$ = T_PDEC;
299798Speter 		|
300798Speter 	YFUNCTION
301798Speter 		= $$ = T_FDEC;
302798Speter 		;
303798Speter params:
304798Speter 	'(' param_list ')'
305798Speter 		= $$ = fixlist($2);
306798Speter 		|
307798Speter 	/* lambda */
308798Speter 		= $$ = NIL;
309798Speter 		;
310798Speter 
311798Speter /*
312798Speter  * PARAMETERS
313798Speter  */
314798Speter 
315798Speter param:
316798Speter 	id_list ':' type
317798Speter 		= $$ = tree3(T_PVAL, fixlist($1), $3);
318798Speter 		|
319798Speter 	YVAR id_list ':' type
320798Speter 		= $$ = tree3(T_PVAR, fixlist($2), $4);
321798Speter 		|
322798Speter 	YFUNCTION id_list ':' type
323798Speter 		= $$ = tree3(T_PFUNC, fixlist($2), $4);
324798Speter 		|
325798Speter 	YPROCEDURE id_list
326798Speter 		= $$ = tree2(T_PPROC, fixlist($2));
327798Speter 		;
328798Speter ftype:
329798Speter 	':' type
330798Speter 		= $$ = $2;
331798Speter 		|
332798Speter 	/* lambda */
333798Speter 		= $$ = NIL;
334798Speter 		;
335798Speter param_list:
336798Speter 	param
337798Speter 		= $$ = newlist($1);
338798Speter 		|
339798Speter 	param_list ';' param
340798Speter 		= $$ = addlist($1, $3);
341798Speter 		;
342798Speter 
343798Speter /*
344798Speter  * CONSTANTS
345798Speter  */
346798Speter 
347798Speter const:
348798Speter 	YSTRING
349798Speter 		= $$ = tree2(T_CSTRNG, $1);
350798Speter 		|
351798Speter 	number
352798Speter 		|
353798Speter 	'+' number
354798Speter 		= $$ = tree2(T_PLUSC, $2);
355798Speter 		|
356798Speter 	'-' number
357798Speter 		= $$ = tree2(T_MINUSC, $2);
358798Speter 		;
359798Speter number:
360798Speter 	const_id
361798Speter 		= $$ = tree2(T_ID, $1);
362798Speter 		|
363798Speter 	YINT
364798Speter 		= $$ = tree2(T_CINT, $1);
365798Speter 		|
366798Speter 	YBINT
367798Speter 		= $$ = tree2(T_CBINT, $1);
368798Speter 		|
369798Speter 	YNUMB
370798Speter 		= $$ = tree2(T_CFINT, $1);
371798Speter 		;
372798Speter const_list:
373798Speter 	const
374798Speter 		= $$ = newlist($1);
375798Speter 		|
376798Speter 	const_list ',' const
377798Speter 		= $$ = addlist($1, $3);
378798Speter 		;
379798Speter 
380798Speter /*
381798Speter  * TYPES
382798Speter  */
383798Speter 
384798Speter type:
385798Speter 	simple_type
386798Speter 		|
387798Speter 	'^' YID
388798Speter 		= $$ = tree3(T_TYPTR, lineof($1), tree2(T_ID, $2));
389798Speter 		|
390798Speter 	struct_type
391798Speter 		|
392798Speter 	YPACKED struct_type
393798Speter 		= $$ = tree3(T_TYPACK, lineof($1), $2);
394798Speter 		;
395798Speter simple_type:
396798Speter 	type_id
397798Speter 		|
398798Speter 	'(' id_list ')'
399798Speter 		= $$ = tree3(T_TYSCAL, lineof($1), fixlist($2));
400798Speter 		|
401798Speter 	const YDOTDOT const
402798Speter 		= $$ = tree4(T_TYRANG, lineof($2), $1, $3);
403798Speter 		;
404798Speter struct_type:
405798Speter 	YARRAY '[' simple_type_list ']' YOF type
406798Speter 		= $$ = tree4(T_TYARY, lineof($1), fixlist($3), $6);
407798Speter 		|
408798Speter 	YFILE YOF type
409798Speter 		= $$ = tree3(T_TYFILE, lineof($1), $3);
410798Speter 		|
411798Speter 	YSET YOF simple_type
412798Speter 		= $$ = tree3(T_TYSET, lineof($1), $3);
413798Speter 		|
414798Speter 	YRECORD field_list YEND
415798Speter 		= {
416798Speter 			$$ = setuptyrec( lineof( $1 ) , $2 );
417798Speter 			if ($3 < 0)
418798Speter 				brerror($1, "record");
419798Speter 		  }
420798Speter 		;
421798Speter simple_type_list:
422798Speter 	simple_type
423798Speter 		= $$ = newlist($1);
424798Speter 		|
425798Speter 	simple_type_list ',' simple_type
426798Speter 		= $$ = addlist($1, $3);
427798Speter 		;
428798Speter 
429798Speter /*
430798Speter  * RECORD TYPE
431798Speter  */
432798Speter field_list:
433798Speter 	fixed_part variant_part
434798Speter 		= $$ = tree4(T_FLDLST, lineof(NIL), fixlist($1), $2);
435798Speter 		;
436798Speter fixed_part:
437798Speter 	field
438798Speter 		= $$ = newlist($1);
439798Speter 		|
440798Speter 	fixed_part ';' field
441798Speter 		= $$ = addlist($1, $3);
442798Speter 		|
443798Speter 	fixed_part error
444798Speter 		= yyPerror("Malformed record declaration", PDECL);
445798Speter 		;
446798Speter field:
447798Speter 	/* lambda */
448798Speter 		= $$ = NIL;
449798Speter 		|
450798Speter 	id_list ':' type
451798Speter 		= $$ = tree4(T_RFIELD, lineof($2), fixlist($1), $3);
452798Speter 		;
453798Speter 
454798Speter variant_part:
455798Speter 	/* lambda */
456798Speter 		= $$ = NIL;
457798Speter 		|
458798Speter 	YCASE type_id YOF variant_list
459798Speter 		= $$ = tree5(T_TYVARPT, lineof($1), NIL, $2, fixlist($4));
460798Speter 		|
461798Speter 	YCASE YID ':' type_id YOF variant_list
462798Speter 		= $$ = tree5(T_TYVARPT, lineof($1), $2, $4, fixlist($6));
463798Speter 		;
464798Speter variant_list:
465798Speter 	variant
466798Speter 		= $$ = newlist($1);
467798Speter 		|
468798Speter 	variant_list ';' variant
469798Speter 		= $$ = addlist($1, $3);
470798Speter 		|
471798Speter 	variant_list error
472798Speter 		= yyPerror("Malformed record declaration", PDECL);
473798Speter 		;
474798Speter variant:
475798Speter 	/* lambda */
476798Speter 		= $$ = NIL;
477798Speter 		|
478798Speter 	const_list ':' '(' field_list ')'
479798Speter 		= $$ = tree4(T_TYVARNT, lineof($2), fixlist($1), $4);
480798Speter 		|
481798Speter 	const_list ':' '(' ')'
482798Speter 		= $$ = tree4(T_TYVARNT, lineof($2), fixlist($1), NIL);
483798Speter 		;
484798Speter 
485798Speter /*
486798Speter  * STATEMENT LIST
487798Speter  */
488798Speter 
489798Speter stat_list:
490798Speter 	stat
491798Speter 		= $$ = newlist($1);
492798Speter 		|
493798Speter 	stat_lsth stat
494798Speter 		= {
495798Speter 			if ((p = $1) != NIL && (q = p[1])[0] == T_IFX) {
496798Speter 				q[0] = T_IFEL;
497798Speter 				q[4] = $2;
498798Speter 			} else
499798Speter 				$$ = addlist($1, $2);
500798Speter 		  }
501798Speter 		;
502798Speter 
503798Speter stat_lsth:
504798Speter 	stat_list ';'
505798Speter 		= if ((q = $1) != NIL && (p = q[1]) != NIL && p[0] == T_IF) {
506798Speter 			if (yychar < 0)
507798Speter 				yychar = yylex();
508798Speter 			if (yyshifts >= 2 && yychar == YELSE) {
509798Speter 				recovered();
510798Speter 				copy(&Y, &OY, sizeof Y);
511798Speter 				yerror("Deleted ';' before keyword else");
512798Speter 				yychar = yylex();
513798Speter 				p[0] = T_IFX;
514798Speter 			}
515798Speter 		  }
516798Speter 		;
517798Speter 
518798Speter /*
519798Speter  * CASE STATEMENT LIST
520798Speter  */
521798Speter 
522798Speter cstat_list:
523798Speter 	cstat
524798Speter 		= $$ = newlist($1);
525798Speter 		|
526798Speter 	cstat_list ';' cstat
527798Speter 		= $$ = addlist($1, $3);
528798Speter 		|
529798Speter 	error
530798Speter 		= {
531798Speter 			$$ = NIL;
532798Speter Kerror:
533798Speter 			yyPerror("Malformed statement in case", PSTAT);
534798Speter 		  }
535798Speter 		|
536798Speter 	cstat_list error
537798Speter 		= goto Kerror;
538798Speter 		;
539798Speter 
540798Speter cstat:
541798Speter 	const_list ':' stat
542798Speter 		= $$ = tree4(T_CSTAT, lineof($2), fixlist($1), $3);
543798Speter 		|
544798Speter 	YCASELAB stat
545798Speter 		= $$ = tree4(T_CSTAT, lineof($1), NIL, $2);
546798Speter 		|
547798Speter 	/* lambda */
548798Speter 		= $$ = NIL;
549798Speter 		;
550798Speter 
551798Speter /*
552798Speter  * STATEMENT
553798Speter  */
554798Speter 
555798Speter stat:
556798Speter 	/* lambda */
557798Speter 		= $$ = NIL;
558798Speter 		|
559798Speter 	YINT ':' stat
560798Speter 		= $$ = tree4(T_LABEL, lineof($2), $1 == NIL ? NIL : *hash($1, 1), $3);
561798Speter 		|
562798Speter 	proc_id
563798Speter 		= $$ = tree4(T_PCALL, lineof(yyline), $1, NIL);
564798Speter 		|
565798Speter 	proc_id '(' wexpr_list ')'
566798Speter 		= $$ = tree4(T_PCALL, lineof($2), $1, fixlist($3));
567798Speter 		|
568798Speter 	YID error
569798Speter 		= goto NSerror;
570798Speter 		|
571798Speter 	assign
572798Speter 		|
573798Speter 	YBEGIN stat_list YEND
574798Speter 		= {
575798Speter 			$$ = tree3(T_BLOCK, lineof($1), fixlist($2));
576798Speter 			if ($3 < 0)
577798Speter 				brerror($1, "begin");
578798Speter 		  }
579798Speter 		|
580798Speter 	YCASE expr YOF cstat_list YEND
581798Speter 		= {
582798Speter 			$$ = tree4(T_CASE, lineof($1), $2, fixlist($4));
583798Speter 			if ($5 < 0)
584798Speter 				brerror($1, "case");
585798Speter 		  }
586798Speter 		|
587798Speter 	YWITH var_list YDO stat
588798Speter 		= $$ = tree4(T_WITH, lineof($1), fixlist($2), $4);
589798Speter 		|
590798Speter 	YWHILE expr YDO stat
591798Speter 		= $$ = tree4(T_WHILE, lineof($1), $2, $4);
592798Speter 		|
593798Speter 	YREPEAT stat_list YUNTIL expr
594798Speter 		= $$ = tree4(T_REPEAT, lineof($3), fixlist($2), $4);
595798Speter 		|
596798Speter 	YFOR assign YTO expr YDO stat
597798Speter 		= $$ = tree5(T_FORU, lineof($1), $2, $4, $6);
598798Speter 		|
599798Speter 	YFOR assign YDOWNTO expr YDO stat
600798Speter 		= $$ = tree5(T_FORD, lineof($1), $2, $4, $6);
601798Speter 		|
602798Speter 	YGOTO YINT
603798Speter 		= $$ = tree3(T_GOTO, lineof($1), *hash($2, 1));
604798Speter 		|
605798Speter 	YIF expr YTHEN stat
606798Speter 		= $$ = tree5(T_IF, lineof($1), $2, $4, NIL);
607798Speter 		|
608798Speter 	YIF expr YTHEN stat YELSE stat
609798Speter 		= $$ = tree5(T_IFEL, lineof($1), $2, $4, $6);
610798Speter 		|
611798Speter 	YIF expr YTHEN stat YELSE
612798Speter 		= $$ = tree5(T_IFEL, lineof($1), $2, $4, NIL);
613798Speter 		|
614798Speter 	YASSERT '(' expr ')'
615798Speter 		= $$ = tree3(T_ASRT, lineof($1), $3);
616798Speter 		|
617798Speter 	error
618798Speter 		= {
619798Speter NSerror:
620798Speter 			$$ = NIL;
621798Speter Serror:
622798Speter 			yyPerror("Malformed statement", PSTAT);
623798Speter 		  }
624798Speter 		;
625798Speter assign:
626798Speter 	variable ':' '=' expr
627798Speter 		= $$ = tree4(T_ASGN, lineof($2), $1, $4);
628798Speter 		;
629798Speter 
630798Speter /*
631798Speter  * EXPRESSION
632798Speter  */
633798Speter 
634798Speter expr:
635798Speter 	error
636798Speter 		= {
637798Speter NEerror:
638798Speter 			$$ = NIL;
639798Speter Eerror:
640798Speter 			yyPerror("Missing/malformed expression", PEXPR);
641798Speter 		  }
642798Speter 		|
643798Speter 	expr relop expr			%prec '<'
644798Speter 		= $$ = tree4($2, $1[1] == SAWCON ? $3[1] : $1[1], $1, $3);
645798Speter 		|
646798Speter 	'+' expr			%prec UNARYSIGN
647798Speter 		= $$ = tree3(T_PLUS, $2[1], $2);
648798Speter 		|
649798Speter 	'-' expr			%prec UNARYSIGN
650798Speter 		= $$ = tree3(T_MINUS, $2[1], $2);
651798Speter 		|
652798Speter 	expr addop expr			%prec '+'
653798Speter 		= $$ = tree4($2, $1[1] == SAWCON ? $3[1] : $1[1], $1, $3);
654798Speter 		|
655798Speter 	expr divop expr			%prec '*'
656798Speter 		= $$ = tree4($2, $1[1] == SAWCON ? $3[1] : $1[1], $1, $3);
657798Speter 		|
658798Speter 	YNIL
659798Speter 		= $$ = tree2(T_NIL, NOCON);
660798Speter 		|
661798Speter 	YSTRING
662798Speter 		= $$ = tree3(T_STRNG, SAWCON, $1);
663798Speter 		|
664798Speter 	YINT
665798Speter 		= $$ = tree3(T_INT, NOCON, $1);
666798Speter 		|
667798Speter 	YBINT
668798Speter 		= $$ = tree3(T_BINT, NOCON, $1);
669798Speter 		|
670798Speter 	YNUMB
671798Speter 		= $$ = tree3(T_FINT, NOCON, $1);
672798Speter 		|
673798Speter 	variable
674798Speter 		|
675798Speter 	YID error
676798Speter 		= goto NEerror;
677798Speter 		|
678798Speter 	func_id '(' wexpr_list ')'
679798Speter 		= $$ = tree4(T_FCALL, NOCON, $1, fixlist($3));
680798Speter 		|
681798Speter 	'(' expr ')'
682798Speter 		= $$ = $2;
683798Speter 		|
684798Speter 	negop expr			%prec YNOT
685798Speter 		= $$ = tree3(T_NOT, NOCON, $2);
686798Speter 		|
687798Speter 	'[' element_list ']'
688798Speter 		= $$ = tree3(T_CSET, SAWCON, fixlist($2));
689798Speter 		|
690798Speter 	'[' ']'
691798Speter 		= $$ = tree3(T_CSET, SAWCON, NIL);
692798Speter 		;
693798Speter 
694798Speter element_list:
695798Speter 	element
696798Speter 		= $$ = newlist($1);
697798Speter 		|
698798Speter 	element_list ',' element
699798Speter 		= $$ = addlist($1, $3);
700798Speter 		;
701798Speter element:
702798Speter 	expr
703798Speter 		|
704798Speter 	expr YDOTDOT expr
705798Speter 		= $$ = tree3(T_RANG, $1, $3);
706798Speter 		;
707798Speter 
708798Speter /*
709798Speter  * QUALIFIED VARIABLES
710798Speter  */
711798Speter 
712798Speter variable:
713798Speter 	YID
714798Speter 		= {
715*804Speter 			@@ return (identis(var, VAR));
716798Speter 			$$ = setupvar($1, NIL);
717798Speter 		  }
718798Speter 		|
719798Speter 	qual_var
720798Speter 		= $1[3] = fixlist($1[3]);
721798Speter 		;
722798Speter qual_var:
723798Speter 	array_id '[' expr_list ']'
724798Speter 		= $$ = setupvar($1, tree2(T_ARY, fixlist($3)));
725798Speter 		|
726798Speter 	qual_var '[' expr_list ']'
727798Speter 		= $1[3] = addlist($1[3], tree2(T_ARY, fixlist($3)));
728798Speter 		|
729798Speter 	record_id '.' field_id
730798Speter 		= $$ = setupvar($1, setupfield($3, NIL));
731798Speter 		|
732798Speter 	qual_var '.' field_id
733798Speter 		= $1[3] = addlist($1[3], setupfield($3, NIL));
734798Speter 		|
735798Speter 	ptr_id '^'
736798Speter 		= $$ = setupvar($1, tree1(T_PTR));
737798Speter 		|
738798Speter 	qual_var '^'
739798Speter 		= $1[3] = addlist($1[3], tree1(T_PTR));
740798Speter 		;
741798Speter 
742798Speter /*
743798Speter  * Expression with write widths
744798Speter  */
745798Speter wexpr:
746798Speter 	expr
747798Speter 		|
748798Speter 	expr ':' expr
749798Speter 		= $$ = tree4(T_WEXP, $1, $3, NIL);
750798Speter 		|
751798Speter 	expr ':' expr ':' expr
752798Speter 		= $$ = tree4(T_WEXP, $1, $3, $5);
753798Speter 		|
754798Speter 	expr octhex
755798Speter 		= $$ = tree4(T_WEXP, $1, NIL, $2);
756798Speter 		|
757798Speter 	expr ':' expr octhex
758798Speter 		= $$ = tree4(T_WEXP, $1, $3, $4);
759798Speter 		;
760798Speter octhex:
761798Speter 	YOCT
762798Speter 		= $$ = OCT;
763798Speter 		|
764798Speter 	YHEX
765798Speter 		= $$ = HEX;
766798Speter 		;
767798Speter 
768798Speter expr_list:
769798Speter 	expr
770798Speter 		= $$ = newlist($1);
771798Speter 		|
772798Speter 	expr_list ',' expr
773798Speter 		= $$ = addlist($1, $3);
774798Speter 		;
775798Speter 
776798Speter wexpr_list:
777798Speter 	wexpr
778798Speter 		= $$ = newlist($1);
779798Speter 		|
780798Speter 	wexpr_list ',' wexpr
781798Speter 		= $$ = addlist($1, $3);
782798Speter 		;
783798Speter 
784798Speter /*
785798Speter  * OPERATORS
786798Speter  */
787798Speter 
788798Speter relop:
789798Speter 	'='	= $$ = T_EQ;
790798Speter 		|
791798Speter 	'<'	= $$ = T_LT;
792798Speter 		|
793798Speter 	'>'	= $$ = T_GT;
794798Speter 		|
795798Speter 	'<' '>'	= $$ = T_NE;
796798Speter 		|
797798Speter 	'<' '='	= $$ = T_LE;
798798Speter 		|
799798Speter 	'>' '='	= $$ = T_GE;
800798Speter 		|
801798Speter 	YIN	= $$ = T_IN;
802798Speter 		;
803798Speter addop:
804798Speter 	'+'	= $$ = T_ADD;
805798Speter 		|
806798Speter 	'-'	= $$ = T_SUB;
807798Speter 		|
808798Speter 	YOR	= $$ = T_OR;
809798Speter 		|
810798Speter 	'|'	= $$ = T_OR;
811798Speter 		;
812798Speter divop:
813798Speter 	'*'	= $$ = T_MULT;
814798Speter 		|
815798Speter 	'/'	= $$ = T_DIVD;
816798Speter 		|
817798Speter 	YDIV	= $$ = T_DIV;
818798Speter 		|
819798Speter 	YMOD	= $$ = T_MOD;
820798Speter 		|
821798Speter 	YAND	= $$ = T_AND;
822798Speter 		|
823798Speter 	'&'	= $$ = T_AND;
824798Speter 		;
825798Speter 
826798Speter negop:
827798Speter 	YNOT
828798Speter 		|
829798Speter 	'~'
830798Speter 		;
831798Speter 
832798Speter /*
833798Speter  * LISTS
834798Speter  */
835798Speter 
836798Speter var_list:
837798Speter 	variable
838798Speter 		= $$ = newlist($1);
839798Speter 		|
840798Speter 	var_list ',' variable
841798Speter 		= $$ = addlist($1, $3);
842798Speter 		;
843798Speter 
844798Speter id_list:
845798Speter 	YID
846798Speter 		= $$ = newlist($1);
847798Speter 		|
848798Speter 	id_list ',' YID
849798Speter 		= $$ = addlist($1, $3);
850798Speter 		;
851798Speter 
852798Speter /*
853798Speter  * Identifier productions with semantic restrictions
854798Speter  *
855*804Speter  * For these productions, the characters @@ signify
856798Speter  * that the associated C statement is to provide
857798Speter  * the semantic restriction for this reduction.
858798Speter  * These lines are made into a procedure yyEactr, similar to
859798Speter  * yyactr, which determines whether the corresponding reduction
860798Speter  * is permitted, or whether an error is to be signaled.
861798Speter  * A zero return from yyEactr is considered an error.
862798Speter  * YyEactr is called with an argument "var" giving the string
863798Speter  * name of the variable in question, essentially $1, although
864798Speter  * $1 will not work because yyEactr is called from loccor in
865798Speter  * the recovery routines.
866798Speter  */
867798Speter 
868798Speter const_id:
869798Speter 	YID
870*804Speter 		= @@ return (identis(var, CONST));
871798Speter 		;
872798Speter type_id:
873798Speter 	YID
874798Speter 		= {
875*804Speter 			@@ return (identis(var, TYPE));
876798Speter 			$$ = tree3(T_TYID, lineof(yyline), $1);
877798Speter 		  }
878798Speter 		;
879798Speter var_id:
880798Speter 	YID
881*804Speter 		= @@ return (identis(var, VAR));
882798Speter 		;
883798Speter array_id:
884798Speter 	YID
885*804Speter 		= @@ return (identis(var, ARRAY));
886798Speter 		;
887798Speter ptr_id:
888798Speter 	YID
889*804Speter 		= @@ return (identis(var, PTRFILE));
890798Speter 		;
891798Speter record_id:
892798Speter 	YID
893*804Speter 		= @@ return (identis(var, RECORD));
894798Speter 		;
895798Speter field_id:
896798Speter 	YID
897*804Speter 		= @@ return (identis(var, FIELD));
898798Speter 		;
899798Speter proc_id:
900798Speter 	YID
901*804Speter 		= @@ return (identis(var, PROC));
902798Speter 		;
903798Speter func_id:
904798Speter 	YID
905*804Speter 		= @@ return (identis(var, FUNC));
906798Speter 		;
907