From bf03074e346b004659196b6c17eee04dbffd3ac2 Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Fri, 15 Oct 2021 16:18:02 -0700 Subject: feat(rc): working prototype of input->compile->print loop --- sys/cmd/rc/syntax.y | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 sys/cmd/rc/syntax.y (limited to 'sys/cmd/rc/syntax.y') diff --git a/sys/cmd/rc/syntax.y b/sys/cmd/rc/syntax.y new file mode 100644 index 0000000..247cc8a --- /dev/null +++ b/sys/cmd/rc/syntax.y @@ -0,0 +1,104 @@ +%token Tword Tif Telse Tbang +%token Targs +%token Tbasic Tparen Tblock + +%{ + #include "rc.h" + + int yylex(void); + void yyerror(char *); +%} + +/* operator precendence: lowest first */ +%right Telse +%left Twhile +%left '\n' +%left Tbang +%right '$' + +/* semantic types */ +%union{ + struct Tree *tree; +} +%type line cmds cmdsln body paren block ifbody assign; +%type cmd basic executable nonkeyword keyword word atom arg args; +%type Tbang; +%type Tword Tif Telse; + +/* grammar */ + +%start rc + +%% +rc: +/*empty*/ { return 0; } +| line '\n' { return compile($1); } + +line: + cmd +| cmds line { $$ = maketree2(';', $1, $2); } + +body: + cmd +| cmdsln body { $$ = maketree2(';', $1, $2); } + +paren: + '(' body ')' { $$ = maketree1(Tparen, $2); } + +block: + '{' body '}' { $$ = maketree1(Tblock, $2); } + +cmds: + cmd ';' +| cmd '&' { $$ = maketree1('&', $1); } + +cmdsln: + cmds +| cmd '\n' + +ifbody: + cmd %prec Telse { $$ = maketree2(Tif, nil, $1); } +| block Telse nl cmd { $$ = maketree3(Tif, nil, $1, $2); } + +assign: + executable '=' word { $$ = maketree2('=', $1, $3); } + +cmd: +/* empty */ %prec Twhile { $$ = nil; } +| basic { $$ = maketree1(Tbasic, $1); } +| block +| Tif paren nl ifbody { $$ = hangchild1($2, $1, 0); } + +basic: + executable +| basic word { $$ = maketree2(Targs, $1, $2); } + +arg: word + +args: + arg +| args arg { $$ = maketree2(Targs, $1, $2); } + +atom: + nonkeyword +| keyword { $$ = maketree1(Tword, $1); } + +word: + atom +| word '^' atom { $$ = maketree2('^', $1, $3); } + +executable: + nonkeyword +| executable '^' atom { $$ = maketree2('^', $1, $3); } + +nonkeyword: + Tword +| '$' atom { $$ = maketree1('$', $2); } + +keyword: + Tif|Telse + +nl: +/*empty*/ +| nl '\n' +%% -- cgit v1.2.1