1 %{
2 /*-
3 * Copyright (c) 1982, 1993
4 * The Regents of the University of California. All rights reserved.
5 *
6 * %sccs.include.redist.c%
7 */
8
9 #ifndef lint
10 static char sccsid[] = "@(#)grammar.y 8.1 (Berkeley) 06/06/93";
11 #endif /* not lint */
12
13 /*
14 * yacc grammar for debugger commands
15 */
16
17 #include "defs.h"
18 #include "command.h"
19 #include "sym.h"
20 #include "symtab.h"
21 #include "tree.h"
22 #include "process.h"
23 #include "source.h"
24
25 %}
26
27 %term ALIAS ASSIGN CALL CHFILE
28 %term CONT DUMP EDIT
29 %term GRIPE HELP LIST NEXT
30 %term QUIT REMAKE PRINT
31 %term RUN SH SOURCE
32 %term STATUS STEP
33 %term STOP STOPI TRACE TRACEI
34 %term DELETE
35 %term WHATIS WHICH WHERE
36 %term XI XD
37
38 %term AT IN IF
39 %term FILENAME
40 %term INT REAL NAME STRING
41 %term DIV MOD
42 %term AND OR NOT
43
44 %binary '<' '=' '>' IN
45 %left '+' '-' OR '|'
46 %left UNARYSIGN
47 %left '*' '/' DIV MOD AND '&'
48 %left NOT
49
50 %union {
51 SYM *y_sym;
52 NODE *y_node;
53 int y_int;
54 OP y_op;
55 long y_long;
56 double y_real;
57 char *y_string;
58 BOOLEAN y_bool;
59 };
60
61 %type <y_int> trace TRACE TRACEI stop STOP STOPI
62 %type <y_long> INT
63 %type <y_real> REAL
64 %type <y_op> addop mulop relop
65 %type <y_string> STRING FILENAME SH opt_filename
66 %type <y_sym> NAME
67 %type <y_node> command rcommand what where opt_arglist opt_cond
68 %type <y_node> exp_list exp boolean_exp term constant
69 %type <y_node> line_list line_number address_list
70 %%
71 input:
72 input command_nl
73 {
74 prompt();
75 }
76 | /* empty */
77 ;
78 command_nl:
79 command_line '\n'
80 | '\n'
81 ;
82
83 /*
84 * There are two kinds of commands, those that can be redirected
85 * and those that can't.
86 */
87
88 command_line:
89 command
90 {
91 eval($1);
92 }
93 | rcommand
94 {
95 eval($1);
96 }
97 | rcommand '>' FILENAME
98 {
99 setout($3);
100 eval($1);
101 unsetout();
102 }
103 | SH
104 {
105 shell($1);
106 }
107 | run args
108 {
109 run();
110 }
111 ;
112 run:
113 RUN
114 {
115 arginit();
116 }
117 ;
118 args:
119 arg args
120 | /* empty */
121 ;
122 arg:
123 FILENAME
124 {
125 newarg($1);
126 }
127 | '<' FILENAME
128 {
129 inarg($2);
130 }
131 | '>' FILENAME
132 {
133 outarg($2);
134 }
135 ;
136 command:
137 ASSIGN term exp
138 {
139 $$ = build(O_ASSIGN, $2, $3);
140 }
141 | CHFILE opt_filename
142 {
143 $$ = build(O_CHFILE, $2);
144 }
145 | CONT
146 {
147 $$ = build(O_CONT);
148 }
149 | LIST line_list
150 {
151 $$ = build(O_LIST, $2);
152 }
153 | LIST NAME
154 {
155 $$ = build(O_LIST, build(O_NAME, $2));
156 }
157 | NEXT
158 {
159 $$ = build(O_NEXT);
160 }
161 | PRINT exp_list
162 {
163 $$ = build(O_PRINT, $2);
164 }
165 | QUIT
166 {
167 quit(0);
168 }
169 | STEP
170 {
171 $$ = build(O_STEP);
172 }
173 | stop where opt_cond
174 {
175 $$ = build($1, NIL, $2, $3);
176 }
177 | stop what opt_cond
178 {
179 $$ = build($1, $2, NIL, $3);
180 }
181 | stop IF boolean_exp
182 {
183 $$ = build($1, NIL, NIL, $3);
184 }
185 | trace what where opt_cond
186 {
187 $$ = build($1, $2, $3, $4);
188 }
189 | trace where opt_cond
190 {
191 $$ = build($1, NIL, $2, $3);
192 }
193 | trace what opt_cond
194 {
195 $$ = build($1, $2, NIL, $3);
196 }
197 | trace opt_cond
198 {
199 $$ = build($1, NIL, NIL, $2);
200 }
201 | DELETE INT
202 {
203 $$ = build(O_DELETE, $2);
204 }
205 | WHATIS term
206 {
207 $$ = build(O_WHATIS, $2);
208 }
209 | WHICH NAME
210 {
211 $$ = build(O_WHICH, $2);
212 }
213 | WHERE
214 {
215 $$ = build(O_WHERE);
216 }
217 | XI address_list
218 {
219 $$ = build(O_XI, $2);
220 }
221 | XD address_list
222 {
223 $$ = build(O_XD, $2);
224 }
225 ;
226 rcommand:
227 ALIAS FILENAME opt_filename
228 {
229 $$ = build(O_ALIAS, $2, $3);
230 }
231 | ALIAS
232 {
233 $$ = build(O_ALIAS, NIL, NIL);
234 }
235 | CALL term opt_arglist
236 {
237 $$ = build(O_CALL, $2, $3);
238 }
239 | EDIT opt_filename
240 {
241 $$ = build(O_EDIT, $2);
242 }
243 | DUMP
244 {
245 $$ = build(O_DUMP);
246 }
247 | GRIPE
248 {
249 $$ = build(O_GRIPE);
250 }
251 | HELP
252 {
253 $$ = build(O_HELP);
254 }
255 | REMAKE
256 {
257 $$ = build(O_REMAKE);
258 }
259 | SOURCE FILENAME
260 {
261 $$ = build(O_SOURCE, $2);
262 }
263 | STATUS
264 {
265 $$ = build(O_STATUS);
266 }
267 ;
268 trace:
269 TRACE
270 {
271 $$ = O_TRACE;
272 }
273 | TRACEI
274 {
275 $$ = O_TRACEI;
276 }
277 ;
278 stop:
279 STOP
280 {
281 $$ = O_STOP;
282 }
283 | STOPI
284 {
285 $$ = O_STOPI;
286 }
287 ;
288 what:
289 exp
290 | FILENAME line_number
291 {
292 $$ = build(O_QLINE, $1, $2);
293 }
294 ;
295 where:
296 IN term
297 {
298 $$ = $2;
299 }
300 | AT line_number
301 {
302 $$ = build(O_QLINE, cursource, $2);
303 }
304 | AT FILENAME line_number
305 {
306 $$ = build(O_QLINE, $2, $3);
307 }
308 ;
309 opt_filename:
310 /* empty */
311 {
312 $$ = NIL;
313 }
314 | FILENAME
315 ;
316 opt_arglist:
317 /* empty */
318 {
319 $$ = NIL;
320 }
321 | '(' exp_list ')'
322 {
323 $$ = $2;
324 }
325 ;
326 line_list:
327 /* empty */
328 {
329 NODE *first, *last;
330
331 first = build(O_LCON, (long) 1);
332 last = build(O_LCON, (long) lastlinenum);
333 $$ = build(O_COMMA, first, last);
334 }
335 | line_number
336 {
337 $$ = build(O_COMMA, $1, $1);
338 }
339 | line_number ',' line_number
340 {
341 $$ = build(O_COMMA, $1, $3);
342 }
343 ;
344 line_number:
345 INT
346 {
347 $$ = build(O_LCON, $1);
348 }
349 | '$'
350 {
351 $$ = build(O_LCON, (long) lastlinenum);
352 }
353 ;
354 address_list:
355 exp
356 {
357 $$ = build(O_COMMA, $1, $1);
358 }
359 | exp ',' exp
360 {
361 $$ = build(O_COMMA, $1, $3);
362 }
363 ;
364 opt_cond:
365 /* empty */
366 {
367 $$ = NIL;
368 }
369 | IF boolean_exp
370 {
371 $$ = $2;
372 }
373 ;
374 exp_list:
375 exp
376 {
377 $$ = build(O_COMMA, $1, NIL);
378 }
379 | exp ',' exp_list
380 {
381 $$ = build(O_COMMA, $1, $3);
382 }
383 ;
384 exp:
385 term
386 {
387 $$ = build(O_RVAL, $1);
388 }
389 | term '(' exp_list ')'
390 {
391 $$ = build(O_CALL, $1, $3);
392 }
393 | constant
394 | '+' exp %prec UNARYSIGN
395 {
396 $$ = $2;
397 }
398 | '-' exp %prec UNARYSIGN
399 {
400 $$ = build(O_NEG, $2);
401 }
402 | exp addop exp %prec '+'
403 {
404 $$ = build($2, $1, $3);
405 }
406 | exp mulop exp %prec '*'
407 {
408 $$ = build($2, $1, $3);
409 }
410 | exp relop exp %prec '<'
411 {
412 $$ = build($2, $1, $3);
413 }
414 | '(' exp ')'
415 {
416 $$ = $2;
417 }
418 ;
419 boolean_exp:
420 exp
421 {
422 chkboolean($$ = $1);
423 }
424 ;
425 term:
426 NAME
427 {
428 $$ = build(O_NAME, $1);
429 }
430 | AT
431 {
432 SYM *s;
433
434 s = st_lookup(symtab, "at");
435 if (s == NIL) {
436 error("\"at\" is not defined");
437 }
438 $$ = build(O_NAME, s);
439 }
440 | term '[' exp_list ']'
441 {
442 $$ = subscript($1, $3);
443 }
444 | term '.' NAME
445 {
446 $$ = dot($1, $3);
447 }
448 | term '^'
449 {
450 $$ = build(O_INDIR, $1);
451 }
452 ;
453 constant:
454 INT
455 {
456 $$ = build(O_LCON, $1);
457 }
458 | REAL
459 {
460 $$ = build(O_FCON, $1);
461 }
462 | STRING
463 {
464 $$ = build(O_SCON, $1);
465 }
466 ;
467 addop:
468 '+'
469 {
470 $$ = O_ADD;
471 }
472 | '-'
473 {
474 $$ = O_SUB;
475 }
476 | OR
477 {
478 $$ = O_OR;
479 }
480 | '|'
481 {
482 $$ = O_OR;
483 }
484 ;
485 mulop:
486 '*'
487 {
488 $$ = O_MUL;
489 }
490 | '/'
491 {
492 $$ = O_DIVF;
493 }
494 | DIV
495 {
496 $$ = O_DIV;
497 }
498 | MOD
499 {
500 $$ = O_MOD;
501 }
502 | AND
503 {
504 $$ = O_AND;
505 }
506 | '&'
507 {
508 $$ = O_AND;
509 }
510 ;
511 relop:
512 '<'
513 {
514 $$ = O_LT;
515 }
516 | '<' '='
517 {
518 $$ = O_LE;
519 }
520 | '>'
521 {
522 $$ = O_GT;
523 }
524 | '>' '='
525 {
526 $$ = O_GE;
527 }
528 | '='
529 {
530 $$ = O_EQ;
531 }
532 | '<' '>'
533 {
534 $$ = O_NE;
535 }
536 ;
537 %%
538
539 /*
540 * parser error handling
541 */
542
yyerror(s)543 yyerror(s)
544 char *s;
545 {
546 if (strcmp(s, "syntax error") == 0) {
547 error("bad command syntax");
548 } else {
549 error(s);
550 }
551 }
552
553 /*
554 * In recovering from an error we gobble input up to a newline.
555 */
556
gobble()557 gobble()
558 {
559 register int t;
560
561 if (!nlflag) {
562 while ((t = yylex()) != '\n' && t != 0);
563 }
564 }
565