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