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