BSD 4_3_Tahoe release
[unix-history] / usr / src / ucb / pascal / src / pas.y
CommitLineData
252367af
DF
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.
23cbaf02 5 *
ca67e7b4 6 * @(#)pas.y 5.4 (Berkeley) 1/3/88
252367af
DF
7 */
8
481a3e15
PK
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
40aee854 42 * by processing action lines containing `@@'.
481a3e15
PK
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\f
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
cbd78a39 65 YFOR YFORWARD YPROCEDURE YGOTO
481a3e15
PK
66 YID YIF YIN YINT
67 YLABEL YMOD YNOT YNUMB
68 YOF YOR YPACKED YNIL
cbd78a39 69 YFUNCTION YPROG YRECORD YREPEAT
481a3e15
PK
70 YSET YSTRING YTHEN YDOWNTO
71 YTYPE YUNTIL YVAR YWHILE
72 YWITH YBINT YOCT YHEX
b57b948a 73 YCASELAB YILLCH YEXTERN YLAST
481a3e15
PK
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\f
90%{
91/*
92 * GLOBALS FOR ACTIONS
93 */
94
95/* Copyright (c) 1979 Regents of the University of California */
96
ca67e7b4 97/* static char sccsid[] = "@(#)pas.y 5.4 1/3/88"; */
481a3e15
PK
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
ca67e7b4 107static char sccsid[] = "@(#)pas.y 5.4 1/3/88";
481a3e15
PK
108
109#include "whoami.h"
110#include "0.h"
60ba0e41 111#include "tree_ty.h" /* must be included for yy.h */
481a3e15
PK
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\f
124/*
125 * PRODUCTIONS
126 */
127
128goal:
af97bcfa 129 prog_hedr decls block '.'
60ba0e41 130 = funcend($1.nl_entry, $3.tr_entry, lineof($4.i_entry));
481a3e15 131 |
af97bcfa 132 decls
481a3e15
PK
133 = segend();
134 ;
135
136
137prog_hedr:
138 YPROG YID '(' id_list ')' ';'
60ba0e41 139 = $$.nl_entry = funcbody(funchdr(tree5(T_PROG, lineof($1.i_entry), $2.tr_entry, fixlist($4.tr_entry), TR_NIL)));
481a3e15 140 |
f32541ef 141 YPROG YID ';'
60ba0e41 142 = $$.nl_entry = funcbody(funchdr(tree5(T_PROG, lineof($1.i_entry), $2.tr_entry, TR_NIL, TR_NIL)));
f32541ef 143 |
481a3e15
PK
144 YPROG error
145 = {
146 yyPerror("Malformed program statement", PPROG);
147 /*
148 * Should make a program statement
149 * with "input" and "output" here.
150 */
60ba0e41 151 $$.nl_entry = funcbody(funchdr(tree5(T_PROG, lineof($1.i_entry), TR_NIL, TR_NIL, TR_NIL)));
481a3e15
PK
152 }
153 ;
154block:
155 YBEGIN stat_list YEND
156 = {
60ba0e41
RT
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");
481a3e15
PK
160 }
161 ;
162
163\f
164/*
165 * DECLARATION PART
166 */
167decls:
168 decls decl
169 = trfree();
170 |
171 decls error
172 = {
481a3e15
PK
173 constend(), typeend(), varend(), trfree();
174 yyPerror("Malformed declaration", PDECL);
175 }
176 |
177 /* lambda */
178 = trfree();
179 ;
180
181decl:
182 labels
183 |
184 const_decl
185 = constend();
186 |
187 type_decl
188 = typeend();
189 |
190 var_decl
191 = varend();
af97bcfa
PK
192 |
193 proc_decl
481a3e15
PK
194 ;
195\f
196/*
197 * LABEL PART
198 */
199
200labels:
201 YLABEL label_decl ';'
60ba0e41 202 = label(fixlist($2.tr_entry), lineof($1.i_entry));
481a3e15
PK
203 ;
204label_decl:
205 YINT
60ba0e41
RT
206 = $$.tr_entry = newlist($1.i_entry == NIL ? TR_NIL :
207 (struct tnode *) *hash($1.cptr, 1));
481a3e15
PK
208 |
209 label_decl ',' YINT
60ba0e41
RT
210 = $$.tr_entry = addlist($1.tr_entry, $3.i_entry == NIL ?
211 TR_NIL : (struct tnode *) *hash($3.cptr, 1));
481a3e15
PK
212 ;
213\f
214/*
215 * CONST PART
216 */
217
218const_decl:
219 YCONST YID '=' const ';'
079ab0cb 220 = constbeg($1.i_entry, lineof($1.i_entry)),
a04e8692 221 constant(lineof($3.i_entry), $2.cptr, $4.tr_entry);
481a3e15
PK
222 |
223 const_decl YID '=' const ';'
a04e8692 224 = constant(lineof($3.i_entry), $2.cptr, $4.tr_entry);
481a3e15
PK
225 |
226 YCONST error
227 = {
60ba0e41 228 constbeg($1.i_entry);
481a3e15
PK
229Cerror:
230 yyPerror("Malformed const declaration", PDECL);
231 }
232 |
233 const_decl error
234 = goto Cerror;
235 ;
236\f
237/*
238 * TYPE PART
239 */
240
241type_decl:
242 YTYPE YID '=' type ';'
60ba0e41 243 = typebeg($1.i_entry, line2of($2.i_entry)), type(lineof($3.i_entry), $2.cptr, $4.tr_entry);
481a3e15
PK
244 |
245 type_decl YID '=' type ';'
60ba0e41 246 = type(lineof($3.i_entry), $2.cptr, $4.tr_entry);
481a3e15
PK
247 |
248 YTYPE error
249 = {
60ba0e41 250 typebeg($1.i_entry, line2of($1.i_entry));
481a3e15
PK
251Terror:
252 yyPerror("Malformed type declaration", PDECL);
253 }
254 |
255 type_decl error
256 = goto Terror;
257 ;
258\f
259/*
260 * VAR PART
261 */
262
263var_decl:
264 YVAR id_list ':' type ';'
60ba0e41 265 = varbeg($1.i_entry, line2of($3.i_entry)), var(lineof($3.i_entry), fixlist($2.tr_entry), $4.tr_entry);
481a3e15
PK
266 |
267 var_decl id_list ':' type ';'
60ba0e41 268 = var(lineof($3.i_entry), fixlist($2.tr_entry), $4.tr_entry);
481a3e15
PK
269 |
270 YVAR error
271 = {
60ba0e41 272 varbeg($1.i_entry, line2of($1.i_entry));
481a3e15
PK
273Verror:
274 yyPerror("Malformed var declaration", PDECL);
275 }
276 |
277 var_decl error
278 = goto Verror;
279 ;
280\f
281/*
282 * PROCEDURE AND FUNCTION DECLARATION PART
283 */
284
af97bcfa 285proc_decl:
481a3e15 286 phead YFORWARD ';'
60ba0e41 287 = funcfwd($1.nl_entry);
481a3e15
PK
288 |
289 phead YEXTERN ';'
60ba0e41 290 = (void) funcext($1.nl_entry);
481a3e15 291 |
af97bcfa 292 pheadres decls block ';'
60ba0e41 293 = funcend($1.nl_entry, $3.tr_entry, lineof($4.i_entry));
56d7b7d7
PK
294 |
295 phead error
481a3e15
PK
296 ;
297pheadres:
298 phead
60ba0e41 299 = (void) funcbody($1.nl_entry);
481a3e15
PK
300 ;
301phead:
302 porf YID params ftype ';'
60ba0e41
RT
303 = $$.nl_entry = funchdr(tree5($1.i_entry, lineof($5.i_entry),
304 $2.tr_entry, $3.tr_entry, $4.tr_entry));
481a3e15
PK
305 ;
306porf:
307 YPROCEDURE
60ba0e41 308 = $$.i_entry = T_PDEC;
481a3e15
PK
309 |
310 YFUNCTION
60ba0e41 311 = $$.i_entry = T_FDEC;
481a3e15
PK
312 ;
313params:
314 '(' param_list ')'
60ba0e41 315 = $$.tr_entry = fixlist($2.tr_entry);
481a3e15
PK
316 |
317 /* lambda */
60ba0e41 318 = $$.tr_entry = TR_NIL;
481a3e15
PK
319 ;
320\f
321/*
322 * PARAMETERS
323 */
324
325param:
326 id_list ':' type
60ba0e41 327 = $$.tr_entry = tree3(T_PVAL, (int) fixlist($1.tr_entry), $3.tr_entry);
481a3e15 328 |
aff96250 329 YVAR id_list ':' type
60ba0e41 330 = $$.tr_entry = tree3(T_PVAR, (int) fixlist($2.tr_entry), $4.tr_entry);
481a3e15 331 |
b34994ae 332 YFUNCTION id_list params ftype
60ba0e41
RT
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));
481a3e15 336 |
b34994ae 337 YPROCEDURE id_list params ftype
60ba0e41
RT
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));
481a3e15
PK
341 ;
342ftype:
343 ':' type
344 = $$ = $2;
345 |
346 /* lambda */
60ba0e41 347 = $$.tr_entry = TR_NIL;
481a3e15
PK
348 ;
349param_list:
350 param
60ba0e41 351 = $$.tr_entry = newlist($1.tr_entry);
481a3e15
PK
352 |
353 param_list ';' param
60ba0e41 354 = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
481a3e15
PK
355 ;
356\f
357/*
358 * CONSTANTS
359 */
360
361const:
362 YSTRING
60ba0e41 363 = $$.tr_entry = tree2(T_CSTRNG, $1.i_entry);
481a3e15
PK
364 |
365 number
366 |
367 '+' number
60ba0e41 368 = $$.tr_entry = tree2(T_PLUSC, $2.i_entry);
481a3e15
PK
369 |
370 '-' number
60ba0e41 371 = $$.tr_entry = tree2(T_MINUSC, $2.i_entry);
481a3e15
PK
372 ;
373number:
374 const_id
60ba0e41 375 = $$.tr_entry = tree2(T_ID, $1.i_entry);
481a3e15
PK
376 |
377 YINT
60ba0e41 378 = $$.tr_entry = tree2(T_CINT, $1.i_entry);
481a3e15
PK
379 |
380 YBINT
60ba0e41 381 = $$.tr_entry = tree2(T_CBINT, $1.i_entry);
481a3e15
PK
382 |
383 YNUMB
60ba0e41 384 = $$.tr_entry = tree2(T_CFINT, $1.i_entry);
481a3e15
PK
385 ;
386const_list:
387 const
60ba0e41 388 = $$.tr_entry = newlist($1.tr_entry);
481a3e15
PK
389 |
390 const_list ',' const
60ba0e41 391 = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
481a3e15
PK
392 ;
393\f
394/*
395 * TYPES
396 */
397
398type:
399 simple_type
400 |
401 '^' YID
60ba0e41
RT
402 = $$.tr_entry = tree3(T_TYPTR, lineof($1.i_entry), tree2(T_ID,
403 $2.i_entry));
481a3e15
PK
404 |
405 struct_type
406 |
407 YPACKED struct_type
60ba0e41 408 = $$.tr_entry = tree3(T_TYPACK, lineof($1.i_entry), $2.tr_entry);
481a3e15
PK
409 ;
410simple_type:
411 type_id
412 |
413 '(' id_list ')'
60ba0e41 414 = $$.tr_entry = tree3(T_TYSCAL, lineof($1.i_entry), fixlist($2.tr_entry));
481a3e15
PK
415 |
416 const YDOTDOT const
60ba0e41
RT
417 = $$.tr_entry = tree4(T_TYRANG, lineof($2.i_entry), $1.tr_entry,
418 $3.tr_entry);
481a3e15
PK
419 ;
420struct_type:
421 YARRAY '[' simple_type_list ']' YOF type
60ba0e41
RT
422 = $$.tr_entry = tree4(T_TYARY, lineof($1.i_entry),
423 fixlist($3.tr_entry), $6.tr_entry);
481a3e15
PK
424 |
425 YFILE YOF type
60ba0e41 426 = $$.tr_entry = tree3(T_TYFILE, lineof($1.i_entry), $3.tr_entry);
481a3e15
PK
427 |
428 YSET YOF simple_type
60ba0e41 429 = $$.tr_entry = tree3(T_TYSET, lineof($1.i_entry), $3.tr_entry);
481a3e15
PK
430 |
431 YRECORD field_list YEND
432 = {
60ba0e41
RT
433 $$.tr_entry = setuptyrec( lineof( $1.i_entry ) , $2.tr_entry);
434 if ($3.i_entry < 0)
435 brerror($1.i_entry, "record");
481a3e15
PK
436 }
437 ;
438simple_type_list:
439 simple_type
60ba0e41 440 = $$.tr_entry = newlist($1.tr_entry);
481a3e15
PK
441 |
442 simple_type_list ',' simple_type
60ba0e41 443 = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
481a3e15
PK
444 ;
445\f
446/*
447 * RECORD TYPE
448 */
449field_list:
450 fixed_part variant_part
60ba0e41
RT
451 = $$.tr_entry = tree4(T_FLDLST, lineof(NIL),
452 fixlist($1.tr_entry), $2.tr_entry);
481a3e15
PK
453 ;
454fixed_part:
455 field
60ba0e41 456 = $$.tr_entry = newlist($1.tr_entry);
481a3e15
PK
457 |
458 fixed_part ';' field
60ba0e41 459 = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
481a3e15
PK
460 |
461 fixed_part error
462 = yyPerror("Malformed record declaration", PDECL);
463 ;
464field:
465 /* lambda */
60ba0e41 466 = $$.tr_entry = TR_NIL;
481a3e15
PK
467 |
468 id_list ':' type
60ba0e41
RT
469 = $$.tr_entry = tree4(T_RFIELD, lineof($2.i_entry),
470 fixlist($1.tr_entry), $3.tr_entry);
481a3e15
PK
471 ;
472
473variant_part:
474 /* lambda */
60ba0e41 475 = $$.tr_entry = TR_NIL;
481a3e15
PK
476 |
477 YCASE type_id YOF variant_list
60ba0e41
RT
478 = $$.tr_entry = tree5(T_TYVARPT, lineof($1.i_entry), TR_NIL,
479 $2.tr_entry, fixlist($4.tr_entry));
481a3e15
PK
480 |
481 YCASE YID ':' type_id YOF variant_list
60ba0e41
RT
482 = $$.tr_entry = tree5(T_TYVARPT, lineof($1.i_entry),
483 $2.tr_entry, $4.tr_entry,
484 fixlist($6.tr_entry));
481a3e15
PK
485 ;
486variant_list:
487 variant
60ba0e41 488 = $$.tr_entry = newlist($1.tr_entry);
481a3e15
PK
489 |
490 variant_list ';' variant
60ba0e41 491 = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
481a3e15
PK
492 |
493 variant_list error
494 = yyPerror("Malformed record declaration", PDECL);
495 ;
496variant:
497 /* lambda */
60ba0e41 498 = $$.tr_entry = TR_NIL;
481a3e15
PK
499 |
500 const_list ':' '(' field_list ')'
60ba0e41
RT
501 = $$.tr_entry = tree4(T_TYVARNT,lineof($2.i_entry), fixlist($1.tr_entry),
502 $4.tr_entry);
481a3e15
PK
503 ;
504\f
505/*
506 * STATEMENT LIST
507 */
508
509stat_list:
510 stat
60ba0e41 511 = $$.tr_entry = newlist($1.tr_entry);
481a3e15
PK
512 |
513 stat_lsth stat
514 = {
60ba0e41
RT
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;
481a3e15 518 } else
60ba0e41 519 $$.tr_entry= addlist($1.tr_entry, $2.tr_entry);
481a3e15
PK
520 }
521 ;
522
523stat_lsth:
524 stat_list ';'
60ba0e41 525 = if ((q = $1.tr_entry) != TR_NIL && (p = q->list_node.list) != TR_NIL && p->tag == T_IF) {
481a3e15
PK
526 if (yychar < 0)
527 yychar = yylex();
528 if (yyshifts >= 2 && yychar == YELSE) {
529 recovered();
60ba0e41 530 copy((char *) (&Y), (char *) (&OY), sizeof Y);
481a3e15
PK
531 yerror("Deleted ';' before keyword else");
532 yychar = yylex();
60ba0e41 533 p->tag = T_IFX;
481a3e15
PK
534 }
535 }
536 ;
537\f
538/*
539 * CASE STATEMENT LIST
540 */
541
542cstat_list:
543 cstat
60ba0e41 544 = $$.tr_entry = newlist($1.tr_entry);
481a3e15
PK
545 |
546 cstat_list ';' cstat
60ba0e41 547 = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
481a3e15
PK
548 |
549 error
550 = {
60ba0e41 551 $$.tr_entry = TR_NIL;
481a3e15
PK
552Kerror:
553 yyPerror("Malformed statement in case", PSTAT);
554 }
555 |
556 cstat_list error
557 = goto Kerror;
558 ;
559
560cstat:
561 const_list ':' stat
60ba0e41
RT
562 = $$.tr_entry = tree4(T_CSTAT, lineof($2.i_entry),
563 fixlist($1.tr_entry), $3.tr_entry);
481a3e15
PK
564 |
565 YCASELAB stat
60ba0e41
RT
566 = $$.tr_entry = tree4(T_CSTAT, lineof($1.i_entry), TR_NIL,
567 $2.tr_entry);
481a3e15
PK
568 |
569 /* lambda */
60ba0e41 570 = $$.tr_entry = TR_NIL;
481a3e15
PK
571 ;
572\f
573/*
574 * STATEMENT
575 */
576
577stat:
578 /* lambda */
60ba0e41 579 = $$.tr_entry = TR_NIL;
481a3e15
PK
580 |
581 YINT ':' stat
60ba0e41
RT
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);
481a3e15
PK
585 |
586 proc_id
60ba0e41
RT
587 = $$.tr_entry = tree4(T_PCALL, lineof(yyline), $1.tr_entry,
588 TR_NIL);
481a3e15
PK
589 |
590 proc_id '(' wexpr_list ')'
60ba0e41
RT
591 = $$.tr_entry = tree4(T_PCALL, lineof($2.i_entry), $1.tr_entry,
592 fixlist($3.tr_entry));
481a3e15
PK
593 |
594 YID error
595 = goto NSerror;
596 |
597 assign
598 |
599 YBEGIN stat_list YEND
600 = {
60ba0e41
RT
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");
481a3e15
PK
605 }
606 |
607 YCASE expr YOF cstat_list YEND
608 = {
60ba0e41
RT
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");
481a3e15
PK
613 }
614 |
615 YWITH var_list YDO stat
60ba0e41
RT
616 = $$.tr_entry = tree4(T_WITH, lineof($1.i_entry),
617 fixlist($2.tr_entry), $4.tr_entry);
481a3e15
PK
618 |
619 YWHILE expr YDO stat
60ba0e41
RT
620 = $$.tr_entry = tree4(T_WHILE, lineof($1.i_entry), $2.tr_entry,
621 $4.tr_entry);
481a3e15
PK
622 |
623 YREPEAT stat_list YUNTIL expr
60ba0e41
RT
624 = $$.tr_entry = tree4(T_REPEAT, lineof($3.i_entry),
625 fixlist($2.tr_entry), $4.tr_entry);
481a3e15
PK
626 |
627 YFOR assign YTO expr YDO stat
60ba0e41
RT
628 = $$.tr_entry = tree5(T_FORU, lineof($1.i_entry), $2.tr_entry,
629 $4.tr_entry, $6.tr_entry);
481a3e15
PK
630 |
631 YFOR assign YDOWNTO expr YDO stat
60ba0e41
RT
632 = $$.tr_entry = tree5(T_FORD, lineof($1.i_entry), $2.tr_entry,
633 $4.tr_entry, $6.tr_entry);
481a3e15
PK
634 |
635 YGOTO YINT
60ba0e41
RT
636 = $$.tr_entry = tree3(T_GOTO, lineof($1.i_entry),
637 (struct tnode *) *hash($2.cptr, 1));
481a3e15
PK
638 |
639 YIF expr YTHEN stat
60ba0e41
RT
640 = $$.tr_entry = tree5(T_IF, lineof($1.i_entry), $2.tr_entry,
641 $4.tr_entry, TR_NIL);
481a3e15
PK
642 |
643 YIF expr YTHEN stat YELSE stat
60ba0e41
RT
644 = $$.tr_entry = tree5(T_IFEL, lineof($1.i_entry), $2.tr_entry,
645 $4.tr_entry, $6.tr_entry);
481a3e15 646 |
481a3e15
PK
647 error
648 = {
649NSerror:
60ba0e41 650 $$.tr_entry = TR_NIL;
481a3e15
PK
651 yyPerror("Malformed statement", PSTAT);
652 }
653 ;
654assign:
655 variable ':' '=' expr
60ba0e41
RT
656 = $$.tr_entry = tree4(T_ASGN, lineof($2.i_entry), $1.tr_entry,
657 $4.tr_entry);
481a3e15
PK
658 ;
659\f
660/*
661 * EXPRESSION
662 */
663
664expr:
665 error
666 = {
667NEerror:
60ba0e41 668 $$.tr_entry = TR_NIL;
481a3e15
PK
669 yyPerror("Missing/malformed expression", PEXPR);
670 }
671 |
672 expr relop expr %prec '<'
60ba0e41
RT
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);
481a3e15
PK
678 |
679 '+' expr %prec UNARYSIGN
60ba0e41
RT
680 = $$.tr_entry = tree3(T_PLUS, $2.tr_entry->expr_node.const_tag,
681 $2.tr_entry);
481a3e15
PK
682 |
683 '-' expr %prec UNARYSIGN
60ba0e41
RT
684 = $$.tr_entry = tree3(T_MINUS, $2.tr_entry->expr_node.const_tag,
685 $2.tr_entry);
481a3e15
PK
686 |
687 expr addop expr %prec '+'
60ba0e41
RT
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);
481a3e15
PK
693 |
694 expr divop expr %prec '*'
60ba0e41
RT
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);
481a3e15
PK
700 |
701 YNIL
60ba0e41 702 = $$.tr_entry = tree2(T_NIL, NOCON);
481a3e15
PK
703 |
704 YSTRING
60ba0e41 705 = $$.tr_entry = tree3(T_STRNG, SAWCON, $1.tr_entry);
481a3e15
PK
706 |
707 YINT
60ba0e41 708 = $$.tr_entry = tree3(T_INT, NOCON, $1.tr_entry);
481a3e15
PK
709 |
710 YBINT
60ba0e41 711 = $$.tr_entry = tree3(T_BINT, NOCON, $1.tr_entry);
481a3e15
PK
712 |
713 YNUMB
60ba0e41 714 = $$.tr_entry = tree3(T_FINT, NOCON, $1.tr_entry);
481a3e15
PK
715 |
716 variable
717 |
718 YID error
719 = goto NEerror;
720 |
721 func_id '(' wexpr_list ')'
60ba0e41
RT
722 = $$.tr_entry = tree4(T_FCALL, NOCON, $1.tr_entry,
723 fixlist($3.tr_entry));
481a3e15
PK
724 |
725 '(' expr ')'
60ba0e41 726 = $$.tr_entry = $2.tr_entry;
481a3e15
PK
727 |
728 negop expr %prec YNOT
60ba0e41 729 = $$.tr_entry = tree3(T_NOT, NOCON, $2.tr_entry);
481a3e15
PK
730 |
731 '[' element_list ']'
60ba0e41 732 = $$.tr_entry = tree3(T_CSET, SAWCON, fixlist($2.tr_entry));
481a3e15
PK
733 |
734 '[' ']'
60ba0e41 735 = $$.tr_entry = tree3(T_CSET, SAWCON, TR_NIL);
481a3e15
PK
736 ;
737
738element_list:
739 element
60ba0e41 740 = $$.tr_entry = newlist($1.tr_entry);
481a3e15
PK
741 |
742 element_list ',' element
60ba0e41 743 = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
481a3e15
PK
744 ;
745element:
746 expr
747 |
748 expr YDOTDOT expr
60ba0e41 749 = $$.tr_entry = tree3(T_RANG, $1.i_entry, $3.tr_entry);
481a3e15
PK
750 ;
751\f
752/*
753 * QUALIFIED VARIABLES
754 */
755
756variable:
757 YID
758 = {
40aee854 759 @@ return (identis(var, VAR));
60ba0e41 760 $$.tr_entry = setupvar($1.cptr, TR_NIL);
481a3e15
PK
761 }
762 |
763 qual_var
60ba0e41
RT
764 = $1.tr_entry->var_node.qual =
765 fixlist($1.tr_entry->var_node.qual);
481a3e15
PK
766 ;
767qual_var:
768 array_id '[' expr_list ']'
60ba0e41
RT
769 = $$.tr_entry = setupvar($1.cptr, tree2(T_ARY,
770 (int) fixlist($3.tr_entry)));
481a3e15
PK
771 |
772 qual_var '[' expr_list ']'
60ba0e41
RT
773 = $1.tr_entry->var_node.qual =
774 addlist($1.tr_entry->var_node.qual,
775 tree2(T_ARY, (int) fixlist($3.tr_entry)));
481a3e15
PK
776 |
777 record_id '.' field_id
60ba0e41
RT
778 = $$.tr_entry = setupvar($1.cptr, setupfield($3.tr_entry,
779 TR_NIL));
481a3e15
PK
780 |
781 qual_var '.' field_id
60ba0e41
RT
782 = $1.tr_entry->var_node.qual =
783 addlist($1.tr_entry->var_node.qual,
784 setupfield($3.tr_entry, TR_NIL));
481a3e15
PK
785 |
786 ptr_id '^'
60ba0e41 787 = $$.tr_entry = setupvar($1.cptr, tree1(T_PTR));
481a3e15
PK
788 |
789 qual_var '^'
60ba0e41
RT
790 = $1.tr_entry->var_node.qual =
791 addlist($1.tr_entry->var_node.qual, tree1(T_PTR));
481a3e15
PK
792 ;
793\f
794/*
795 * Expression with write widths
796 */
797wexpr:
798 expr
799 |
800 expr ':' expr
60ba0e41 801 = $$.tr_entry = tree4(T_WEXP, $1.i_entry, $3.tr_entry, TR_NIL);
481a3e15
PK
802 |
803 expr ':' expr ':' expr
60ba0e41
RT
804 = $$.tr_entry = tree4(T_WEXP, $1.i_entry, $3.tr_entry,
805 $5.tr_entry);
481a3e15
PK
806 |
807 expr octhex
60ba0e41 808 = $$.tr_entry = tree4(T_WEXP, $1.i_entry, TR_NIL, $2.tr_entry);
481a3e15
PK
809 |
810 expr ':' expr octhex
60ba0e41
RT
811 = $$.tr_entry = tree4(T_WEXP, $1.i_entry, $3.tr_entry,
812 $4.tr_entry);
481a3e15
PK
813 ;
814octhex:
815 YOCT
60ba0e41 816 = $$.i_entry = OCT;
481a3e15
PK
817 |
818 YHEX
60ba0e41 819 = $$.i_entry = HEX;
481a3e15
PK
820 ;
821
822expr_list:
823 expr
60ba0e41 824 = $$.tr_entry = newlist($1.tr_entry);
481a3e15
PK
825 |
826 expr_list ',' expr
60ba0e41 827 = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
481a3e15
PK
828 ;
829
830wexpr_list:
831 wexpr
60ba0e41 832 = $$.tr_entry = newlist($1.tr_entry);
481a3e15
PK
833 |
834 wexpr_list ',' wexpr
60ba0e41 835 = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
481a3e15
PK
836 ;
837\f
838/*
839 * OPERATORS
840 */
841
842relop:
60ba0e41 843 '=' = $$.i_entry = T_EQ;
481a3e15 844 |
60ba0e41 845 '<' = $$.i_entry = T_LT;
481a3e15 846 |
60ba0e41 847 '>' = $$.i_entry = T_GT;
481a3e15 848 |
60ba0e41 849 '<' '>' = $$.i_entry = T_NE;
481a3e15 850 |
60ba0e41 851 '<' '=' = $$.i_entry = T_LE;
481a3e15 852 |
60ba0e41 853 '>' '=' = $$.i_entry = T_GE;
481a3e15 854 |
60ba0e41 855 YIN = $$.i_entry = T_IN;
481a3e15
PK
856 ;
857addop:
60ba0e41 858 '+' = $$.i_entry = T_ADD;
481a3e15 859 |
60ba0e41 860 '-' = $$.i_entry = T_SUB;
481a3e15 861 |
60ba0e41 862 YOR = $$.i_entry = T_OR;
481a3e15 863 |
60ba0e41 864 '|' = $$.i_entry = T_OR;
481a3e15
PK
865 ;
866divop:
60ba0e41 867 '*' = $$.i_entry = T_MULT;
481a3e15 868 |
60ba0e41 869 '/' = $$.i_entry = T_DIVD;
481a3e15 870 |
60ba0e41 871 YDIV = $$.i_entry = T_DIV;
481a3e15 872 |
60ba0e41 873 YMOD = $$.i_entry = T_MOD;
481a3e15 874 |
60ba0e41 875 YAND = $$.i_entry = T_AND;
481a3e15 876 |
60ba0e41 877 '&' = $$.i_entry = T_AND;
481a3e15
PK
878 ;
879
880negop:
881 YNOT
882 |
883 '~'
884 ;
885\f
886/*
887 * LISTS
888 */
889
890var_list:
891 variable
60ba0e41 892 = $$.tr_entry = newlist($1.tr_entry);
481a3e15
PK
893 |
894 var_list ',' variable
60ba0e41 895 = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
481a3e15
PK
896 ;
897
898id_list:
899 YID
60ba0e41 900 = $$.tr_entry = newlist($1.tr_entry);
481a3e15
PK
901 |
902 id_list ',' YID
60ba0e41 903 = $$.tr_entry = addlist($1.tr_entry, $3.tr_entry);
481a3e15
PK
904 ;
905\f
906/*
907 * Identifier productions with semantic restrictions
908 *
40aee854 909 * For these productions, the characters @@ signify
481a3e15
PK
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
922const_id:
923 YID
40aee854 924 = @@ return (identis(var, CONST));
481a3e15
PK
925 ;
926type_id:
927 YID
928 = {
40aee854 929 @@ return (identis(var, TYPE));
60ba0e41 930 $$.tr_entry = tree3(T_TYID, lineof(yyline), $1.tr_entry);
481a3e15
PK
931 }
932 ;
933var_id:
934 YID
40aee854 935 = @@ return (identis(var, VAR));
481a3e15
PK
936 ;
937array_id:
938 YID
40aee854 939 = @@ return (identis(var, ARRAY));
481a3e15
PK
940 ;
941ptr_id:
942 YID
40aee854 943 = @@ return (identis(var, PTRFILE));
481a3e15
PK
944 ;
945record_id:
946 YID
40aee854 947 = @@ return (identis(var, RECORD));
481a3e15
PK
948 ;
949field_id:
950 YID
40aee854 951 = @@ return (identis(var, FIELD));
481a3e15
PK
952 ;
953proc_id:
954 YID
40aee854 955 = @@ return (identis(var, PROC));
481a3e15
PK
956 ;
957func_id:
958 YID
40aee854 959 = @@ return (identis(var, FUNC));
481a3e15 960 ;