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