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