xref: /csrg-svn/usr.bin/pascal/src/pas.y (revision 804)
1 /* Copyright (c) 1979 Regents of the University of California */
2 
3 /*
4  * Yacc grammar for UNIX Pascal
5  *
6  * This grammar is processed by the commands in the shell script
7  * "gram" to yield parse tables and semantic routines in the file
8  * "y.tab.c" and a header defining the lexical tokens in "yy.h".
9  *
10  * In order for the syntactic error recovery possible with this
11  * grammar to work, the grammar must be processed by a yacc which
12  * has been modified to fully enumerate possibilities in states
13  * which involve the symbol "error".
14  * The parser used for Pascal also uses a different encoding of
15  * the test entries in the action table which speeds the parse.
16  * A version of yacc which will work for Pascal is included on
17  * the distribution table as "eyacc".
18  *
19  * The "gram" script also makes the following changes to the "y.tab.c"
20  * file:
21  *
22  *	1) Causes yyval to be declared int *.
23  *
24  *	2) Loads the variable yypv into a register as yyYpv so that
25  *	   the arguments $1, ... are available as yyYpv[1] etc.
26  *	   This produces much smaller code in the semantic actions.
27  *
28  *	3) Deletes the unused array yysterm.
29  *
30  *	4) Moves the declarations up to the flag line containing
31  *	   '##' to the file yy.h so that the routines which use
32  *	   these "magic numbers" don't have to all be compiled at
33  *	   the same time.
34  *
35  *	5) Creates the semantic restriction checking routine yyEactr
36  *	   by processing action lines containing `@@'.
37  *
38  * This compiler uses a different version of the yacc parser, a
39  * different yyerror which is called yerror, and requires more
40  * lookahead sets than normally provided by yacc.
41  *
42  * Source for the yacc used with this grammar is included on
43  * distribution tapes.
44  */
45 
46 /*
47  * TERMINAL DECLARATIONS
48  *
49  * Some of the terminal declarations are out of the most natural
50  * alphabetic order because the error recovery
51  * will guess the first of equal cost non-terminals.
52  * This makes, e.g. YTO preferable to YDOWNTO.
53  */
54 
55 %term
56 	YAND		YARRAY		YBEGIN		YCASE
57 	YCONST		YDIV		YDO		YDOTDOT
58 	YTO		YELSE		YEND		YFILE
59 	YFOR		YFORWARD	YFUNCTION	YGOTO
60 	YID		YIF		YIN		YINT
61 	YLABEL		YMOD		YNOT		YNUMB
62 	YOF		YOR		YPACKED		YNIL
63 	YPROCEDURE	YPROG		YRECORD		YREPEAT
64 	YSET		YSTRING		YTHEN		YDOWNTO
65 	YTYPE		YUNTIL		YVAR		YWHILE
66 	YWITH		YBINT		YOCT		YHEX
67 	YASSERT		YCASELAB	YILLCH		YLAST
68 	YEXTERN
69 
70 /*
71  * PRECEDENCE DECLARATIONS
72  *
73  * Highest precedence is the unary logical NOT.
74  * Next are the multiplying operators, signified by '*'.
75  * Lower still are the binary adding operators, signified by '+'.
76  * Finally, at lowest precedence and non-associative are the relationals.
77  */
78 
79 %binary	'<'	'='	'>'	YIN
80 %left	'+'	'-'	YOR	'|'
81 %left	UNARYSIGN
82 %left	'*'	'/'	YDIV	YMOD	YAND	'&'
83 %left	YNOT
84 
85 %{
86 /*
87  * GLOBALS FOR ACTIONS
88  */
89 
90 /* Copyright (c) 1979 Regents of the University of California */
91 
92 /* static	char sccsid[] = "@(#)pas.y 1.2 08/27/80"; */
93 
94 /*
95  * The following line marks the end of the yacc
96  * Constant definitions which are removed from
97  * y.tab.c and placed in the file y.tab.h.
98  */
99 ##
100 /* Copyright (c) 1979 Regents of the University of California */
101 
102 static	char sccsid[] = "@(#)pas.y 1.2 08/27/80";
103 
104 #include "whoami.h"
105 #include "0.h"
106 #include "yy.h"
107 #include "tree.h"
108 
109 #ifdef PI
110 #define	lineof(l)	l
111 #define	line2of(l)	l
112 #endif
113 
114 %}
115 
116 %%
117 
118 /*
119  * PRODUCTIONS
120  */
121 
122 goal:
123 	prog_hedr decls procs block '.'
124 		= funcend($1, $4, lineof($5));
125 		|
126 	decls procs
127 		= segend();
128 		;
129 
130 
131 prog_hedr:
132 	YPROG YID '(' id_list ')' ';'
133 		= $$ = funcbody(funchdr(tree5(T_PROG, lineof($1), $2, fixlist($4), NIL)));
134 		|
135 	YPROG error
136 		= {
137 			yyPerror("Malformed program statement", PPROG);
138 			/*
139 			 * Should make a program statement
140 			 * with "input" and "output" here.
141 			 */
142 			$$ = funcbody(funchdr(tree5(T_PROG, lineof($1), NIL, NIL, NIL)));
143 		  }
144 		;
145 block:
146 	YBEGIN stat_list YEND
147 		= {
148 			$$ = tree3(T_BSTL, lineof($1), fixlist($2));
149 			if ($3 < 0)
150 				brerror($1, "begin");
151 		  }
152 		;
153 
154 
155 /*
156  * DECLARATION PART
157  */
158 decls:
159 	decls decl
160 		= trfree();
161 		|
162 	decls error
163 		= {
164 Derror:
165 			constend(), typeend(), varend(), trfree();
166 			yyPerror("Malformed declaration", PDECL);
167 		  }
168 		|
169 	/* lambda */
170 		= trfree();
171 		;
172 
173 decl:
174 	labels
175 		|
176 	const_decl
177 		= constend();
178 		|
179 	type_decl
180 		= typeend();
181 		|
182 	var_decl
183 		= varend();
184 		;
185 
186 /*
187  * LABEL PART
188  */
189 
190 labels:
191 	YLABEL label_decl ';'
192 		= label(fixlist($2), lineof($1));
193 		;
194 label_decl:
195 	YINT
196 		= $$ = newlist($1 == NIL ? NIL : *hash($1, 1));
197 		|
198 	label_decl ',' YINT
199 		= $$ = addlist($1, $3 == NIL ? NIL : *hash($3, 1));
200 		;
201 
202 /*
203  * CONST PART
204  */
205 
206 const_decl:
207 	YCONST YID '=' const ';'
208 		= constbeg($1, line2of($2)), const(lineof($3), $2, $4);
209 		|
210 	const_decl YID '=' const ';'
211 		= const(lineof($3), $2, $4);
212 		|
213 	YCONST error
214 		= {
215 			constbeg($1, line2of($1));
216 Cerror:
217 			yyPerror("Malformed const declaration", PDECL);
218 		  }
219 		|
220 	const_decl error
221 		= goto Cerror;
222 		;
223 
224 /*
225  * TYPE PART
226  */
227 
228 type_decl:
229 	YTYPE YID '=' type ';'
230 		= typebeg($1, line2of($2)), type(lineof($3), $2, $4);
231 		|
232 	type_decl YID '=' type ';'
233 		= type(lineof($3), $2, $4);
234 		|
235 	YTYPE error
236 		= {
237 			typebeg($1, line2of($1));
238 Terror:
239 			yyPerror("Malformed type declaration", PDECL);
240 		  }
241 		|
242 	type_decl error
243 		= goto Terror;
244 		;
245 
246 /*
247  * VAR PART
248  */
249 
250 var_decl:
251 	YVAR id_list ':' type ';'
252 		= varbeg($1, line2of($3)), var(lineof($3), fixlist($2), $4);
253 		|
254 	var_decl id_list ':' type ';'
255 		= var(lineof($3), fixlist($2), $4);
256 		|
257 	YVAR error
258 		= {
259 			varbeg($1, line2of($1));
260 Verror:
261 			yyPerror("Malformed var declaration", PDECL);
262 		  }
263 		|
264 	var_decl error
265 		= goto Verror;
266 		;
267 
268 /*
269  * PROCEDURE AND FUNCTION DECLARATION PART
270  */
271 
272 procs:
273 	/* lambda */
274 		|
275 	procs proc
276 		= trfree();
277 		;
278 proc:
279 	phead YFORWARD ';'
280 		= funcfwd($1);
281 		|
282 	phead YEXTERN ';'
283 		= funcext($1);
284 		|
285 	pheadres decls procs block ';'
286 		= funcend($1, $4, lineof($5));
287 		;
288 pheadres:
289 	phead
290 		= funcbody($1);
291 		;
292 phead:
293 	porf YID params ftype ';'
294 		= $$ = funchdr(tree5($1, lineof($5), $2, $3, $4));
295 		;
296 porf:
297 	YPROCEDURE
298 		= $$ = T_PDEC;
299 		|
300 	YFUNCTION
301 		= $$ = T_FDEC;
302 		;
303 params:
304 	'(' param_list ')'
305 		= $$ = fixlist($2);
306 		|
307 	/* lambda */
308 		= $$ = NIL;
309 		;
310 
311 /*
312  * PARAMETERS
313  */
314 
315 param:
316 	id_list ':' type
317 		= $$ = tree3(T_PVAL, fixlist($1), $3);
318 		|
319 	YVAR id_list ':' type
320 		= $$ = tree3(T_PVAR, fixlist($2), $4);
321 		|
322 	YFUNCTION id_list ':' type
323 		= $$ = tree3(T_PFUNC, fixlist($2), $4);
324 		|
325 	YPROCEDURE id_list
326 		= $$ = tree2(T_PPROC, fixlist($2));
327 		;
328 ftype:
329 	':' type
330 		= $$ = $2;
331 		|
332 	/* lambda */
333 		= $$ = NIL;
334 		;
335 param_list:
336 	param
337 		= $$ = newlist($1);
338 		|
339 	param_list ';' param
340 		= $$ = addlist($1, $3);
341 		;
342 
343 /*
344  * CONSTANTS
345  */
346 
347 const:
348 	YSTRING
349 		= $$ = tree2(T_CSTRNG, $1);
350 		|
351 	number
352 		|
353 	'+' number
354 		= $$ = tree2(T_PLUSC, $2);
355 		|
356 	'-' number
357 		= $$ = tree2(T_MINUSC, $2);
358 		;
359 number:
360 	const_id
361 		= $$ = tree2(T_ID, $1);
362 		|
363 	YINT
364 		= $$ = tree2(T_CINT, $1);
365 		|
366 	YBINT
367 		= $$ = tree2(T_CBINT, $1);
368 		|
369 	YNUMB
370 		= $$ = tree2(T_CFINT, $1);
371 		;
372 const_list:
373 	const
374 		= $$ = newlist($1);
375 		|
376 	const_list ',' const
377 		= $$ = addlist($1, $3);
378 		;
379 
380 /*
381  * TYPES
382  */
383 
384 type:
385 	simple_type
386 		|
387 	'^' YID
388 		= $$ = tree3(T_TYPTR, lineof($1), tree2(T_ID, $2));
389 		|
390 	struct_type
391 		|
392 	YPACKED struct_type
393 		= $$ = tree3(T_TYPACK, lineof($1), $2);
394 		;
395 simple_type:
396 	type_id
397 		|
398 	'(' id_list ')'
399 		= $$ = tree3(T_TYSCAL, lineof($1), fixlist($2));
400 		|
401 	const YDOTDOT const
402 		= $$ = tree4(T_TYRANG, lineof($2), $1, $3);
403 		;
404 struct_type:
405 	YARRAY '[' simple_type_list ']' YOF type
406 		= $$ = tree4(T_TYARY, lineof($1), fixlist($3), $6);
407 		|
408 	YFILE YOF type
409 		= $$ = tree3(T_TYFILE, lineof($1), $3);
410 		|
411 	YSET YOF simple_type
412 		= $$ = tree3(T_TYSET, lineof($1), $3);
413 		|
414 	YRECORD field_list YEND
415 		= {
416 			$$ = setuptyrec( lineof( $1 ) , $2 );
417 			if ($3 < 0)
418 				brerror($1, "record");
419 		  }
420 		;
421 simple_type_list:
422 	simple_type
423 		= $$ = newlist($1);
424 		|
425 	simple_type_list ',' simple_type
426 		= $$ = addlist($1, $3);
427 		;
428 
429 /*
430  * RECORD TYPE
431  */
432 field_list:
433 	fixed_part variant_part
434 		= $$ = tree4(T_FLDLST, lineof(NIL), fixlist($1), $2);
435 		;
436 fixed_part:
437 	field
438 		= $$ = newlist($1);
439 		|
440 	fixed_part ';' field
441 		= $$ = addlist($1, $3);
442 		|
443 	fixed_part error
444 		= yyPerror("Malformed record declaration", PDECL);
445 		;
446 field:
447 	/* lambda */
448 		= $$ = NIL;
449 		|
450 	id_list ':' type
451 		= $$ = tree4(T_RFIELD, lineof($2), fixlist($1), $3);
452 		;
453 
454 variant_part:
455 	/* lambda */
456 		= $$ = NIL;
457 		|
458 	YCASE type_id YOF variant_list
459 		= $$ = tree5(T_TYVARPT, lineof($1), NIL, $2, fixlist($4));
460 		|
461 	YCASE YID ':' type_id YOF variant_list
462 		= $$ = tree5(T_TYVARPT, lineof($1), $2, $4, fixlist($6));
463 		;
464 variant_list:
465 	variant
466 		= $$ = newlist($1);
467 		|
468 	variant_list ';' variant
469 		= $$ = addlist($1, $3);
470 		|
471 	variant_list error
472 		= yyPerror("Malformed record declaration", PDECL);
473 		;
474 variant:
475 	/* lambda */
476 		= $$ = NIL;
477 		|
478 	const_list ':' '(' field_list ')'
479 		= $$ = tree4(T_TYVARNT, lineof($2), fixlist($1), $4);
480 		|
481 	const_list ':' '(' ')'
482 		= $$ = tree4(T_TYVARNT, lineof($2), fixlist($1), NIL);
483 		;
484 
485 /*
486  * STATEMENT LIST
487  */
488 
489 stat_list:
490 	stat
491 		= $$ = newlist($1);
492 		|
493 	stat_lsth stat
494 		= {
495 			if ((p = $1) != NIL && (q = p[1])[0] == T_IFX) {
496 				q[0] = T_IFEL;
497 				q[4] = $2;
498 			} else
499 				$$ = addlist($1, $2);
500 		  }
501 		;
502 
503 stat_lsth:
504 	stat_list ';'
505 		= if ((q = $1) != NIL && (p = q[1]) != NIL && p[0] == T_IF) {
506 			if (yychar < 0)
507 				yychar = yylex();
508 			if (yyshifts >= 2 && yychar == YELSE) {
509 				recovered();
510 				copy(&Y, &OY, sizeof Y);
511 				yerror("Deleted ';' before keyword else");
512 				yychar = yylex();
513 				p[0] = T_IFX;
514 			}
515 		  }
516 		;
517 
518 /*
519  * CASE STATEMENT LIST
520  */
521 
522 cstat_list:
523 	cstat
524 		= $$ = newlist($1);
525 		|
526 	cstat_list ';' cstat
527 		= $$ = addlist($1, $3);
528 		|
529 	error
530 		= {
531 			$$ = NIL;
532 Kerror:
533 			yyPerror("Malformed statement in case", PSTAT);
534 		  }
535 		|
536 	cstat_list error
537 		= goto Kerror;
538 		;
539 
540 cstat:
541 	const_list ':' stat
542 		= $$ = tree4(T_CSTAT, lineof($2), fixlist($1), $3);
543 		|
544 	YCASELAB stat
545 		= $$ = tree4(T_CSTAT, lineof($1), NIL, $2);
546 		|
547 	/* lambda */
548 		= $$ = NIL;
549 		;
550 
551 /*
552  * STATEMENT
553  */
554 
555 stat:
556 	/* lambda */
557 		= $$ = NIL;
558 		|
559 	YINT ':' stat
560 		= $$ = tree4(T_LABEL, lineof($2), $1 == NIL ? NIL : *hash($1, 1), $3);
561 		|
562 	proc_id
563 		= $$ = tree4(T_PCALL, lineof(yyline), $1, NIL);
564 		|
565 	proc_id '(' wexpr_list ')'
566 		= $$ = tree4(T_PCALL, lineof($2), $1, fixlist($3));
567 		|
568 	YID error
569 		= goto NSerror;
570 		|
571 	assign
572 		|
573 	YBEGIN stat_list YEND
574 		= {
575 			$$ = tree3(T_BLOCK, lineof($1), fixlist($2));
576 			if ($3 < 0)
577 				brerror($1, "begin");
578 		  }
579 		|
580 	YCASE expr YOF cstat_list YEND
581 		= {
582 			$$ = tree4(T_CASE, lineof($1), $2, fixlist($4));
583 			if ($5 < 0)
584 				brerror($1, "case");
585 		  }
586 		|
587 	YWITH var_list YDO stat
588 		= $$ = tree4(T_WITH, lineof($1), fixlist($2), $4);
589 		|
590 	YWHILE expr YDO stat
591 		= $$ = tree4(T_WHILE, lineof($1), $2, $4);
592 		|
593 	YREPEAT stat_list YUNTIL expr
594 		= $$ = tree4(T_REPEAT, lineof($3), fixlist($2), $4);
595 		|
596 	YFOR assign YTO expr YDO stat
597 		= $$ = tree5(T_FORU, lineof($1), $2, $4, $6);
598 		|
599 	YFOR assign YDOWNTO expr YDO stat
600 		= $$ = tree5(T_FORD, lineof($1), $2, $4, $6);
601 		|
602 	YGOTO YINT
603 		= $$ = tree3(T_GOTO, lineof($1), *hash($2, 1));
604 		|
605 	YIF expr YTHEN stat
606 		= $$ = tree5(T_IF, lineof($1), $2, $4, NIL);
607 		|
608 	YIF expr YTHEN stat YELSE stat
609 		= $$ = tree5(T_IFEL, lineof($1), $2, $4, $6);
610 		|
611 	YIF expr YTHEN stat YELSE
612 		= $$ = tree5(T_IFEL, lineof($1), $2, $4, NIL);
613 		|
614 	YASSERT '(' expr ')'
615 		= $$ = tree3(T_ASRT, lineof($1), $3);
616 		|
617 	error
618 		= {
619 NSerror:
620 			$$ = NIL;
621 Serror:
622 			yyPerror("Malformed statement", PSTAT);
623 		  }
624 		;
625 assign:
626 	variable ':' '=' expr
627 		= $$ = tree4(T_ASGN, lineof($2), $1, $4);
628 		;
629 
630 /*
631  * EXPRESSION
632  */
633 
634 expr:
635 	error
636 		= {
637 NEerror:
638 			$$ = NIL;
639 Eerror:
640 			yyPerror("Missing/malformed expression", PEXPR);
641 		  }
642 		|
643 	expr relop expr			%prec '<'
644 		= $$ = tree4($2, $1[1] == SAWCON ? $3[1] : $1[1], $1, $3);
645 		|
646 	'+' expr			%prec UNARYSIGN
647 		= $$ = tree3(T_PLUS, $2[1], $2);
648 		|
649 	'-' expr			%prec UNARYSIGN
650 		= $$ = tree3(T_MINUS, $2[1], $2);
651 		|
652 	expr addop expr			%prec '+'
653 		= $$ = tree4($2, $1[1] == SAWCON ? $3[1] : $1[1], $1, $3);
654 		|
655 	expr divop expr			%prec '*'
656 		= $$ = tree4($2, $1[1] == SAWCON ? $3[1] : $1[1], $1, $3);
657 		|
658 	YNIL
659 		= $$ = tree2(T_NIL, NOCON);
660 		|
661 	YSTRING
662 		= $$ = tree3(T_STRNG, SAWCON, $1);
663 		|
664 	YINT
665 		= $$ = tree3(T_INT, NOCON, $1);
666 		|
667 	YBINT
668 		= $$ = tree3(T_BINT, NOCON, $1);
669 		|
670 	YNUMB
671 		= $$ = tree3(T_FINT, NOCON, $1);
672 		|
673 	variable
674 		|
675 	YID error
676 		= goto NEerror;
677 		|
678 	func_id '(' wexpr_list ')'
679 		= $$ = tree4(T_FCALL, NOCON, $1, fixlist($3));
680 		|
681 	'(' expr ')'
682 		= $$ = $2;
683 		|
684 	negop expr			%prec YNOT
685 		= $$ = tree3(T_NOT, NOCON, $2);
686 		|
687 	'[' element_list ']'
688 		= $$ = tree3(T_CSET, SAWCON, fixlist($2));
689 		|
690 	'[' ']'
691 		= $$ = tree3(T_CSET, SAWCON, NIL);
692 		;
693 
694 element_list:
695 	element
696 		= $$ = newlist($1);
697 		|
698 	element_list ',' element
699 		= $$ = addlist($1, $3);
700 		;
701 element:
702 	expr
703 		|
704 	expr YDOTDOT expr
705 		= $$ = tree3(T_RANG, $1, $3);
706 		;
707 
708 /*
709  * QUALIFIED VARIABLES
710  */
711 
712 variable:
713 	YID
714 		= {
715 			@@ return (identis(var, VAR));
716 			$$ = setupvar($1, NIL);
717 		  }
718 		|
719 	qual_var
720 		= $1[3] = fixlist($1[3]);
721 		;
722 qual_var:
723 	array_id '[' expr_list ']'
724 		= $$ = setupvar($1, tree2(T_ARY, fixlist($3)));
725 		|
726 	qual_var '[' expr_list ']'
727 		= $1[3] = addlist($1[3], tree2(T_ARY, fixlist($3)));
728 		|
729 	record_id '.' field_id
730 		= $$ = setupvar($1, setupfield($3, NIL));
731 		|
732 	qual_var '.' field_id
733 		= $1[3] = addlist($1[3], setupfield($3, NIL));
734 		|
735 	ptr_id '^'
736 		= $$ = setupvar($1, tree1(T_PTR));
737 		|
738 	qual_var '^'
739 		= $1[3] = addlist($1[3], tree1(T_PTR));
740 		;
741 
742 /*
743  * Expression with write widths
744  */
745 wexpr:
746 	expr
747 		|
748 	expr ':' expr
749 		= $$ = tree4(T_WEXP, $1, $3, NIL);
750 		|
751 	expr ':' expr ':' expr
752 		= $$ = tree4(T_WEXP, $1, $3, $5);
753 		|
754 	expr octhex
755 		= $$ = tree4(T_WEXP, $1, NIL, $2);
756 		|
757 	expr ':' expr octhex
758 		= $$ = tree4(T_WEXP, $1, $3, $4);
759 		;
760 octhex:
761 	YOCT
762 		= $$ = OCT;
763 		|
764 	YHEX
765 		= $$ = HEX;
766 		;
767 
768 expr_list:
769 	expr
770 		= $$ = newlist($1);
771 		|
772 	expr_list ',' expr
773 		= $$ = addlist($1, $3);
774 		;
775 
776 wexpr_list:
777 	wexpr
778 		= $$ = newlist($1);
779 		|
780 	wexpr_list ',' wexpr
781 		= $$ = addlist($1, $3);
782 		;
783 
784 /*
785  * OPERATORS
786  */
787 
788 relop:
789 	'='	= $$ = T_EQ;
790 		|
791 	'<'	= $$ = T_LT;
792 		|
793 	'>'	= $$ = T_GT;
794 		|
795 	'<' '>'	= $$ = T_NE;
796 		|
797 	'<' '='	= $$ = T_LE;
798 		|
799 	'>' '='	= $$ = T_GE;
800 		|
801 	YIN	= $$ = T_IN;
802 		;
803 addop:
804 	'+'	= $$ = T_ADD;
805 		|
806 	'-'	= $$ = T_SUB;
807 		|
808 	YOR	= $$ = T_OR;
809 		|
810 	'|'	= $$ = T_OR;
811 		;
812 divop:
813 	'*'	= $$ = T_MULT;
814 		|
815 	'/'	= $$ = T_DIVD;
816 		|
817 	YDIV	= $$ = T_DIV;
818 		|
819 	YMOD	= $$ = T_MOD;
820 		|
821 	YAND	= $$ = T_AND;
822 		|
823 	'&'	= $$ = T_AND;
824 		;
825 
826 negop:
827 	YNOT
828 		|
829 	'~'
830 		;
831 
832 /*
833  * LISTS
834  */
835 
836 var_list:
837 	variable
838 		= $$ = newlist($1);
839 		|
840 	var_list ',' variable
841 		= $$ = addlist($1, $3);
842 		;
843 
844 id_list:
845 	YID
846 		= $$ = newlist($1);
847 		|
848 	id_list ',' YID
849 		= $$ = addlist($1, $3);
850 		;
851 
852 /*
853  * Identifier productions with semantic restrictions
854  *
855  * For these productions, the characters @@ signify
856  * that the associated C statement is to provide
857  * the semantic restriction for this reduction.
858  * These lines are made into a procedure yyEactr, similar to
859  * yyactr, which determines whether the corresponding reduction
860  * is permitted, or whether an error is to be signaled.
861  * A zero return from yyEactr is considered an error.
862  * YyEactr is called with an argument "var" giving the string
863  * name of the variable in question, essentially $1, although
864  * $1 will not work because yyEactr is called from loccor in
865  * the recovery routines.
866  */
867 
868 const_id:
869 	YID
870 		= @@ return (identis(var, CONST));
871 		;
872 type_id:
873 	YID
874 		= {
875 			@@ return (identis(var, TYPE));
876 			$$ = tree3(T_TYID, lineof(yyline), $1);
877 		  }
878 		;
879 var_id:
880 	YID
881 		= @@ return (identis(var, VAR));
882 		;
883 array_id:
884 	YID
885 		= @@ return (identis(var, ARRAY));
886 		;
887 ptr_id:
888 	YID
889 		= @@ return (identis(var, PTRFILE));
890 		;
891 record_id:
892 	YID
893 		= @@ return (identis(var, RECORD));
894 		;
895 field_id:
896 	YID
897 		= @@ return (identis(var, FIELD));
898 		;
899 proc_id:
900 	YID
901 		= @@ return (identis(var, PROC));
902 		;
903 func_id:
904 	YID
905 		= @@ return (identis(var, FUNC));
906 		;
907