Commit | Line | Data |
---|---|---|
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 | 107 | static 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 | ||
128 | goal: | |
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 | ||
137 | prog_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 | ; | |
154 | block: | |
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 | */ | |
167 | decls: | |
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 | ||
181 | decl: | |
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 | ||
200 | labels: | |
201 | YLABEL label_decl ';' | |
60ba0e41 | 202 | = label(fixlist($2.tr_entry), lineof($1.i_entry)); |
481a3e15 PK |
203 | ; |
204 | label_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 | ||
218 | const_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 |
229 | Cerror: |
230 | yyPerror("Malformed const declaration", PDECL); | |
231 | } | |
232 | | | |
233 | const_decl error | |
234 | = goto Cerror; | |
235 | ; | |
236 | \f | |
237 | /* | |
238 | * TYPE PART | |
239 | */ | |
240 | ||
241 | type_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 |
251 | Terror: |
252 | yyPerror("Malformed type declaration", PDECL); | |
253 | } | |
254 | | | |
255 | type_decl error | |
256 | = goto Terror; | |
257 | ; | |
258 | \f | |
259 | /* | |
260 | * VAR PART | |
261 | */ | |
262 | ||
263 | var_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 |
273 | Verror: |
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 | 285 | proc_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 | ; |
297 | pheadres: | |
298 | phead | |
60ba0e41 | 299 | = (void) funcbody($1.nl_entry); |
481a3e15 PK |
300 | ; |
301 | phead: | |
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 | ; |
306 | porf: | |
307 | YPROCEDURE | |
60ba0e41 | 308 | = $$.i_entry = T_PDEC; |
481a3e15 PK |
309 | | |
310 | YFUNCTION | |
60ba0e41 | 311 | = $$.i_entry = T_FDEC; |
481a3e15 PK |
312 | ; |
313 | params: | |
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 | ||
325 | param: | |
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 | ; |
342 | ftype: | |
343 | ':' type | |
344 | = $$ = $2; | |
345 | | | |
346 | /* lambda */ | |
60ba0e41 | 347 | = $$.tr_entry = TR_NIL; |
481a3e15 PK |
348 | ; |
349 | param_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 | ||
361 | const: | |
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 | ; |
373 | number: | |
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 | ; |
386 | const_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 | ||
398 | type: | |
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 | ; |
410 | simple_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 | ; |
420 | struct_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 | ; | |
438 | simple_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 | */ | |
449 | field_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 | ; |
454 | fixed_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 | ; | |
464 | field: | |
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 | ||
473 | variant_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 | ; |
486 | variant_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 | ; | |
496 | variant: | |
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 | ||
509 | stat_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 | ||
523 | stat_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 | ||
542 | cstat_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 |
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 | |
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 | ||
577 | stat: | |
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 | = { | |
649 | NSerror: | |
60ba0e41 | 650 | $$.tr_entry = TR_NIL; |
481a3e15 PK |
651 | yyPerror("Malformed statement", PSTAT); |
652 | } | |
653 | ; | |
654 | assign: | |
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 | ||
664 | expr: | |
665 | error | |
666 | = { | |
667 | NEerror: | |
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 | ||
738 | element_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 | ; |
745 | element: | |
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 | ||
756 | variable: | |
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 | ; |
767 | qual_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 | */ | |
797 | wexpr: | |
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 | ; |
814 | octhex: | |
815 | YOCT | |
60ba0e41 | 816 | = $$.i_entry = OCT; |
481a3e15 PK |
817 | | |
818 | YHEX | |
60ba0e41 | 819 | = $$.i_entry = HEX; |
481a3e15 PK |
820 | ; |
821 | ||
822 | expr_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 | ||
830 | wexpr_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 | ||
842 | relop: | |
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 | ; |
857 | addop: | |
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 | ; |
866 | divop: | |
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 | ||
880 | negop: | |
881 | YNOT | |
882 | | | |
883 | '~' | |
884 | ; | |
885 | \f | |
886 | /* | |
887 | * LISTS | |
888 | */ | |
889 | ||
890 | var_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 | ||
898 | id_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 | ||
922 | const_id: | |
923 | YID | |
40aee854 | 924 | = @@ return (identis(var, CONST)); |
481a3e15 PK |
925 | ; |
926 | type_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 | ; | |
933 | var_id: | |
934 | YID | |
40aee854 | 935 | = @@ return (identis(var, VAR)); |
481a3e15 PK |
936 | ; |
937 | array_id: | |
938 | YID | |
40aee854 | 939 | = @@ return (identis(var, ARRAY)); |
481a3e15 PK |
940 | ; |
941 | ptr_id: | |
942 | YID | |
40aee854 | 943 | = @@ return (identis(var, PTRFILE)); |
481a3e15 PK |
944 | ; |
945 | record_id: | |
946 | YID | |
40aee854 | 947 | = @@ return (identis(var, RECORD)); |
481a3e15 PK |
948 | ; |
949 | field_id: | |
950 | YID | |
40aee854 | 951 | = @@ return (identis(var, FIELD)); |
481a3e15 PK |
952 | ; |
953 | proc_id: | |
954 | YID | |
40aee854 | 955 | = @@ return (identis(var, PROC)); |
481a3e15 PK |
956 | ; |
957 | func_id: | |
958 | YID | |
40aee854 | 959 | = @@ return (identis(var, FUNC)); |
481a3e15 | 960 | ; |