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