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