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