xref: /original-bsd/old/dbx/commands.y (revision f0fd5f8a)
1 %{
2 
3 /* Copyright (c) 1982 Regents of the University of California */
4 
5 static char sccsid[] = "@(#)commands.y 1.2 12/15/82";
6 
7 /*
8  * Yacc grammar for debugger commands.
9  */
10 
11 #include "defs.h"
12 #include "symbols.h"
13 #include "operators.h"
14 #include "tree.h"
15 #include "process.h"
16 #include "source.h"
17 #include "scanner.h"
18 #include "names.h"
19 
20 private String curformat = "X";
21 
22 %}
23 
24 %term
25     ALIAS AND ASSIGN AT CALL CATCH CONT DELETE DIV DUMP
26     EDIT FILE FUNC GRIPE HELP IF IGNORE IN LIST MOD NEXT NEXTI NIL NOT OR
27     PRINT PSYM QUIT RUN SH SKIP SOURCE STATUS STEP STEPI
28     STOP STOPI TRACE TRACEI
29     USE WHATIS WHEN WHERE WHEREIS WHICH
30 
31 %term INT REAL NAME STRING
32 %term LFORMER RFORMER ABSTRACTION ARROW
33 
34 %right INT
35 %binary REDIRECT
36 %binary '<' '=' '>' '!' IN
37 %left '+' '-' OR
38 %left UNARYSIGN
39 %left '*' '/' DIV MOD AND
40 %left NOT '(' '[' '.' '^' ARROW
41 
42 %union {
43     Name y_name;
44     Symbol y_sym;
45     Node y_node;
46     Integer y_int;
47     Operator y_op;
48     long y_long;
49     double y_real;
50     String y_string;
51     Boolean y_bool;
52     Cmdlist y_cmdlist;
53 };
54 
55 %type <y_op>	    trace stop
56 %type <y_long>	    INT count
57 %type <y_real>	    REAL
58 %type <y_string>    STRING redirectout filename opt_filename mode
59 %type <y_name>	    ALIAS AND ASSIGN AT CALL CATCH CONT DELETE DIV DUMP
60 %type <y_name>	    EDIT FILE FUNC GRIPE HELP IF IGNORE IN LIST MOD
61 %type <y_name>	    NEXT NEXTI NIL NOT OR
62 %type <y_name>	    PRINT PSYM QUIT RUN SH SKIP SOURCE STATUS STEP STEPI
63 %type <y_name>	    STOP STOPI TRACE TRACEI
64 %type <y_name>	    USE WHATIS WHEN WHERE WHEREIS WHICH
65 %type <y_name>	    name NAME keyword
66 %type <y_node>      symbol
67 %type <y_node>	    command rcommand cmd step what where examine
68 %type <y_node>	    event opt_arglist opt_cond
69 %type <y_node>	    exp_list exp term boolean_exp constant address
70 %type <y_node>	    alias_command list_command line_number
71 %type <y_cmdlist>   actions
72 
73 %%
74 
75 input:
76     input command_nl
77 |
78     /* empty */
79 ;
80 command_nl:
81     command_line '\n'
82 |
83     command_line ';'
84 |
85     '\n'
86 ;
87 
88 command_line:
89     command
90 {
91 	if ($1 != nil) {
92 	    eval($1);
93 	}
94 }
95 |
96     rcommand redirectout
97 {
98 	if ($1 != nil) {
99 	    if ($2 != nil) {
100 		setout($2);
101 		eval($1);
102 		unsetout();
103 	    } else {
104 		eval($1);
105 	    }
106 	}
107 }
108 ;
109 redirectout:
110     '>' shellmode NAME
111 {
112 	$$ = ident($3);
113 }
114 |
115     /* empty */
116 {
117 	$$ = nil;
118 }
119 ;
120 
121 /*
122  * Non-redirectable commands.
123  */
124 command:
125     alias_command
126 {
127 	$$ = $1;
128 }
129 |
130     ASSIGN term '=' exp
131 {
132 	$$ = build(O_ASSIGN, $2, $4);
133 }
134 |
135     CATCH INT
136 {
137 	$$ = build(O_CATCH, $2);
138 }
139 |
140     CONT
141 {
142 	$$ = build(O_CONT);
143 }
144 |
145     DELETE INT
146 {
147 	$$ = build(O_DELETE, $2);
148 }
149 |
150     EDIT shellmode opt_filename
151 {
152 	$$ = build(O_EDIT, $3);
153 }
154 |
155     FILE shellmode opt_filename
156 {
157 	$$ = build(O_CHFILE, $3);
158 }
159 |
160     FUNC
161 {
162 	$$ = build(O_FUNC, nil);
163 }
164 |
165     FUNC symbol
166 {
167 	$$ = build(O_FUNC, $2);
168 }
169 |
170     GRIPE
171 {
172 	$$ = build(O_GRIPE);
173 }
174 |
175     HELP
176 {
177 	$$ = build(O_HELP);
178 }
179 |
180     IGNORE INT
181 {
182 	$$ = build(O_IGNORE, $2);
183 }
184 |
185     list_command
186 {
187 	$$ = $1;
188 }
189 |
190     PSYM term
191 {
192 	$$ = build(O_PSYM, $2);
193 }
194 |
195     QUIT
196 {
197 	if (not popinput()) {
198 	    quit(0);
199 	} else {
200 	    $$ = nil;
201 	}
202 }
203 |
204     runcommand
205 {
206 	run();
207 	/* NOTREACHED */
208 }
209 |
210     SH
211 {
212 	shellline();
213 	$$ = nil;
214 }
215 |
216     SOURCE shellmode filename
217 {
218 	$$ = build(O_SOURCE, $3);
219 }
220 |
221     step
222 {
223 	$$ = $1;
224 }
225 |
226     stop where opt_cond
227 {
228 	$$ = build($1, nil, $2, $3);
229 }
230 |
231     stop what opt_cond
232 {
233 	$$ = build($1, $2, nil, $3);
234 }
235 |
236     stop IF boolean_exp
237 {
238 	$$ = build($1, nil, nil, $3);
239 }
240 |
241     trace what where opt_cond
242 {
243 	$$ = build($1, $2, $3, $4);
244 }
245 |
246     trace where opt_cond
247 {
248 	$$ = build($1, nil, $2, $3);
249 }
250 |
251     trace what opt_cond
252 {
253 	$$ = build($1, $2, nil, $3);
254 }
255 |
256     trace opt_cond
257 {
258 	$$ = build($1, nil, nil, $2);
259 }
260 |
261     WHATIS term
262 {
263 	$$ = build(O_WHATIS, $2);
264 }
265 |
266     WHEN event '{' actions '}'
267 {
268 	$$ = build(O_ADDEVENT, $2, $4);
269 }
270 |
271     WHEREIS symbol
272 {
273 	$$ = build(O_WHEREIS, $2);
274 }
275 |
276     WHICH symbol
277 {
278 	$$ = build(O_WHICH, $2);
279 }
280 |
281     USE shellmode sourcepath
282 {
283 	$$ = nil;
284 	if (list_size(sourcepath) == 0) {
285 	    list_append(list_item("."), nil, sourcepath);
286 	}
287 }
288 ;
289 runcommand:
290     run shellmode arglist
291 ;
292 run:
293     RUN
294 {
295 	fflush(stdout);
296 	arginit();
297 }
298 ;
299 arglist:
300     arglist arg
301 |
302     /* empty */
303 ;
304 arg:
305     NAME
306 {
307 	newarg(ident($1));
308 }
309 |
310     '<' NAME
311 {
312 	inarg(ident($2));
313 }
314 |
315     '>' NAME
316 {
317 	outarg(ident($2));
318 }
319 ;
320 step:
321     STEP
322 {
323 	$$ = build(O_STEP, true, false);
324 }
325 |
326     STEPI
327 {
328 	$$ = build(O_STEP, false, false);
329 }
330 |
331     NEXT
332 {
333 	$$ = build(O_STEP, true, true);
334 }
335 |
336     NEXTI
337 {
338 	$$ = build(O_STEP, false, true);
339 }
340 ;
341 shellmode:
342     /* empty */
343 {
344 	beginshellmode();
345 }
346 ;
347 sourcepath:
348     sourcepath NAME
349 {
350 	list_append(list_item(ident($2)), nil, sourcepath);
351 }
352 |
353     /* empty */
354 {
355 	String dir;
356 
357 	foreach (String, dir, sourcepath)
358 	    list_delete(list_curitem(sourcepath), sourcepath);
359 	endfor
360 }
361 ;
362 event:
363     where
364 |
365     exp
366 ;
367 actions:
368     actions cmd ';'
369 {
370 	$$ = $1;
371 	cmdlist_append($2, $$);
372 }
373 |
374     cmd ';'
375 {
376 	$$ = list_alloc();
377 	cmdlist_append($1, $$);
378 }
379 ;
380 cmd:
381     command
382 |
383     rcommand
384 ;
385 
386 /*
387  * Redirectable commands.
388  */
389 rcommand:
390     PRINT exp_list
391 {
392 	$$ = build(O_PRINT, $2);
393 }
394 |
395     WHERE
396 {
397 	$$ = build(O_WHERE);
398 }
399 |
400     examine
401 {
402 	$$ = $1;
403 }
404 |
405     CALL term
406 {
407 	$$ = $2;
408 }
409 |
410     DUMP
411 {
412 	$$ = build(O_DUMP);
413 }
414 |
415     STATUS
416 {
417 	$$ = build(O_STATUS);
418 }
419 ;
420 alias_command:
421     ALIAS name name
422 {
423 	$$ = build(O_ALIAS, build(O_NAME, $2), build(O_NAME, $3));
424 }
425 |
426     ALIAS name
427 {
428 	$$ = build(O_ALIAS, build(O_NAME, $2), nil);
429 }
430 |
431     ALIAS
432 {
433 	$$ = build(O_ALIAS, nil, nil);
434 }
435 ;
436 trace:
437     TRACE
438 {
439 	$$ = O_TRACE;
440 }
441 |
442     TRACEI
443 {
444 	$$ = O_TRACEI;
445 }
446 ;
447 stop:
448     STOP
449 {
450 	$$ = O_STOP;
451 }
452 |
453     STOPI
454 {
455 	$$ = O_STOPI;
456 }
457 ;
458 what:
459     exp
460 {
461 	$$ = $1;
462 }
463 |
464     STRING ':' line_number
465 {
466 	$$ = build(O_QLINE, build(O_SCON, $1), $3);
467 }
468 ;
469 where:
470     IN term
471 {
472 	$$ = $2;
473 }
474 |
475     AT line_number
476 {
477 	$$ = build(O_QLINE, build(O_SCON, cursource), $2);
478 }
479 |
480     AT STRING ':' line_number
481 {
482 	$$ = build(O_QLINE, build(O_SCON, $2), $4);
483 }
484 ;
485 filename:
486     NAME
487 {
488 	$$ = ident($1);
489 }
490 ;
491 opt_filename:
492     /* empty */
493 {
494 	$$ = nil;
495 }
496 |
497     filename
498 {
499 	$$ = $1;
500 }
501 ;
502 opt_arglist:
503     /* empty */
504 {
505 	$$ = nil;
506 }
507 |
508     '(' exp_list ')'
509 {
510 	$$ = $2;
511 }
512 ;
513 list_command:
514     LIST
515 {
516 	$$ = build(O_LIST,
517 	    build(O_LCON, (long) cursrcline),
518 	    build(O_LCON, (long) cursrcline + 9)
519 	);
520 }
521 |
522     LIST line_number
523 {
524 	$$ = build(O_LIST, $2, $2);
525 }
526 |
527     LIST line_number ',' line_number
528 {
529 	$$ = build(O_LIST, $2, $4);
530 }
531 |
532     LIST symbol
533 {
534 	$$ = build(O_LIST, $2);
535 }
536 ;
537 line_number:
538     INT
539 {
540 	$$ = build(O_LCON, $1);
541 }
542 |
543     '$'
544 {
545 	$$ = build(O_LCON, (long) LASTLINE);
546 }
547 ;
548 examine:
549     address '/' count mode
550 {
551 	$$ = build(O_EXAMINE, $4, $1, nil, $3);
552 }
553 |
554     address ',' address '/' mode
555 {
556 	$$ = build(O_EXAMINE, $5, $1, $3, 0);
557 }
558 |
559     '/' count mode
560 {
561 	$$ = build(O_EXAMINE, $3, build(O_LCON, (long) prtaddr), nil, $2);
562 }
563 ;
564 address:
565     INT
566 {
567 	$$ = build(O_LCON, $1);
568 }
569 |
570     '&' term
571 {
572 	$$ = amper($2);
573 }
574 |
575     address '+' address
576 {
577 	$$ = build(O_ADD, $1, $3);
578 }
579 |
580     address '-' address
581 {
582 	$$ = build(O_SUB, $1, $3);
583 }
584 |
585     address '*' address
586 {
587 	$$ = build(O_MUL, $1, $3);
588 }
589 |
590     '*' address %prec UNARYSIGN
591 {
592 	$$ = build(O_INDIR, $2);
593 }
594 |
595     '(' exp ')'
596 {
597 	$$ = $2;
598 }
599 ;
600 count:
601     /* empty */
602 {
603 	$$ = 1;
604 }
605 |
606     INT
607 {
608 	$$ = $1;
609 }
610 ;
611 mode:
612     name
613 {
614 	$$ = ident($1);
615 	curformat = $$;
616 }
617 |
618     /* empty */
619 {
620 	$$ = curformat;
621 }
622 ;
623 opt_cond:
624     /* empty */
625 {
626 	$$ = nil;
627 }
628 |
629     IF boolean_exp
630 {
631 	$$ = $2;
632 }
633 ;
634 exp_list:
635     exp
636 {
637 	$$ = build(O_COMMA, $1, nil);
638 }
639 |
640     exp ',' exp_list
641 {
642 	$$ = build(O_COMMA, $1, $3);
643 }
644 ;
645 exp:
646     term
647 {
648 	$$ = build(O_RVAL, $1);
649 }
650 |
651     constant
652 {
653 	$$ = $1;
654 }
655 |
656     '+' exp %prec UNARYSIGN
657 {
658 	$$ = $2;
659 }
660 |
661     '-' exp %prec UNARYSIGN
662 {
663 	$$ = build(O_NEG, $2);
664 }
665 |
666     '&' exp %prec UNARYSIGN
667 {
668 	$$ = amper($2);
669 }
670 |
671     exp '+' exp
672 {
673 	$$ = build(O_ADD, $1, $3);
674 }
675 |
676     exp '-' exp
677 {
678 	$$ = build(O_SUB, $1, $3);
679 }
680 |
681     exp '*' exp
682 {
683 	$$ = build(O_MUL, $1, $3);
684 }
685 |
686     exp '/' exp
687 {
688 	$$ = build(O_DIVF, $1, $3);
689 }
690 |
691     exp DIV exp
692 {
693 	$$ = build(O_DIV, $1, $3);
694 }
695 |
696     exp MOD exp
697 {
698 	$$ = build(O_MOD, $1, $3);
699 }
700 |
701     exp AND exp
702 {
703 	$$ = build(O_AND, $1, $3);
704 }
705 |
706     exp OR exp
707 {
708 	$$ = build(O_OR, $1, $3);
709 }
710 |
711     exp '<' exp
712 {
713 	$$ = build(O_LT, $1, $3);
714 }
715 |
716     exp '<' '=' exp
717 {
718 	$$ = build(O_LE, $1, $4);
719 }
720 |
721     exp '>' exp
722 {
723 	$$ = build(O_GT, $1, $3);
724 }
725 |
726     exp '>' '=' exp
727 {
728 	$$ = build(O_GE, $1, $4);
729 }
730 |
731     exp '=' exp
732 {
733 	$$ = build(O_EQ, $1, $3);
734 }
735 |
736     exp '=' '=' exp
737 {
738 	$$ = build(O_EQ, $1, $4);
739 }
740 |
741     exp '<' '>' exp
742 {
743 	$$ = build(O_NE, $1, $4);
744 }
745 |
746     exp '!' '=' exp
747 {
748 	$$ = build(O_NE, $1, $4);
749 }
750 |
751     '(' exp ')'
752 {
753 	$$ = $2;
754 }
755 ;
756 term:
757     symbol
758 {
759 	$$ = $1;
760 }
761 |
762     term '[' exp_list ']'
763 {
764 	$$ = subscript($1, $3);
765 }
766 |
767     term '.' name
768 {
769 	$$ = dot($1, $3);
770 }
771 |
772     term ARROW name
773 {
774 	$$ = dot($1, $3);
775 }
776 |
777     '*' term %prec UNARYSIGN
778 {
779 	$$ = build(O_INDIR, $2);
780 }
781 |
782     '*' '(' exp ')' %prec UNARYSIGN
783 {
784 	$$ = build(O_INDIR, $3);
785 }
786 |
787     term '^' %prec UNARYSIGN
788 {
789 	$$ = build(O_INDIR, $1);
790 }
791 |
792     '#' term %prec UNARYSIGN
793 {
794 	$$ = concrete($2);
795 }
796 |
797     term '(' exp_list ')'
798 {
799 	$$ = build(O_CALL, $1, $3);
800 }
801 ;
802 boolean_exp:
803     exp
804 {
805 	chkboolean($1);
806 	$$ = $1;
807 }
808 ;
809 constant:
810     INT
811 {
812 	$$ = build(O_LCON, $1);
813 }
814 |
815     REAL
816 {
817 	$$ = build(O_FCON, $1);
818 }
819 |
820     STRING
821 {
822 	$$ = build(O_SCON, $1);
823 }
824 ;
825 symbol:
826     name
827 {
828 	$$ = build(O_SYM, which($1));
829 }
830 ;
831 name:
832     NAME
833 {
834 	$$ = $1;
835 }
836 |
837     keyword
838 {
839 	$$ = $1;
840 }
841 keyword:
842     ALIAS | AND | ASSIGN | AT | CALL | CATCH | CONT | DELETE | DIV | DUMP |
843     EDIT | FILE | FUNC | GRIPE | HELP | IGNORE | IN | LIST | MOD |
844     NEXT | NEXTI | NIL | NOT | OR | PRINT | PSYM | QUIT | RUN |
845     SH | SKIP | SOURCE | STATUS | STEP | STEPI |
846     STOP | STOPI | TRACE | TRACEI |
847     USE | WHATIS | WHEN | WHERE | WHICH
848 ;
849