15475Slinton %{
248102Sbostic /*-
3*62130Sbostic * Copyright (c) 1982, 1993
4*62130Sbostic * The Regents of the University of California. All rights reserved.
548102Sbostic *
648102Sbostic * %sccs.include.redist.c%
722760Smckusick */
85475Slinton
922760Smckusick #ifndef lint
10*62130Sbostic static char sccsid[] = "@(#)grammar.y 8.1 (Berkeley) 06/06/93";
1148102Sbostic #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
yyerror(s)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
gobble()5575475Slinton gobble()
5585475Slinton {
5595475Slinton register int t;
5605475Slinton
5615475Slinton if (!nlflag) {
5625475Slinton while ((t = yylex()) != '\n' && t != 0);
5635475Slinton }
5645475Slinton }
565