X-Git-Url: http://git.joshuawise.com/snipe.git/blobdiff_plain/6ade8b0a3251e44b34c6bdbbd9403e36d6fd6231:/parse/l3.grm..1144856ba9d6018d9922c6ede7e97779a0fe6373:/parse/l4.grm diff --git a/parse/l3.grm b/parse/l4.grm similarity index 62% rename from parse/l3.grm rename to parse/l4.grm index cbf92ea..3f14c33 100644 --- a/parse/l3.grm +++ b/parse/l4.grm @@ -1,5 +1,5 @@ -(* L3 Compiler - * L3 grammar +(* L4 Compiler + * L4 grammar * Author: Kaustuv Chaudhuri * Modified: Frank Pfenning * Modified: Joshua Wise @@ -7,12 +7,16 @@ *) structure A = Ast +structure AU = AstUtils +structure AUP = AstUtils.Program (* for simplicity, we only mark expressions, not statements *) (* mark e with region (left, right) in source file *) fun mark (e, (left, right)) = A.Marked (Mark.mark' (e, ParseState.ext (left, right))) fun markstm (e, (left, right)) = A.MarkedStm (Mark.mark' (e, ParseState.ext (left, right))) +fun markfunction (e, (left, right)) = A.MarkedFunction (Mark.mark' (e, ParseState.ext (left, right))) +fun marktypedef (e, (left, right)) = A.MarkedTypedef (Mark.mark' (e, ParseState.ext (left, right))) (* create lval from expression; here just an id *) (* generates error if not an identifier *) @@ -22,19 +26,8 @@ fun make_lval (A.Var(id)) ext = id | make_lval _ ext = ( ErrorMsg.error ext "not a variable" ; Symbol.bogus ) -(* expand_asnop (exp1, "op=", exp2) region = "exp1 = exp1 op exps" - * or = "exp1 = exp2" if asnop is "=" - * generates error if exp1 is an lval (identifier) - * syntactically expands a compound assignment operator - *) -fun expand_asnop (exp1, NONE, exp2) (left, right) = - A.Assign(make_lval exp1 NONE, exp2) - | expand_asnop (exp1, SOME(oper), exp2) (left, right) = - A.Assign(make_lval exp1 NONE, - mark(A.OpExp(oper, [exp1, exp2]), (left, right))) - %% -%header (functor L3LrValsFn (structure Token : TOKEN)) +%header (functor L4LrValsFn (structure Token : TOKEN)) %term EOF @@ -49,10 +42,11 @@ fun expand_asnop (exp1, NONE, exp2) (left, right) = | LBRACE | RBRACE | LPAREN | RPAREN | UNARY | ASNOP (* dummy *) - | EXTERN | VAR | INT | COLON | COMMA + | EXTERN | VAR | INT | COLON | COMMA | STRUCT | NULL | LBRACKET | RBRACKET | ARROW | DOT | NEW %nonterm program of A.program + | programx of A.program | stms of A.stm list | stm of A.stm | simp of A.stm @@ -60,18 +54,20 @@ fun expand_asnop (exp1, NONE, exp2) (left, right) = | exp of A.exp | explist of A.exp list | control of A.stm - | asnop of A.oper option + | asnop of A.oper | block of A.stm list | simpoption of A.stm option | elseoption of A.stm list option | idents of A.ident list | vtype of A.vtype - | extdecls of A.function list - | extdecl of A.function + | decls of A.program + | extdecl of A.ident * A.function | paramlist of A.variable list | param of A.variable - | functions of A.function list - | function of A.function + | typedecl of A.ident * A.typedef + | memberlist of (A.ident * A.vtype) list + | member of (A.ident * A.vtype) + | function of A.ident * A.function | vardecl of A.variable list | vardecls of A.variable list @@ -81,7 +77,7 @@ fun expand_asnop (exp1, NONE, exp2) (left, right) = %eop EOF %noshift EOF -%name L3 +%name L4 %left LOGOR %left LOGAND @@ -94,36 +90,49 @@ fun expand_asnop (exp1, NONE, exp2) (left, right) = %left PLUS MINUS %left STAR SLASH PERCENT %right UNARY -%left LPAREN +%left LPAREN LBRACKET ARROW DOT %% -program : extdecls functions (extdecls @ functions) +program : programx (programx) + +programx : decls (decls) + | programx function (AUP.append_function programx function) vtype : INT (A.Int) + | IDENT (A.Typedef IDENT) + | vtype STAR (A.Pointer vtype) + | vtype LBRACKET RBRACKET + (A.Array vtype) -extdecls : ([]) - | extdecl extdecls (extdecl :: extdecls) +decls : (Symbol.empty, Symbol.empty) + | typedecl decls (AUP.append_typedef decls typedecl) + | extdecl decls (AUP.append_function decls extdecl) extdecl : EXTERN vtype IDENT LPAREN RPAREN SEMI - (A.Extern (vtype, IDENT, [])) - | EXTERN vtype IDENT LPAREN param RPAREN SEMI - (A.Extern (vtype, IDENT, [param])) + (IDENT, markfunction (A.Extern (vtype, []), (EXTERNleft, SEMIright))) | EXTERN vtype IDENT LPAREN paramlist RPAREN SEMI - (A.Extern (vtype, IDENT, paramlist)) + (IDENT, markfunction (A.Extern (vtype, paramlist), (EXTERNleft, SEMIright))) paramlist : param COMMA paramlist (param :: paramlist) | param ([param]) param : IDENT COLON vtype (IDENT, vtype) -functions : ([]) - | function functions (function :: functions) +typedecl : STRUCT IDENT LBRACE RBRACE SEMI + (IDENT, marktypedef (A.Struct ([]), (STRUCTleft, SEMIright))) + | STRUCT IDENT LBRACE memberlist RBRACE SEMI + (IDENT, marktypedef (A.Struct (memberlist), (STRUCTleft, SEMIright))) + +memberlist : member memberlist (member :: memberlist) + | member ([member]) + +member : IDENT COLON vtype SEMI (IDENT, vtype) -function : vtype IDENT LPAREN RPAREN LBRACE vardecls stms RBRACE - (A.Function (vtype, IDENT, [], vardecls, stms)) - | vtype IDENT LPAREN paramlist RPAREN LBRACE vardecls stms RBRACE - (A.Function (vtype, IDENT, paramlist, vardecls, stms)) +function : vtype IDENT LPAREN paramlist RPAREN LBRACE vardecls stms RBRACE + (IDENT, markfunction (A.Function (vtype, paramlist, vardecls, stms), (vtypeleft, RBRACEright))) + | vtype IDENT LPAREN RPAREN LBRACE vardecls stms RBRACE + (IDENT, markfunction (A.Function (vtype, [], vardecls, stms), (vtypeleft, RBRACEright))) vardecls : ([]) | vardecl vardecls (vardecl @ vardecls) @@ -141,8 +150,11 @@ stm : simp SEMI (simp) | control (control) | SEMI (A.Nop) -simp : exp asnop exp %prec ASNOP - (expand_asnop (exp1, asnop, exp2) (exp1left, exp2right)) +simp : exp ASSIGN exp %prec ASNOP + (A.Assign(exp1, exp2)) + | exp asnop exp %prec ASNOP + (A.AsnOp(asnop, exp1, exp2)) + | exp (markstm (A.Effect (exp), (expleft, expright))) control : IF LPAREN exp RPAREN block elseoption (markstm ((A.If (exp, block, elseoption)), (IFleft, elseoptionright))) @@ -166,6 +178,11 @@ block : stm ([stm]) exp : LPAREN exp RPAREN (exp) | INTNUM (mark (A.ConstExp(INTNUM),(INTNUMleft,INTNUMright))) | IDENT (mark (A.Var(IDENT), (IDENTleft,IDENTright))) + | exp DOT IDENT (mark (A.Member(exp, IDENT), (expleft, IDENTright))) + | exp ARROW IDENT (mark (A.DerefMember(exp, IDENT), (expleft, IDENTright))) + | STAR exp %prec UNARY (mark (A.Dereference(exp), (STARleft, expright))) + | exp LBRACKET exp RBRACKET + (mark (A.ArrIndex(exp1, exp2), (exp1left, exp2right))) | exp PLUS exp (mark (A.OpExp (A.PLUS, [exp1,exp2]), (exp1left,exp2right))) | exp MINUS exp (mark (A.OpExp (A.MINUS, [exp1,exp2]), (exp1left,exp2right))) | exp STAR exp (mark (A.OpExp (A.TIMES, [exp1,exp2]), (exp1left,exp2right))) @@ -184,11 +201,14 @@ exp : LPAREN exp RPAREN (exp) | exp LE exp (mark (A.OpExp (A.LE, [exp1,exp2]), (exp1left,exp2right))) | exp GT exp (mark (A.OpExp (A.GT, [exp1,exp2]), (exp1left,exp2right))) | exp GE exp (mark (A.OpExp (A.GE, [exp1,exp2]), (exp1left,exp2right))) + | NULL (mark (A.Null, (NULLleft, NULLright))) | IDENT LPAREN RPAREN (mark (A.FuncCall(IDENT, []), (IDENTleft, RPARENright))) - | IDENT LPAREN exp RPAREN - (mark (A.FuncCall(IDENT, [exp]), (IDENTleft, RPARENright))) | IDENT LPAREN explist RPAREN (mark (A.FuncCall(IDENT, explist), (IDENTleft, RPARENright))) + | NEW LPAREN vtype RPAREN + (mark (A.New (vtype), (NEWleft, RPARENright))) + | NEW LPAREN vtype LBRACKET exp RBRACKET RPAREN + (mark (A.NewArr (vtype, exp), (NEWleft, RPARENright))) | MINUS exp %prec UNARY (mark (A.OpExp (A.NEGATIVE, [exp]), (MINUSleft,expright))) | BITNOT exp %prec UNARY (mark (A.OpExp (A.BITNOT, [exp]), (BITNOTleft,expright))) | BANG exp %prec UNARY (mark (A.OpExp (A.BANG, [exp]), (BANGleft,expright))) @@ -196,14 +216,13 @@ exp : LPAREN exp RPAREN (exp) explist : exp ([exp]) | exp COMMA explist (exp :: explist) -asnop : ASSIGN (NONE) - | PLUSEQ (SOME(A.PLUS)) - | MINUSEQ (SOME(A.MINUS)) - | STAREQ (SOME(A.TIMES)) - | SLASHEQ (SOME(A.DIVIDEDBY)) - | PERCENTEQ (SOME(A.MODULO)) - | LSHEQ (SOME(A.LSH)) - | RSHEQ (SOME(A.RSH)) - | BITOREQ (SOME(A.BITOR)) - | BITANDEQ (SOME(A.BITAND)) - | BITXOREQ (SOME(A.BITXOR)) +asnop : PLUSEQ (A.PLUS) + | MINUSEQ (A.MINUS) + | STAREQ (A.TIMES) + | SLASHEQ (A.DIVIDEDBY) + | PERCENTEQ (A.MODULO) + | LSHEQ (A.LSH) + | RSHEQ (A.RSH) + | BITOREQ (A.BITOR) + | BITANDEQ (A.BITAND) + | BITXOREQ (A.BITXOR)