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