15475Slinton %{ 25475Slinton /* Copyright (c) 1982 Regents of the University of California */ 35475Slinton 4*5588Slinton static char sccsid[] = "@(#)grammar.y 1.2 01/20/82"; 55475Slinton 65475Slinton /* 75475Slinton * yacc grammar for debugger commands 85475Slinton */ 95475Slinton 105475Slinton #include "defs.h" 115475Slinton #include "command.h" 125475Slinton #include "sym.h" 135475Slinton #include "symtab.h" 145475Slinton #include "tree.h" 155475Slinton #include "process.h" 165475Slinton #include "source.h" 175475Slinton 185475Slinton %} 195475Slinton 205475Slinton %term ALIAS ASSIGN CALL CHFILE 215475Slinton %term CONT DUMP EDIT 225475Slinton %term GRIPE HELP LIST NEXT 235475Slinton %term QUIT REMAKE PRINT 245475Slinton %term RUN SH SOURCE 255475Slinton %term STATUS STEP 265475Slinton %term STOP STOPI TRACE TRACEI 275475Slinton %term DELETE 285475Slinton %term WHATIS WHICH WHERE 295475Slinton %term XI XD 305475Slinton 315475Slinton %term AT IN IF 325475Slinton %term FILENAME 335475Slinton %term INT REAL NAME STRING 345475Slinton %term DIV MOD 355475Slinton %term AND OR NOT 365475Slinton 375475Slinton %binary '<' '=' '>' IN 385475Slinton %left '+' '-' OR '|' 395475Slinton %left UNARYSIGN 405475Slinton %left '*' '/' DIV MOD AND '&' 415475Slinton %left NOT 425475Slinton 435475Slinton %union { 445475Slinton SYM *y_sym; 455475Slinton NODE *y_node; 465475Slinton int y_int; 475475Slinton OP y_op; 485475Slinton long y_long; 495475Slinton double y_real; 505475Slinton char *y_string; 515475Slinton BOOLEAN y_bool; 525475Slinton }; 535475Slinton 545475Slinton %type <y_int> trace TRACE TRACEI stop STOP STOPI 555475Slinton %type <y_long> INT 565475Slinton %type <y_real> REAL 575475Slinton %type <y_op> addop mulop relop 585475Slinton %type <y_string> STRING FILENAME SH opt_filename 595475Slinton %type <y_sym> NAME 605475Slinton %type <y_node> command rcommand what where opt_arglist opt_cond 615475Slinton %type <y_node> exp_list exp boolean_exp term constant 625475Slinton %type <y_node> line_list line_number address_list 635475Slinton %% 645475Slinton input: 655475Slinton input command_nl 665475Slinton { 675475Slinton prompt(); 685475Slinton } 695475Slinton | /* empty */ 705475Slinton ; 715475Slinton command_nl: 725475Slinton command_line '\n' 735475Slinton | '\n' 745475Slinton ; 755475Slinton 765475Slinton /* 775475Slinton * There are two kinds of commands, those that can be redirected 785475Slinton * and those that can't. 795475Slinton */ 805475Slinton 815475Slinton command_line: 825475Slinton command 835475Slinton { 845475Slinton eval($1); 855475Slinton } 865475Slinton | rcommand 875475Slinton { 885475Slinton eval($1); 895475Slinton } 905475Slinton | rcommand '>' FILENAME 915475Slinton { 925475Slinton setout($3); 935475Slinton eval($1); 945475Slinton unsetout(); 955475Slinton } 965475Slinton | SH 975475Slinton { 985475Slinton shell($1); 995475Slinton } 1005475Slinton | run args 1015475Slinton { 1025475Slinton run(); 1035475Slinton } 1045475Slinton ; 1055475Slinton run: 1065475Slinton RUN 1075475Slinton { 1085475Slinton arginit(); 1095475Slinton } 1105475Slinton ; 1115475Slinton args: 1125475Slinton arg args 1135475Slinton | /* empty */ 1145475Slinton ; 1155475Slinton arg: 1165475Slinton FILENAME 1175475Slinton { 1185475Slinton newarg($1); 1195475Slinton } 1205475Slinton | '<' FILENAME 1215475Slinton { 1225475Slinton inarg($2); 1235475Slinton } 1245475Slinton | '>' FILENAME 1255475Slinton { 1265475Slinton outarg($2); 1275475Slinton } 1285475Slinton ; 1295475Slinton command: 1305475Slinton ASSIGN term exp 1315475Slinton { 1325475Slinton $$ = build(O_ASSIGN, $2, $3); 1335475Slinton } 1345475Slinton | CHFILE opt_filename 1355475Slinton { 1365475Slinton $$ = build(O_CHFILE, $2); 1375475Slinton } 1385475Slinton | CONT 1395475Slinton { 1405475Slinton $$ = build(O_CONT); 1415475Slinton } 1425475Slinton | LIST line_list 1435475Slinton { 1445475Slinton $$ = build(O_LIST, $2); 1455475Slinton } 1465475Slinton | LIST NAME 1475475Slinton { 1485475Slinton $$ = build(O_LIST, build(O_NAME, $2)); 1495475Slinton } 1505475Slinton | NEXT 1515475Slinton { 1525475Slinton $$ = build(O_NEXT); 1535475Slinton } 1545475Slinton | PRINT exp_list 1555475Slinton { 1565475Slinton $$ = build(O_PRINT, $2); 1575475Slinton } 1585475Slinton | QUIT 1595475Slinton { 160*5588Slinton quit(0); 1615475Slinton } 1625475Slinton | STEP 1635475Slinton { 1645475Slinton $$ = build(O_STEP); 1655475Slinton } 1665475Slinton | stop where opt_cond 1675475Slinton { 1685475Slinton $$ = build($1, NIL, $2, $3); 1695475Slinton } 1705475Slinton | stop what opt_cond 1715475Slinton { 1725475Slinton $$ = build($1, $2, NIL, $3); 1735475Slinton } 1745475Slinton | stop IF boolean_exp 1755475Slinton { 1765475Slinton $$ = build($1, NIL, NIL, $3); 1775475Slinton } 1785475Slinton | trace what where opt_cond 1795475Slinton { 1805475Slinton $$ = build($1, $2, $3, $4); 1815475Slinton } 1825475Slinton | trace where opt_cond 1835475Slinton { 1845475Slinton $$ = build($1, NIL, $2, $3); 1855475Slinton } 1865475Slinton | trace what opt_cond 1875475Slinton { 1885475Slinton $$ = build($1, $2, NIL, $3); 1895475Slinton } 1905475Slinton | trace opt_cond 1915475Slinton { 1925475Slinton $$ = build($1, NIL, NIL, $2); 1935475Slinton } 1945475Slinton | DELETE INT 1955475Slinton { 1965475Slinton $$ = build(O_DELETE, $2); 1975475Slinton } 1985475Slinton | WHATIS term 1995475Slinton { 2005475Slinton $$ = build(O_WHATIS, $2); 2015475Slinton } 2025475Slinton | WHICH NAME 2035475Slinton { 2045475Slinton $$ = build(O_WHICH, $2); 2055475Slinton } 2065475Slinton | WHERE 2075475Slinton { 2085475Slinton $$ = build(O_WHERE); 2095475Slinton } 2105475Slinton | XI address_list 2115475Slinton { 2125475Slinton $$ = build(O_XI, $2); 2135475Slinton } 2145475Slinton | XD address_list 2155475Slinton { 2165475Slinton $$ = build(O_XD, $2); 2175475Slinton } 2185475Slinton ; 2195475Slinton rcommand: 2205475Slinton ALIAS FILENAME opt_filename 2215475Slinton { 2225475Slinton $$ = build(O_ALIAS, $2, $3); 2235475Slinton } 2245475Slinton | ALIAS 2255475Slinton { 2265475Slinton $$ = build(O_ALIAS, NIL, NIL); 2275475Slinton } 2285475Slinton | CALL term opt_arglist 2295475Slinton { 2305475Slinton $$ = build(O_CALL, $2, $3); 2315475Slinton } 2325475Slinton | EDIT opt_filename 2335475Slinton { 2345475Slinton $$ = build(O_EDIT, $2); 2355475Slinton } 2365475Slinton | DUMP 2375475Slinton { 2385475Slinton $$ = build(O_DUMP); 2395475Slinton } 2405475Slinton | GRIPE 2415475Slinton { 2425475Slinton $$ = build(O_GRIPE); 2435475Slinton } 2445475Slinton | HELP 2455475Slinton { 2465475Slinton $$ = build(O_HELP); 2475475Slinton } 2485475Slinton | REMAKE 2495475Slinton { 2505475Slinton $$ = build(O_REMAKE); 2515475Slinton } 2525475Slinton | SOURCE FILENAME 2535475Slinton { 2545475Slinton $$ = build(O_SOURCE, $2); 2555475Slinton } 2565475Slinton | STATUS 2575475Slinton { 2585475Slinton $$ = build(O_STATUS); 2595475Slinton } 2605475Slinton ; 2615475Slinton trace: 2625475Slinton TRACE 2635475Slinton { 2645475Slinton $$ = O_TRACE; 2655475Slinton } 2665475Slinton | TRACEI 2675475Slinton { 2685475Slinton $$ = O_TRACEI; 2695475Slinton } 2705475Slinton ; 2715475Slinton stop: 2725475Slinton STOP 2735475Slinton { 2745475Slinton $$ = O_STOP; 2755475Slinton } 2765475Slinton | STOPI 2775475Slinton { 2785475Slinton $$ = O_STOPI; 2795475Slinton } 2805475Slinton ; 2815475Slinton what: 2825475Slinton exp 2835475Slinton | FILENAME line_number 2845475Slinton { 2855475Slinton $$ = build(O_QLINE, $1, $2); 2865475Slinton } 2875475Slinton ; 2885475Slinton where: 2895475Slinton IN term 2905475Slinton { 2915475Slinton $$ = $2; 2925475Slinton } 2935475Slinton | AT line_number 2945475Slinton { 2955475Slinton $$ = build(O_QLINE, cursource, $2); 2965475Slinton } 2975475Slinton | AT FILENAME line_number 2985475Slinton { 2995475Slinton $$ = build(O_QLINE, $2, $3); 3005475Slinton } 3015475Slinton ; 3025475Slinton opt_filename: 3035475Slinton /* empty */ 3045475Slinton { 3055475Slinton $$ = NIL; 3065475Slinton } 3075475Slinton | FILENAME 3085475Slinton ; 3095475Slinton opt_arglist: 3105475Slinton /* empty */ 3115475Slinton { 3125475Slinton $$ = NIL; 3135475Slinton } 3145475Slinton | '(' exp_list ')' 3155475Slinton { 3165475Slinton $$ = $2; 3175475Slinton } 3185475Slinton ; 3195475Slinton line_list: 3205475Slinton /* empty */ 3215475Slinton { 3225475Slinton NODE *first, *last; 3235475Slinton 3245475Slinton first = build(O_LCON, (long) 1); 3255475Slinton last = build(O_LCON, (long) lastlinenum); 3265475Slinton $$ = build(O_COMMA, first, last); 3275475Slinton } 3285475Slinton | line_number 3295475Slinton { 3305475Slinton $$ = build(O_COMMA, $1, $1); 3315475Slinton } 3325475Slinton | line_number ',' line_number 3335475Slinton { 3345475Slinton $$ = build(O_COMMA, $1, $3); 3355475Slinton } 3365475Slinton ; 3375475Slinton line_number: 3385475Slinton INT 3395475Slinton { 3405475Slinton $$ = build(O_LCON, $1); 3415475Slinton } 3425475Slinton | '$' 3435475Slinton { 3445475Slinton $$ = build(O_LCON, (long) lastlinenum); 3455475Slinton } 3465475Slinton ; 3475475Slinton address_list: 3485475Slinton exp 3495475Slinton { 3505475Slinton $$ = build(O_COMMA, $1, $1); 3515475Slinton } 3525475Slinton | exp ',' exp 3535475Slinton { 3545475Slinton $$ = build(O_COMMA, $1, $3); 3555475Slinton } 3565475Slinton ; 3575475Slinton opt_cond: 3585475Slinton /* empty */ 3595475Slinton { 3605475Slinton $$ = NIL; 3615475Slinton } 3625475Slinton | IF boolean_exp 3635475Slinton { 3645475Slinton $$ = $2; 3655475Slinton } 3665475Slinton ; 3675475Slinton exp_list: 3685475Slinton exp 3695475Slinton { 3705475Slinton $$ = build(O_COMMA, $1, NIL); 3715475Slinton } 3725475Slinton | exp ',' exp_list 3735475Slinton { 3745475Slinton $$ = build(O_COMMA, $1, $3); 3755475Slinton } 3765475Slinton ; 3775475Slinton exp: 3785475Slinton term 3795475Slinton { 3805475Slinton $$ = build(O_RVAL, $1); 3815475Slinton } 3825475Slinton | term '(' exp_list ')' 3835475Slinton { 3845475Slinton $$ = build(O_CALL, $1, $3); 3855475Slinton } 3865475Slinton | constant 3875475Slinton | '+' exp %prec UNARYSIGN 3885475Slinton { 3895475Slinton $$ = $2; 3905475Slinton } 3915475Slinton | '-' exp %prec UNARYSIGN 3925475Slinton { 3935475Slinton $$ = build(O_NEG, $2); 3945475Slinton } 3955475Slinton | exp addop exp %prec '+' 3965475Slinton { 3975475Slinton $$ = build($2, $1, $3); 3985475Slinton } 3995475Slinton | exp mulop exp %prec '*' 4005475Slinton { 4015475Slinton $$ = build($2, $1, $3); 4025475Slinton } 4035475Slinton | exp relop exp %prec '<' 4045475Slinton { 4055475Slinton $$ = build($2, $1, $3); 4065475Slinton } 4075475Slinton | '(' exp ')' 4085475Slinton { 4095475Slinton $$ = $2; 4105475Slinton } 4115475Slinton ; 4125475Slinton boolean_exp: 4135475Slinton exp 4145475Slinton { 4155475Slinton chkboolean($$ = $1); 4165475Slinton } 4175475Slinton ; 4185475Slinton term: 4195475Slinton NAME 4205475Slinton { 4215475Slinton $$ = build(O_NAME, $1); 4225475Slinton } 4235475Slinton | AT 4245475Slinton { 4255475Slinton SYM *s; 4265475Slinton 4275475Slinton s = st_lookup(symtab, "at"); 4285475Slinton if (s == NIL) { 4295475Slinton error("\"at\" is not defined"); 4305475Slinton } 4315475Slinton $$ = build(O_NAME, s); 4325475Slinton } 4335475Slinton | term '[' exp_list ']' 4345475Slinton { 4355475Slinton $$ = subscript($1, $3); 4365475Slinton } 4375475Slinton | term '.' NAME 4385475Slinton { 4395475Slinton $$ = dot($1, $3); 4405475Slinton } 4415475Slinton | term '^' 4425475Slinton { 4435475Slinton $$ = build(O_INDIR, $1); 4445475Slinton } 4455475Slinton ; 4465475Slinton constant: 4475475Slinton INT 4485475Slinton { 4495475Slinton $$ = build(O_LCON, $1); 4505475Slinton } 4515475Slinton | REAL 4525475Slinton { 4535475Slinton $$ = build(O_FCON, $1); 4545475Slinton } 4555475Slinton | STRING 4565475Slinton { 4575475Slinton $$ = build(O_SCON, $1); 4585475Slinton } 4595475Slinton ; 4605475Slinton addop: 4615475Slinton '+' 4625475Slinton { 4635475Slinton $$ = O_ADD; 4645475Slinton } 4655475Slinton | '-' 4665475Slinton { 4675475Slinton $$ = O_SUB; 4685475Slinton } 4695475Slinton | OR 4705475Slinton { 4715475Slinton $$ = O_OR; 4725475Slinton } 4735475Slinton | '|' 4745475Slinton { 4755475Slinton $$ = O_OR; 4765475Slinton } 4775475Slinton ; 4785475Slinton mulop: 4795475Slinton '*' 4805475Slinton { 4815475Slinton $$ = O_MUL; 4825475Slinton } 4835475Slinton | '/' 4845475Slinton { 4855475Slinton $$ = O_DIVF; 4865475Slinton } 4875475Slinton | DIV 4885475Slinton { 4895475Slinton $$ = O_DIV; 4905475Slinton } 4915475Slinton | MOD 4925475Slinton { 4935475Slinton $$ = O_MOD; 4945475Slinton } 4955475Slinton | AND 4965475Slinton { 4975475Slinton $$ = O_AND; 4985475Slinton } 4995475Slinton | '&' 5005475Slinton { 5015475Slinton $$ = O_AND; 5025475Slinton } 5035475Slinton ; 5045475Slinton relop: 5055475Slinton '<' 5065475Slinton { 5075475Slinton $$ = O_LT; 5085475Slinton } 5095475Slinton | '<' '=' 5105475Slinton { 5115475Slinton $$ = O_LE; 5125475Slinton } 5135475Slinton | '>' 5145475Slinton { 5155475Slinton $$ = O_GT; 5165475Slinton } 5175475Slinton | '>' '=' 5185475Slinton { 5195475Slinton $$ = O_GE; 5205475Slinton } 5215475Slinton | '=' 5225475Slinton { 5235475Slinton $$ = O_EQ; 5245475Slinton } 5255475Slinton | '<' '>' 5265475Slinton { 5275475Slinton $$ = O_NE; 5285475Slinton } 5295475Slinton ; 5305475Slinton %% 5315475Slinton 5325475Slinton /* 5335475Slinton * parser error handling 5345475Slinton */ 5355475Slinton 5365475Slinton yyerror(s) 5375475Slinton char *s; 5385475Slinton { 5395475Slinton if (strcmp(s, "syntax error") == 0) { 5405475Slinton error("bad command syntax"); 5415475Slinton } else { 5425475Slinton error(s); 5435475Slinton } 5445475Slinton } 5455475Slinton 5465475Slinton /* 5475475Slinton * In recovering from an error we gobble input up to a newline. 5485475Slinton */ 5495475Slinton 5505475Slinton gobble() 5515475Slinton { 5525475Slinton register int t; 5535475Slinton 5545475Slinton if (!nlflag) { 5555475Slinton while ((t = yylex()) != '\n' && t != 0); 5565475Slinton } 5575475Slinton } 558