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