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