diff options
| author | tim <tim> | 1997-05-14 15:30:41 +0000 |
|---|---|---|
| committer | Toby Goodwin <toby@paccrat.org> | 2015-05-16 21:23:00 +0100 |
| commit | 53cf1b1c1c3f0c2b5067afccc2976b99a574a089 (patch) | |
| tree | a31f167c3779362e29ab377d662052b6257253a8 /parse.y | |
| parent | b87bfedf65c289bf0ee5338c9e10492b70b1e8e0 (diff) | |
Initial revision
Diffstat (limited to 'parse.y')
| -rw-r--r-- | parse.y | 174 |
1 files changed, 0 insertions, 174 deletions
diff --git a/parse.y b/parse.y deleted file mode 100644 index f1f5526..0000000 --- a/parse.y +++ /dev/null @@ -1,174 +0,0 @@ -/* parse.y */ - -/* - * Adapted from rc grammar, v10 manuals, volume 2. - */ - -%{ -#include "rc.h" -#ifndef lint -#define lint /* hush up gcc -Wall, leave out the dumb sccsid's. */ -#endif -static Node *star, *nolist; -Node *parsetree; /* not using yylval because bison declares it as an auto */ -%} - -%token ANDAND BACKBACK BANG CASE COUNT DUP ELSE END FLAT FN FOR IF IN -%token OROR PIPE REDIR SREDIR SUB SUBSHELL SWITCH TWIDDLE WHILE WORD HUH - -%left WHILE ')' ELSE -%left ANDAND OROR '\n' -%left BANG SUBSHELL -%left PIPE -%right '$' -%left SUB -/* -*/ - -%union { - struct Node *node; - struct Redir redir; - struct Pipe pipe; - struct Dup dup; - struct Word word; - char *keyword; -} - -%type <redir> REDIR SREDIR -%type <pipe> PIPE -%type <dup> DUP -%type <word> WORD -%type <keyword> keyword -%type <node> assign body brace case cbody cmd cmdsa cmdsan comword epilog - first line nlwords paren redir sword simple iftail word words - -%start rc - -%% - -rc : line end { parsetree = $1; YYACCEPT; } - | error end { yyerrok; parsetree = NULL; YYABORT; } - -/* an rc line may end in end-of-file as well as newline, e.g., rc -c 'ls' */ -end : END /* EOF */ { if (!heredoc(1)) YYABORT; } /* flag error if there is a heredoc in the queue */ - | '\n' { if (!heredoc(0)) YYABORT; } /* get heredoc on \n */ - -/* a cmdsa is a command followed by ampersand or newline (used in "line" and "body") */ -cmdsa : cmd ';' - | cmd '&' { $$ = ($1 != NULL ? mk(nNowait,$1) : $1); } - -/* a line is a single command, or a command terminated by ; or & followed by a line (recursive) */ -line : cmd - | cmdsa line { $$ = ($1 != NULL ? mk(nBody,$1,$2) : $2); } - -/* a body is like a line, only commands may also be terminated by newline */ -body : cmd - | cmdsan body { $$ = ($1 == NULL ? $2 : $2 == NULL ? $1 : mk(nBody,$1,$2)); } - -cmdsan : cmdsa - | cmd '\n' { $$ = $1; if (!heredoc(0)) YYABORT; } /* get h.d. on \n */ - -brace : '{' body '}' { $$ = $2; } - -paren : '(' body ')' { $$ = $2; } - -assign : first '=' word { $$ = mk(nAssign,$1,$3); } - -epilog : { $$ = NULL; } - | redir epilog { $$ = mk(nEpilog,$1,$2); } - -/* a redirection is a dup (e.g., >[1=2]) or a file redirection. (e.g., > /dev/null) */ -redir : DUP { $$ = mk(nDup,$1.type,$1.left,$1.right); } - | REDIR word { $$ = mk(nRedir,$1.type,$1.fd,$2); - if ($1.type == rHeredoc && !qdoc($2, $$)) YYABORT; /* queue heredocs up */ - } - | SREDIR word { $$ = mk(nRedir,$1.type,$1.fd,$2); - if ($1.type == rHeredoc && !qdoc($2, $$)) YYABORT; /* queue heredocs up */ - } - -case : CASE words ';' { $$ = mk(nCase, $2); } - | CASE words '\n' { $$ = mk(nCase, $2); } - -cbody : cmd { $$ = mk(nCbody, $1, NULL); } - | case cbody { $$ = mk(nCbody, $1, $2); } - | cmdsan cbody { $$ = mk(nCbody, $1, $2); } - -iftail : cmd %prec ELSE - | brace ELSE optnl cmd { $$ = mk(nElse,$1,$4); } - -cmd : /* empty */ %prec WHILE { $$ = NULL; } - | simple - | brace epilog { $$ = mk(nBrace,$1,$2); } - | IF paren optnl iftail { $$ = mk(nIf,$2,$4); } - | FOR '(' word IN words ')' optnl cmd { $$ = mk(nForin,$3,$5,$8); } - | FOR '(' word ')' optnl cmd { $$ = mk(nForin,$3,star,$6); } - | WHILE paren optnl cmd { $$ = mk(nWhile,$2,$4); } - | SWITCH '(' word ')' optnl '{' cbody '}' { $$ = mk(nSwitch,$3,$7); } - | TWIDDLE optcaret word words { $$ = mk(nMatch,$3,$4); } - | cmd ANDAND optnl cmd { $$ = mk(nAndalso,$1,$4); } - | cmd OROR optnl cmd { $$ = mk(nOrelse,$1,$4); } - | cmd PIPE optnl cmd { $$ = mk(nPipe,$2.left,$2.right,$1,$4); } - | redir cmd %prec BANG { $$ = ($2 != NULL ? mk(nPre,$1,$2) : $1); } - | assign cmd %prec BANG { $$ = ($2 != NULL ? mk(nPre,$1,$2) : $1); } - | BANG optcaret cmd { $$ = mk(nBang,$3); } - | SUBSHELL optcaret cmd { $$ = mk(nSubshell,$3); } - | FN words brace { $$ = mk(nNewfn,$2,$3); } - | FN words { $$ = mk(nRmfn,$2); } - -optcaret : /* empty */ - | '^' - -simple : first - | simple word { $$ = ($2 != NULL ? mk(nArgs,$1,$2) : $1); } - | simple redir { $$ = mk(nArgs,$1,$2); } - -first : comword - | first '^' sword { $$ = mk(nConcat,$1,$3); } - -sword : comword - | keyword { $$ = mk(nWord,$1, NULL); } - -word : sword - | word '^' sword { $$ = mk(nConcat,$1,$3); } - -comword : '$' sword { $$ = mk(nVar,$2); } - | '$' sword SUB words ')' { $$ = mk(nVarsub,$2,$4); } - | COUNT sword { $$ = mk(nCount,$2); } - | FLAT sword { $$ = mk(nFlat, $2); } - | '`' sword { $$ = mk(nBackq,nolist,$2); } - | '`' brace { $$ = mk(nBackq,nolist,$2); } - | BACKBACK word brace { $$ = mk(nBackq,$2,$3); } - | BACKBACK word sword { $$ = mk(nBackq,$2,$3); } - | '(' nlwords ')' { $$ = $2; } - | REDIR brace { $$ = mk(nNmpipe,$1.type,$1.fd,$2); } - | WORD { $$ = ($1.w[0] == '\'') ? mk(nQword, $1.w+1, NULL) : mk(nWord,$1.w, $1.m); } - -keyword : FOR { $$ = "for"; } - | IN { $$ = "in"; } - | WHILE { $$ = "while"; } - | IF { $$ = "if"; } - | SWITCH { $$ = "switch"; } - | FN { $$ = "fn"; } - | ELSE { $$ = "else"; } - | CASE { $$ = "case"; } - | TWIDDLE { $$ = "~"; } - | BANG { $$ = "!"; } - | SUBSHELL { $$ = "@"; } - -words : { $$ = NULL; } - | words word { $$ = ($1 != NULL ? ($2 != NULL ? mk(nLappend,$1,$2) : $1) : $2); } - -nlwords : { $$ = NULL; } - | nlwords '\n' - | nlwords word { $$ = ($1 != NULL ? ($2 != NULL ? mk(nLappend,$1,$2) : $1) : $2); } - -optnl : /* empty */ - | optnl '\n' - -%% - -void initparse() { - star = treecpy(mk(nVar,mk(nWord,"*",NULL)), ealloc); - nolist = treecpy(mk(nVar,mk(nWord,"ifs",NULL)), ealloc); -} - |