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