%term FOR IN WHILE IF NOT TWIDDLE BANG SUBSHELL SWITCH FN
%term WORD REDIR DUP PIPE SUB
%term SIMPLE ARGLIST WORDS BRACE PAREN PCMD PIPEFD /* not used in syntax */
/* operator priorities -- lowest first */
%left IF WHILE FOR SWITCH ')' NOT
%left ANDAND OROR
%left BANG SUBSHELL
%left PIPE
%left '^'
%right '$' COUNT '\"'
%left SUB
%{
#include "rc.h"
#include "fns.h"
%}
%union{
	struct tree *tree;
};
%type<tree> line paren brace body cmdsa cmdsan assign epilog redir
%type<tree> cmd simple first word comword keyword words
%type<tree> NOT FOR IN WHILE IF TWIDDLE BANG SUBSHELL SWITCH FN
%type<tree> WORD REDIR DUP PIPE
%%
rc:				{ return 1;}
|	line '\n'		{return !compile($1);}
line:	cmd
|	cmdsa line		{$$=tree2(';', $1, $2);}
body:	cmd
|	cmdsan body		{$$=tree2(';', $1, $2);}
cmdsa:	cmd ';'
|	cmd '&'			{$$=tree1('&', $1);}
cmdsan:	cmdsa
|	cmd '\n'
brace:	'{' body '}'		{$$=tree1(BRACE, $2);}
paren:	'(' body ')'		{$$=tree1(PCMD, $2);}
assign:	first '=' word		{$$=tree2('=', $1, $3);}
epilog:				{$$=0;}
|	redir epilog		{$$=mung2($1, $1->child[0], $2);}
redir:	REDIR word		{$$=mung1($1, $1->rtype==HERE?heredoc($2):$2);}
|	DUP
cmd:				{$$=0;}
|	brace epilog		{$$=epimung($1, $2);}
|	IF paren {skipnl();} cmd
				{$$=mung2($1, $2, $4);}
|	IF NOT {skipnl();} cmd	{$$=mung1($2, $4);}
|	FOR '(' word IN words ')' {skipnl();} cmd
	/*
	 * if ``words'' is nil, we need a tree element to distinguish between 
	 * for(i in ) and for(i), the former being a loop over the empty set
	 * and the latter being the implicit argument loop.  so if $5 is nil
	 * (the empty set), we represent it as "()".  don't parenthesize non-nil
	 * functions, to avoid growing parentheses every time we reread the
	 * definition.
	 */
				{$$=mung3($1, $3, $5 ? $5 : tree1(PAREN, $5), $8);}
|	FOR '(' word ')' {skipnl();} cmd
				{$$=mung3($1, $3, (struct tree *)0, $6);}
|	WHILE paren {skipnl();} cmd
				{$$=mung2($1, $2, $4);}
|	SWITCH word {skipnl();} brace
				{$$=tree2(SWITCH, $2, $4);}
|	simple			{$$=simplemung($1);}
|	TWIDDLE word words	{$$=mung2($1, $2, $3);}
|	cmd ANDAND cmd		{$$=tree2(ANDAND, $1, $3);}
|	cmd OROR cmd		{$$=tree2(OROR, $1, $3);}
|	cmd PIPE cmd		{$$=mung2($2, $1, $3);}
|	redir cmd  %prec BANG	{$$=mung2($1, $1->child[0], $2);}
|	assign cmd %prec BANG	{$$=mung3($1, $1->child[0], $1->child[1], $2);}
|	BANG cmd		{$$=mung1($1, $2);}
|	SUBSHELL cmd		{$$=mung1($1, $2);}
|	FN words brace		{$$=tree2(FN, $2, $3);}
|	FN words		{$$=tree1(FN, $2);}
simple:	first
|	simple word		{$$=tree2(ARGLIST, $1, $2);}
|	simple redir		{$$=tree2(ARGLIST, $1, $2);}
first:	comword	
|	first '^' word		{$$=tree2('^', $1, $3);}
word:	keyword			{lastword=1; $1->type=WORD;}
|	comword
|	word '^' word		{$$=tree2('^', $1, $3);}
comword: '$' word		{$$=tree1('$', $2);}
|	'$' word SUB words ')'	{$$=tree2(SUB, $2, $4);}
|	'"' word		{$$=tree1('"', $2);}
|	COUNT word		{$$=tree1(COUNT, $2);}
|	WORD
|	'`' brace		{$$=tree1('`', $2);}
|	'(' words ')'		{$$=tree1(PAREN, $2);}
|	REDIR brace		{$$=mung1($1, $2); $$->type=PIPEFD;}
keyword: FOR|IN|WHILE|IF|NOT|TWIDDLE|BANG|SUBSHELL|SWITCH|FN
words:				{$$=(struct tree*)0;}
|	words word		{$$=tree2(WORDS, $1, $2);}
