]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/rc/syn.y
051c9e88ed830c2ac58a656455217656b8c9fd16
[plan9front.git] / sys / src / cmd / rc / syn.y
1 %term FOR IN WHILE IF NOT TWIDDLE BANG SUBSHELL SWITCH FN
2 %term WORD REDIR DUP PIPE SUB
3 %term SIMPLE ARGLIST WORDS BRACE PAREN PCMD PIPEFD /* not used in syntax */
4 /* operator priorities -- lowest first */
5 %left IF WHILE FOR SWITCH ')' NOT
6 %left ANDAND OROR
7 %left BANG SUBSHELL
8 %left PIPE
9 %left '^'
10 %right '$' COUNT '"'
11 %left SUB
12 %{
13 #include "rc.h"
14 #include "fns.h"
15 %}
16 %union{
17         struct tree *tree;
18 };
19 %type<tree> line paren brace body cmdsa cmdsan assign epilog redir
20 %type<tree> cmd simple first word comword keyword words
21 %type<tree> NOT FOR IN WHILE IF TWIDDLE BANG SUBSHELL SWITCH FN
22 %type<tree> WORD REDIR DUP PIPE
23 %%
24 rc:                             { return 1;}
25 |       line '\n'               {return !compile($1);}
26 line:   cmd
27 |       cmdsa line              {$$=tree2(';', $1, $2);}
28 body:   cmd
29 |       cmdsan body             {$$=tree2(';', $1, $2);}
30 cmdsa:  cmd ';'
31 |       cmd '&'                 {$$=tree1('&', $1);}
32 cmdsan: cmdsa
33 |       cmd '\n'
34 brace:  '{' body '}'            {$$=tree1(BRACE, $2);}
35 paren:  '(' body ')'            {$$=tree1(PCMD, $2);}
36 assign: first '=' word          {$$=tree2('=', $1, $3);}
37 epilog:                         {$$=0;}
38 |       redir epilog            {$$=mung2($1, $1->child[0], $2);}
39 redir:  REDIR word              {$$=mung1($1, $1->rtype==HERE?heredoc($2):$2);}
40 |       DUP
41 cmd:                            {$$=0;}
42 |       brace epilog            {$$=epimung($1, $2);}
43 |       IF paren {skipnl();} cmd
44                                 {$$=mung2($1, $2, $4);}
45 |       IF NOT {skipnl();} cmd  {$$=mung1($2, $4);}
46 |       FOR '(' word IN words ')' {skipnl();} cmd
47         /*
48          * if ``words'' is nil, we need a tree element to distinguish between 
49          * for(i in ) and for(i), the former being a loop over the empty set
50          * and the latter being the implicit argument loop.  so if $5 is nil
51          * (the empty set), we represent it as "()".  don't parenthesize non-nil
52          * functions, to avoid growing parentheses every time we reread the
53          * definition.
54          */
55                                 {$$=mung3($1, $3, $5 ? $5 : tree1(PAREN, $5), $8);}
56 |       FOR '(' word ')' {skipnl();} cmd
57                                 {$$=mung3($1, $3, (struct tree *)0, $6);}
58 |       WHILE paren {skipnl();} cmd
59                                 {$$=mung2($1, $2, $4);}
60 |       SWITCH word {skipnl();} brace
61                                 {$$=tree2(SWITCH, $2, $4);}
62 |       simple                  {$$=simplemung($1);}
63 |       TWIDDLE word words      {$$=mung2($1, $2, $3);}
64 |       cmd ANDAND cmd          {$$=tree2(ANDAND, $1, $3);}
65 |       cmd OROR cmd            {$$=tree2(OROR, $1, $3);}
66 |       cmd PIPE cmd            {$$=mung2($2, $1, $3);}
67 |       redir cmd  %prec BANG   {$$=mung2($1, $1->child[0], $2);}
68 |       assign cmd %prec BANG   {$$=mung3($1, $1->child[0], $1->child[1], $2);}
69 |       BANG cmd                {$$=mung1($1, $2);}
70 |       SUBSHELL cmd            {$$=mung1($1, $2);}
71 |       FN words brace          {$$=tree2(FN, $2, $3);}
72 |       FN words                {$$=tree1(FN, $2);}
73 simple: first
74 |       simple word             {$$=tree2(ARGLIST, $1, $2);}
75 |       simple redir            {$$=tree2(ARGLIST, $1, $2);}
76 first:  comword 
77 |       first '^' word          {$$=tree2('^', $1, $3);}
78 word:   keyword                 {lastword=1; $1->type=WORD;}
79 |       comword
80 |       word '^' word           {$$=tree2('^', $1, $3);}
81 comword: '$' word               {$$=tree1('$', $2);}
82 |       '$' word SUB words ')'  {$$=tree2(SUB, $2, $4);}
83 |       '"' word                {$$=tree1('"', $2);}
84 |       COUNT word              {$$=tree1(COUNT, $2);}
85 |       WORD
86 |       '`' brace               {$$=tree2('`', (struct tree*)0, $2);}
87 |       '`' word brace          {$$=tree2('`', $2, $3);}
88 |       '(' words ')'           {$$=tree1(PAREN, $2);}
89 |       REDIR brace             {$$=mung1($1, $2); $$->type=PIPEFD;}
90 keyword: FOR|IN|WHILE|IF|NOT|TWIDDLE|BANG|SUBSHELL|SWITCH|FN
91 words:                          {$$=(struct tree*)0;}
92 |       words word              {$$=tree2(WORDS, $1, $2);}