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