diff options
Diffstat (limited to 'appl/cmd/mash/mash.y')
| -rw-r--r-- | appl/cmd/mash/mash.y | 269 |
1 files changed, 269 insertions, 0 deletions
diff --git a/appl/cmd/mash/mash.y b/appl/cmd/mash/mash.y new file mode 100644 index 00000000..2417ef51 --- /dev/null +++ b/appl/cmd/mash/mash.y @@ -0,0 +1,269 @@ +%{ +include "mash.m"; + +# +# mash parser. Thread safe. +# +%} + +%module Mashparse +{ + PATH: con "/dis/lib/mashparse.dis"; + + init: fn(l: Mashlib); + parse: fn(e: ref Mashlib->Env); + + YYSTYPE: adt + { + cmd: ref Mashlib->Cmd; + item: ref Mashlib->Item; + items: list of ref Mashlib->Item; + flag: int; + }; + + YYETYPE: type ref Mashlib->Env; +} + +%{ + lib: Mashlib; + + Cmd, Item, Stab, Env: import lib; +%} + +%left Lcase Lfor Lif Lwhile Loffparen # low prec +%left Lelse +%left Lpipe +%left Leqeq Lmatch Lnoteq +%right Lcons +%left Lcaret +%left Lnot Lhd Ltl Llen +%type <flag> term +%type <item> item wgen witem word redir sword +%type <items> asimple list +%type <cmd> case cases cmd cmda cmds cmdt complex +%type <cmd> epilog expr cbrace cobrace obrace simple +%token <item> Lword +%token Lbackq Lcolon Lcolonmatch Ldefeq Leq Lmatched Lquote +%token Loncurly Lonparen Loffcurly Loffparen Lat +%token Lgreat Lgreatgreat Lless Llessgreat +%token Lfn Lin Lrescue +%token Land Leof Lsemi +%token Lerror + +%% + +script : tcmds + ; + +tcmds : # empty + | tcmds xeq + ; + +xeq : cmda + { $1.xeq(e.yyenv); } + | Leof + | error + ; + +cmdt : # empty + { $$ = nil; } + | cmdt cmda + { $$ = Cmd.cmd2(Cseq, $1, $2); } + ; + +cmda : cmd term + { $$ = $1.mkcmd(e.yyenv, $2); } + ; + +cmds : cmdt + | cmdt cmd + { $$ = Cmd.cmd2(Cseq, $1, $2.mkcmd(e.yyenv, 0)); } + ; + +cmd : simple + | complex + | cmd Lpipe cmd + { $$ = Cmd.cmd2(Cpipe, $1, $3); } + ; + +simple : asimple + { $$ = e.yyenv.mksimple($1); } + | asimple Lcolon list cobrace + { + $4.words = e.yyenv.mklist($3); + $$ = Cmd.cmd1w(Cdepend, $4, e.yyenv.mklist($1)); + } + ; + +complex : Loncurly cmds Loffcurly epilog + { $$ = $4.cmde(Cgroup, $2, nil); } + | Lat Loncurly cmds Loffcurly epilog + { $$ = $5.cmde(Csubgroup, $3, nil); } + | Lfor Lonparen sword Lin list Loffparen cmd + { $$ = Cmd.cmd1i(Cfor, $7, $3); $$.words = lib->revitems($5); } + | Lif Lonparen expr Loffparen cmd + { $$ = Cmd.cmd2(Cif, $3, $5); } + | Lif Lonparen expr Loffparen cmd Lelse cmd + { $$ = Cmd.cmd2(Cif, $3, Cmd.cmd2(Celse, $5, $7)); } + | Lwhile Lonparen expr Loffparen cmd + { $$ = Cmd.cmd2(Cwhile, $3, $5); } + | Lcase expr Loncurly cases Loffcurly + { $$ = Cmd.cmd2(Ccase, $2, $4.rotcases()); } + | sword Leq list + { $$ = Cmd.cmdiw(Ceq, $1, $3); } + | sword Ldefeq list + { $$ = Cmd.cmdiw(Cdefeq, $1, $3); } + | Lfn word obrace + { $$ = Cmd.cmd1i(Cfn, $3, $2); } + | Lrescue word obrace + { $$ = Cmd.cmd1i(Crescue, $3, $2); } + | word Lcolonmatch word cbrace + { + $4.item = $3; + $$ = Cmd.cmd1i(Crule, $4, $1); + } + ; + +cbrace : Lcolon Loncurly cmds Loffcurly + { $$ = Cmd.cmd1(Clistgroup, $3); } + | Loncurly cmds Loffcurly + { $$ = Cmd.cmd1(Cgroup, $2); } + ; + +cobrace : # empty + { $$ = Cmd.cmd1(Cnop, nil); } + | cbrace + ; + +obrace : # empty + { $$ = nil; } + | Loncurly cmds Loffcurly + { $$ = $2; } + ; + +cases : # empty + { $$ = nil; } + | cases case + { $$ = Cmd.cmd2(Ccases, $1, $2); } + ; + +case : expr Lmatched cmda + { $$ = Cmd.cmd2(Cmatched, $1, $3); } + ; + +asimple : word + { $$ = $1 :: nil; } + | asimple item + { $$ = $2 :: $1; } + ; + +item : witem + | redir + ; + +witem : word + | wgen + ; + +wgen : Lbackq Loncurly cmds Loffcurly + { $$ = Item.itemc(Ibackq, $3); } + | Lquote Loncurly cmds Loffcurly + { $$ = Item.itemc(Iquote, $3); } + | Lless Loncurly cmds Loffcurly + { $$ = Item.itemc(Iinpipe, $3); } + | Lgreat Loncurly cmds Loffcurly + { $$ = Item.itemc(Ioutpipe, $3); } + ; + +word : Lword + | word Lcaret word + { $$ = Item.item2(Icaret, $1, $3); } + | Lonparen expr Loffparen + { $$ = Item.itemc(Iexpr, $2); } + ; + +sword : Lword + { $$ = $1.sword(e.yyenv); } + ; + +list : # empty + { $$ = nil; } + | list witem + { $$ = $2 :: $1; } + ; + +epilog : # empty + { $$ = ref Cmd; $$.error = 0; } + | epilog redir + { $$ = $1; $1.cmdio(e.yyenv, $2); } + ; + +redir : Lless word + { $$ = Item.itemr(Rin, $2); } + | Lgreat word + { $$ = Item.itemr(Rout, $2); } + | Lgreatgreat word + { $$ = Item.itemr(Rappend, $2); } + | Llessgreat word + { $$ = Item.itemr(Rinout, $2); } + ; + +term : Lsemi + { $$ = 0; } + | Leof + { $$ = 0; } + | Land + { $$ = 1; } + ; + +expr : Lword + { $$ = Cmd.cmd1i(Cword, nil, $1); } + | wgen + { $$ = Cmd.cmd1i(Cword, nil, $1); } + | Lonparen expr Loffparen + { $$ = $2; } + | expr Lcaret expr + { $$ = Cmd.cmd2(Ccaret, $1, $3); } + | Lhd expr + { $$ = Cmd.cmd1(Chd, $2); } + | Ltl expr + { $$ = Cmd.cmd1(Ctl, $2); } + | Llen expr + { $$ = Cmd.cmd1(Clen, $2); } + | Lnot expr + { $$ = Cmd.cmd1(Cnot, $2); } + | expr Lcons expr + { $$ = Cmd.cmd2(Ccons, $1, $3); } + | expr Leqeq expr + { $$ = Cmd.cmd2(Ceqeq, $1, $3); } + | expr Lnoteq expr + { $$ = Cmd.cmd2(Cnoteq, $1, $3); } + | expr Lmatch expr + { $$ = Cmd.cmd2(Cmatch, $1, $3); } + ; +%% + +init(l: Mashlib) +{ + lib = l; +} + +parse(e: ref Env) +{ + y := ref YYENV; + y.yyenv = e; + y.yysys = lib->sys; + y.yystderr = e.stderr; + yyeparse(y); +} + +yyerror(e: ref YYENV, s: string) +{ + e.yyenv.report(s); + e.yyenv.suck(); +} + +yyelex(e: ref YYENV): int +{ + return e.yyenv.lex(e.yylval); +} |
