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