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