xref: /original-bsd/old/dbx/commands.y (revision 7211505a)
1 %{
2 
3 /*
4  * Copyright (c) 1983 Regents of the University of California.
5  * All rights reserved.  The Berkeley software License Agreement
6  * specifies the terms and conditions for redistribution.
7  *
8  *	@(#)commands.y	5.4 (Berkeley) 01/12/88
9  */
10 
11 static char rcsid[] = "$Header: commands.y,v 1.2 87/08/19 15:18:53 mike Exp $";
12 
13 /*
14  * Yacc grammar for debugger commands.
15  */
16 
17 #include "defs.h"
18 #include "symbols.h"
19 #include "operators.h"
20 #include "tree.h"
21 #include "process.h"
22 #include "source.h"
23 #include "scanner.h"
24 #include "keywords.h"
25 #include "names.h"
26 #include "lists.h"
27 
28 private String curformat = "X";
29 
30 %}
31 
32 %term
33     ALIAS AND ASSIGN AT CALL CATCH CONT DEBUG DELETE DIV DOWN DUMP
34     EDIT FILE FUNC GRIPE HELP IF IGNORE IN LIST MOD NEXT NEXTI NIL NOT OR
35     PRINT PSYM QUIT RERUN RETURN RUN SET SH SKIP SOURCE STATUS STEP STEPI
36     STOP STOPI TRACE TRACEI UNALIAS UNSET UP USE
37     WHATIS WHEN WHERE WHEREIS WHICH
38 
39 %term INT CHAR REAL NAME STRING
40 %term ARROW
41 
42 %right INT
43 %binary REDIRECT
44 %binary '<' '=' '>' '!' IN
45 %left '+' '-' OR
46 %left UNARYSIGN
47 %left '*' '/' DIV MOD AND
48 %left '\\'
49 %left NOT '(' '[' '.' '^' ARROW
50 
51 %union {
52     Name y_name;
53     Symbol y_sym;
54     Node y_node;
55     Integer y_int;
56     Operator y_op;
57     long y_long;
58     char y_char;
59     double y_real;
60     String y_string;
61     Boolean y_bool;
62     Cmdlist y_cmdlist;
63     List y_list;
64 };
65 
66 %type <y_op>	    trace stop
67 %type <y_long>	    INT count signal
68 %type <y_char>	    CHAR
69 %type <y_real>	    REAL
70 %type <y_string>    STRING redirectout filename opt_filename mode
71 %type <y_name>	    ALIAS AND ASSIGN AT CALL CATCH CONT
72 %type <y_name>	    DEBUG DELETE DIV DOWN DUMP
73 %type <y_name>	    EDIT FILE FUNC GRIPE HELP IF IGNORE IN LIST MOD
74 %type <y_name>	    NEXT NEXTI NIL NOT OR
75 %type <y_name>	    PRINT PSYM QUIT RERUN RETURN RUN SET SH SKIP SOURCE STATUS
76 %type <y_name>	    STEP STEPI STOP STOPI TRACE TRACEI
77 %type <y_name>	    UNALIAS UNSET UP USE WHATIS WHEN WHERE WHEREIS WHICH
78 %type <y_name>	    name NAME keyword
79 %type <y_node>      opt_qual_symbol symbol
80 %type <y_node>	    command rcommand cmd step what where examine
81 %type <y_node>	    event opt_exp_list opt_cond
82 %type <y_node>	    exp_list exp term boolean_exp constant address
83 %type <y_node>	    integer_list alias_command list_command line_number
84 %type <y_cmdlist>   actions
85 %type <y_list>      sourcepath name_list
86 
87 %%
88 
89 input:
90     input command_nl
91 |
92     /* empty */
93 ;
94 command_nl:
95     command_line '\n'
96 |
97     command_line ';'
98 {
99 	chkalias = true;
100 }
101 |
102     '\n'
103 ;
104 
105 command_line:
106     command
107 {
108 	if ($1 != nil) {
109 	    topeval($1);
110 	}
111 }
112 |
113     rcommand redirectout
114 {
115 	if ($1 != nil) {
116 	    if ($2 != nil) {
117 		setout($2);
118 		topeval($1);
119 		unsetout();
120 	    } else {
121 		topeval($1);
122 	    }
123 	}
124 }
125 ;
126 redirectout:
127     '>' shellmode NAME
128 {
129 	$$ = ident($3);
130 }
131 |
132     /* empty */
133 {
134 	$$ = nil;
135 }
136 ;
137 
138 /*
139  * Non-redirectable commands.
140  */
141 command:
142     alias_command
143 {
144 	$$ = $1;
145 }
146 |
147     ASSIGN exp '=' exp
148 {
149 	$$ = build(O_ASSIGN, unrval($2), $4);
150 }
151 |
152     CATCH signal
153 {
154 	$$ = build(O_CATCH, $2);
155 }
156 |
157     CATCH
158 {
159 	$$ = build(O_CATCH, 0);
160 }
161 |
162     CONT
163 {
164 	$$ = build(O_CONT, (long) DEFSIG);
165 }
166 |
167     CONT signal
168 {
169 	$$ = build(O_CONT, $2);
170 }
171 |
172     DELETE integer_list
173 {
174 	$$ = build(O_DELETE, $2);
175 }
176 |
177     DOWN
178 {
179 	$$ = build(O_DOWN, build(O_LCON, (long) 1));
180 }
181 |
182     DOWN INT
183 {
184 	$$ = build(O_DOWN, build(O_LCON, (long) $2));
185 }
186 |
187     EDIT shellmode opt_filename
188 {
189 	$$ = build(O_EDIT, $3);
190 }
191 |
192     FILE shellmode opt_filename
193 {
194 	$$ = build(O_CHFILE, $3);
195 }
196 |
197     FUNC
198 {
199 	$$ = build(O_FUNC, nil);
200 }
201 |
202     FUNC opt_qual_symbol
203 {
204 	$$ = build(O_FUNC, $2);
205 }
206 |
207     GRIPE
208 {
209 	$$ = build(O_GRIPE);
210 }
211 |
212     HELP
213 {
214 	$$ = build(O_HELP);
215 }
216 |
217     IGNORE signal
218 {
219 	$$ = build(O_IGNORE, $2);
220 }
221 |
222     IGNORE
223 {
224 	$$ = build(O_IGNORE, 0);
225 }
226 |
227     list_command
228 {
229 	$$ = $1;
230 }
231 |
232     PSYM exp
233 {
234 	$$ = build(O_PSYM, unrval($2));
235 }
236 |
237     QUIT
238 {
239 	if (not popinput()) {
240 	    quit(0);
241 	} else {
242 	    $$ = nil;
243 	}
244 }
245 |
246     RETURN
247 {
248 	$$ = build(O_RETURN, nil);
249 }
250 |
251     RETURN opt_qual_symbol
252 {
253 	$$ = build(O_RETURN, $2);
254 }
255 |
256     runcommand
257 {
258 	run();
259 	/* NOTREACHED */
260 }
261 |
262     SET name '=' exp
263 {
264 	$$ = build(O_SET, build(O_NAME, $2), $4);
265 }
266 |
267     SET name
268 {
269 	$$ = build(O_SET, build(O_NAME, $2), nil);
270 }
271 |
272     SET
273 {
274 	$$ = build(O_SET, nil, nil);
275 }
276 |
277     SH
278 {
279 	shellline();
280 	$$ = nil;
281 }
282 |
283     SOURCE shellmode filename
284 {
285 	$$ = build(O_SOURCE, $3);
286 }
287 |
288     step
289 {
290 	$$ = $1;
291 }
292 |
293     stop where opt_cond
294 {
295 	$$ = build($1, nil, $2, $3);
296 }
297 |
298     stop what opt_cond
299 {
300 	$$ = build($1, $2, nil, $3);
301 }
302 |
303     stop IF boolean_exp
304 {
305 	$$ = build($1, nil, nil, $3);
306 }
307 |
308     trace what where opt_cond
309 {
310 	$$ = build($1, $2, $3, $4);
311 }
312 |
313     trace where opt_cond
314 {
315 	$$ = build($1, nil, $2, $3);
316 }
317 |
318     trace what opt_cond
319 {
320 	$$ = build($1, $2, nil, $3);
321 }
322 |
323     trace opt_cond
324 {
325 	$$ = build($1, nil, nil, $2);
326 }
327 |
328     UNALIAS name
329 {
330 	$$ = build(O_UNALIAS, build(O_NAME, $2));
331 }
332 |
333     UNSET name
334 {
335 	$$ = build(O_UNSET, build(O_NAME, $2));
336 }
337 |
338     UP
339 {
340 	$$ = build(O_UP, build(O_LCON, (long) 1));
341 }
342 |
343     UP INT
344 {
345 	$$ = build(O_UP, build(O_LCON, (long) $2));
346 }
347 |
348     USE shellmode sourcepath
349 {
350 	String dir;
351 
352 	$$ = nil;
353 	if (list_size($3) == 0) {
354 	    foreach (String, dir, sourcepath)
355 		printf("%s ", dir);
356 	    endfor
357 	    printf("\n");
358 	} else {
359 	    foreach (String, dir, sourcepath)
360 		list_delete(list_curitem(sourcepath), sourcepath);
361 	    endfor
362 	    sourcepath = $3;
363 	}
364 }
365 |
366     WHATIS opt_qual_symbol
367 {
368 	$$ = build(O_WHATIS, $2);
369 }
370 |
371     WHEN event '{' actions '}'
372 {
373 	$$ = build(O_ADDEVENT, $2, $4);
374 }
375 |
376     WHEREIS name
377 {
378 	$$ = build(O_WHEREIS, build(O_SYM, lookup($2)));
379 }
380 |
381     WHICH symbol
382 {
383 	$$ = build(O_WHICH, $2);
384 }
385 |
386     '/'
387 {
388 	$$ = build(O_SEARCH,
389 	    build(O_LCON, (long) '/'),
390 	    build(O_SCON, strdup(scanner_linebuf))
391 	);
392 	gobble();
393 	insertinput("\n");
394 }
395 |
396     '?'
397 {
398 	$$ = build(O_SEARCH,
399 	    build(O_LCON, (long) '?'),
400 	    build(O_SCON, strdup(scanner_linebuf))
401 	);
402 	gobble();
403 	insertinput("\n");
404 }
405 ;
406 signal:
407     INT
408 {
409 	$$ = $1;
410 }
411 |
412     name
413 {
414 	$$ = siglookup(ident($1));
415 }
416 ;
417 runcommand:
418     run arglist
419 |
420     run
421 ;
422 run:
423     RUN shellmode
424 {
425 	arginit();
426 	fflush(stdout);
427 }
428 |
429     RERUN shellmode
430 {
431 	fflush(stdout);
432 }
433 ;
434 arglist:
435     arglist arg
436 |
437     arg
438 ;
439 arg:
440     NAME
441 {
442 	newarg(ident($1));
443 }
444 |
445     STRING
446 {
447 	newarg($1);
448 }
449 |
450     '<' NAME
451 {
452 	inarg(ident($2));
453 }
454 |
455     '>' NAME
456 {
457 	outarg(ident($2));
458 }
459 ;
460 step:
461     STEP
462 {
463 	$$ = build(O_STEP, true, false);
464 }
465 |
466     STEPI
467 {
468 	$$ = build(O_STEP, false, false);
469 }
470 |
471     NEXT
472 {
473 	$$ = build(O_STEP, true, true);
474 }
475 |
476     NEXTI
477 {
478 	$$ = build(O_STEP, false, true);
479 }
480 ;
481 shellmode:
482     /* empty */
483 {
484 	beginshellmode();
485 }
486 ;
487 sourcepath:
488     sourcepath NAME
489 {
490 	$$ = $1;
491 	list_append(list_item(ident($2)), nil, $$);
492 }
493 |
494     /* empty */
495 {
496 	$$ = list_alloc();
497 }
498 ;
499 event:
500     where
501 |
502     exp
503 ;
504 actions:
505     actions cmd ';'
506 {
507 	$$ = $1;
508 	cmdlist_append($2, $$);
509 }
510 |
511     cmd ';'
512 {
513 	$$ = list_alloc();
514 	cmdlist_append($1, $$);
515 }
516 ;
517 cmd:
518     command
519 |
520     rcommand
521 ;
522 
523 /*
524  * Redirectable commands.
525  */
526 rcommand:
527     PRINT exp_list
528 {
529 	$$ = build(O_PRINT, $2);
530 }
531 |
532     WHERE
533 {
534 	$$ = build(O_WHERE);
535 }
536 |
537     examine
538 {
539 	$$ = $1;
540 }
541 |
542     CALL term '(' opt_exp_list ')'
543 {
544 	$$ = build(O_CALLPROC, $2, $4);
545 }
546 |
547     DEBUG INT
548 {
549  	$$ = build(O_DEBUG, $2);
550 }
551 |
552     DEBUG '-' INT
553 {
554 	$$ = build(O_DEBUG, -$3);
555 }
556 |
557     DUMP opt_qual_symbol
558 {
559 	$$ = build(O_DUMP, $2);
560 }
561 |
562     DUMP '.'
563 {
564 	$$ = build(O_DUMP, nil);
565 }
566 |
567     DUMP
568 {
569 	$$ = build(O_DUMP, build(O_SYM, curfunc));
570 }
571 |
572     STATUS
573 {
574 	$$ = build(O_STATUS);
575 }
576 ;
577 alias_command:
578     ALIAS name name
579 {
580 	$$ = build(O_ALIAS, build(O_NAME, $2), build(O_NAME, $3));
581 }
582 |
583     ALIAS name STRING
584 {
585 	$$ = build(O_ALIAS, build(O_NAME, $2), build(O_SCON, $3));
586 }
587 |
588     ALIAS name '(' name_list ')' STRING
589 {
590 	$$ = build(O_ALIAS,
591 	    build(O_COMMA, build(O_NAME, $2), (Node) $4),
592 	    build(O_SCON, $6)
593 	);
594 }
595 |
596     ALIAS name
597 {
598 	$$ = build(O_ALIAS, build(O_NAME, $2), nil);
599 }
600 |
601     ALIAS
602 {
603 	$$ = build(O_ALIAS, nil, nil);
604 }
605 ;
606 name_list:
607     name_list ',' name
608 {
609 	$$ = $1;
610 	list_append(list_item($3), nil, $$);
611 }
612 |
613     name
614 {
615 	$$ = list_alloc();
616 	list_append(list_item($1), nil, $$);
617 }
618 ;
619 trace:
620     TRACE
621 {
622 	$$ = O_TRACE;
623 }
624 |
625     TRACEI
626 {
627 	$$ = O_TRACEI;
628 }
629 ;
630 stop:
631     STOP
632 {
633 	$$ = O_STOP;
634 }
635 |
636     STOPI
637 {
638 	$$ = O_STOPI;
639 }
640 ;
641 what:
642     exp
643 {
644 	$$ = $1;
645 }
646 |
647     STRING ':' line_number
648 {
649 	$$ = build(O_QLINE, build(O_SCON, $1), $3);
650 }
651 ;
652 where:
653     IN exp
654 {
655 	$$ = unrval($2);
656 }
657 |
658     AT line_number
659 {
660 	$$ = build(O_QLINE, build(O_SCON, strdup(cursource)), $2);
661 }
662 |
663     AT STRING ':' line_number
664 {
665 	$$ = build(O_QLINE, build(O_SCON, $2), $4);
666 }
667 ;
668 filename:
669     NAME
670 {
671 	$$ = ident($1);
672 }
673 ;
674 opt_filename:
675     /* empty */
676 {
677 	$$ = nil;
678 }
679 |
680     filename
681 {
682 	$$ = $1;
683 }
684 ;
685 opt_exp_list:
686     exp_list
687 {
688 	$$ = $1;
689 }
690 |
691     /* empty */
692 {
693 	$$ = nil;
694 }
695 ;
696 list_command:
697     LIST
698 {
699 	$$ = build(O_LIST,
700 	    build(O_LCON, (long) cursrcline),
701 	    build(O_LCON, (long) cursrcline + srcwindowlen() - 1)
702 	);
703 }
704 |
705     LIST line_number
706 {
707 	$$ = build(O_LIST, $2, $2);
708 }
709 |
710     LIST line_number ',' line_number
711 {
712 	$$ = build(O_LIST, $2, $4);
713 }
714 |
715     LIST opt_qual_symbol
716 {
717 	$$ = build(O_LIST, $2, $2);
718 }
719 ;
720 integer_list:
721     INT
722 {
723 	$$ = build(O_LCON, $1);
724 }
725 |
726     INT integer_list
727 {
728 	$$ = build(O_COMMA, build(O_LCON, $1), $2);
729 }
730 ;
731 line_number:
732     INT
733 {
734 	$$ = build(O_LCON, $1);
735 }
736 |
737     '$'
738 {
739 	$$ = build(O_LCON, (long) LASTLINE);
740 }
741 ;
742 examine:
743     address '/' count mode
744 {
745 	$$ = build(O_EXAMINE, $4, $1, nil, $3);
746 }
747 |
748     address ',' address '/' mode
749 {
750 	$$ = build(O_EXAMINE, $5, $1, $3, 0);
751 }
752 |
753     address '=' mode
754 {
755 	$$ = build(O_EXAMINE, $3, $1, nil, 0);
756 }
757 ;
758 address:
759     INT
760 {
761 	$$ = build(O_LCON, $1);
762 }
763 |
764     '.'
765 {
766 	$$ = build(O_LCON, (long) prtaddr);
767 }
768 |
769     '&' term
770 {
771 	$$ = amper($2);
772 }
773 |
774     address '+' address
775 {
776 	$$ = build(O_ADD, $1, $3);
777 }
778 |
779     address '-' address
780 {
781 	$$ = build(O_SUB, $1, $3);
782 }
783 |
784     address '*' address
785 {
786 	$$ = build(O_MUL, $1, $3);
787 }
788 |
789     '*' address %prec UNARYSIGN
790 {
791 	$$ = build(O_INDIR, $2);
792 }
793 |
794     '-' address %prec UNARYSIGN
795 {
796 	$$ = build(O_NEG, $2);
797 }
798 |
799     '(' exp ')'
800 {
801 	$$ = $2;
802 }
803 ;
804 term:
805     symbol
806 {
807 	$$ = $1;
808 }
809 |
810     term '.' name
811 {
812 	$$ = unrval(dot($1, $3));
813 }
814 |
815     term ARROW name
816 {
817 	$$ = unrval(dot($1, $3));
818 }
819 |
820     term '[' exp_list ']'
821 {
822 	$$ = unrval(subscript($1, $3));
823 }
824 ;
825 count:
826     /* empty */
827 {
828 	$$ = 1;
829 }
830 |
831     INT
832 {
833 	$$ = $1;
834 }
835 ;
836 mode:
837     name
838 {
839 	$$ = ident($1);
840 	curformat = $$;
841 }
842 |
843     /* empty */
844 {
845 	$$ = curformat;
846 }
847 ;
848 opt_cond:
849     /* empty */
850 {
851 	$$ = nil;
852 }
853 |
854     IF boolean_exp
855 {
856 	$$ = $2;
857 }
858 ;
859 exp_list:
860     exp
861 {
862 	$$ = build(O_COMMA, $1, nil);
863 }
864 |
865     exp ',' exp_list
866 {
867 	$$ = build(O_COMMA, $1, $3);
868 }
869 ;
870 exp:
871     symbol
872 {
873 	$$ = build(O_RVAL, $1);
874 }
875 |
876     exp '[' exp_list ']'
877 {
878 	$$ = subscript(unrval($1), $3);
879 }
880 |
881     exp '.' name
882 {
883 	$$ = dot($1, $3);
884 }
885 |
886     exp ARROW name
887 {
888 	$$ = dot($1, $3);
889 }
890 |
891     '*' exp %prec UNARYSIGN
892 {
893 	$$ = build(O_INDIR, $2);
894 }
895 |
896     exp '^' %prec UNARYSIGN
897 {
898 	$$ = build(O_INDIR, $1);
899 }
900 |
901     exp '\\' opt_qual_symbol
902 {
903 	$$ = build(O_TYPERENAME, $1, $3);
904 }
905 |
906     exp '\\' '&' opt_qual_symbol %prec '\\'
907 {
908 	$$ = renameptr($1, $4);
909 }
910 |
911     exp '(' opt_exp_list ')'
912 {
913 	$$ = build(O_CALL, unrval($1), $3);
914 }
915 |
916     constant
917 {
918 	$$ = $1;
919 }
920 |
921     '+' exp %prec UNARYSIGN
922 {
923 	$$ = $2;
924 }
925 |
926     '-' exp %prec UNARYSIGN
927 {
928 	$$ = build(O_NEG, $2);
929 }
930 |
931     '&' exp %prec UNARYSIGN
932 {
933 	$$ = amper($2);
934 }
935 |
936     exp '+' exp
937 {
938 	$$ = build(O_ADD, $1, $3);
939 }
940 |
941     exp '-' exp
942 {
943 	$$ = build(O_SUB, $1, $3);
944 }
945 |
946     exp '*' exp
947 {
948 	$$ = build(O_MUL, $1, $3);
949 }
950 |
951     exp '/' exp
952 {
953 	$$ = build(O_DIVF, $1, $3);
954 }
955 |
956     exp DIV exp
957 {
958 	$$ = build(O_DIV, $1, $3);
959 }
960 |
961     exp MOD exp
962 {
963 	$$ = build(O_MOD, $1, $3);
964 }
965 |
966     exp AND exp
967 {
968 	$$ = build(O_AND, $1, $3);
969 }
970 |
971     exp OR exp
972 {
973 	$$ = build(O_OR, $1, $3);
974 }
975 |
976     exp '<' exp
977 {
978 	$$ = build(O_LT, $1, $3);
979 }
980 |
981     exp '<' '=' exp
982 {
983 	$$ = build(O_LE, $1, $4);
984 }
985 |
986     exp '>' exp
987 {
988 	$$ = build(O_GT, $1, $3);
989 }
990 |
991     exp '>' '=' exp
992 {
993 	$$ = build(O_GE, $1, $4);
994 }
995 |
996     exp '=' exp
997 {
998 	$$ = build(O_EQ, $1, $3);
999 }
1000 |
1001     exp '=' '=' exp
1002 {
1003 	$$ = build(O_EQ, $1, $4);
1004 }
1005 |
1006     exp '<' '>' exp
1007 {
1008 	$$ = build(O_NE, $1, $4);
1009 }
1010 |
1011     exp '!' '=' exp
1012 {
1013 	$$ = build(O_NE, $1, $4);
1014 }
1015 |
1016     '(' exp ')'
1017 {
1018 	$$ = $2;
1019 }
1020 ;
1021 boolean_exp:
1022     exp
1023 {
1024 	chkboolean($1);
1025 	$$ = $1;
1026 }
1027 ;
1028 constant:
1029     INT
1030 {
1031 	$$ = build(O_LCON, $1);
1032 }
1033 |
1034     CHAR
1035 {
1036 	$$ = build(O_CCON, $1);
1037 }
1038 |
1039     REAL
1040 {
1041 	$$ = build(O_FCON, $1);
1042 }
1043 |
1044     STRING
1045 {
1046 	$$ = build(O_SCON, $1);
1047 }
1048 ;
1049 opt_qual_symbol:
1050     symbol
1051 {
1052 	$$ = $1;
1053 }
1054 |
1055     opt_qual_symbol '.' name
1056 {
1057 	$$ = dot($1, $3);
1058 }
1059 ;
1060 symbol:
1061     name
1062 {
1063 	$$ = findvar($1);
1064 	if ($$ == nil) {
1065 	    $$ = build(O_SYM, which($1));
1066 	}
1067 }
1068 |
1069     '.' name
1070 {
1071 	$$ = dot(build(O_SYM, program), $2);
1072 }
1073 ;
1074 name:
1075     NAME
1076 {
1077 	$$ = $1;
1078 }
1079 |
1080     keyword
1081 {
1082 	$$ = $1;
1083 }
1084 keyword:
1085     ALIAS | AND | ASSIGN | AT | CALL | CATCH | CONT | DEBUG | DELETE | DIV |
1086     DOWN | DUMP | EDIT | FILE | FUNC | GRIPE | HELP | IGNORE | IN | LIST |
1087     MOD | NEXT | NEXTI | NIL | NOT | OR | PRINT | PSYM | QUIT |
1088     RERUN | RETURN | RUN | SET | SH | SKIP | SOURCE | STATUS | STEP | STEPI |
1089     STOP | STOPI | TRACE | TRACEI | UNALIAS | UNSET | UP | USE |
1090     WHATIS | WHEN | WHERE | WHEREIS | WHICH
1091 ;
1092