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