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