3 * Author: Kaustuv Chaudhuri <kaustuv+@cs.cmu.edu>
4 * Modified: Frank Pfenning <fp@cs.cmu.edu>
5 * Modified: Joshua Wise <jwise@andrew.cmu.edu>
6 * Modified: Chris Lu <czl@andrew.cmu.edu>
11 structure AU = AstUtils
12 structure AUP = AstUtils.Program
14 (* for simplicity, we only mark expressions, not statements *)
16 (* mark e with region (left, right) in source file *)
17 fun mark (e, (left, right)) = A.Marked (Mark.mark' (e, ParseState.ext (left, right)))
18 fun markstm (e, (left, right)) = A.MarkedStm (Mark.mark' (e, ParseState.ext (left, right)))
19 fun markfunction (e, (left, right)) = A.MarkedFunction (Mark.mark' (e, ParseState.ext (left, right)))
20 fun marktypedef (e, (left, right)) = T.MarkedTypedef (Mark.mark' (e, ParseState.ext (left, right)))
22 (* create lval from expression; here just an id *)
23 (* generates error if not an identifier *)
24 fun make_lval (A.Var(id)) ext = id
25 | make_lval (A.Marked(marked_exp)) ext =
26 make_lval (Mark.data marked_exp) (Mark.ext marked_exp)
27 | make_lval _ ext = ( ErrorMsg.error ext "not a variable" ;
31 %header (functor L5LrValsFn (structure Token : TOKEN))
36 | INTNUM of Word32.word
37 | IDENT of Symbol.symbol
40 | PLUS | MINUS | STAR | SLASH | PERCENT | LSH | RSH | LOGOR | LOGAND | BITAND | BITXOR | BITOR | BITNOT | BANG
41 | ASSIGN | PLUSEQ | MINUSEQ | STAREQ | SLASHEQ | PERCENTEQ | LSHEQ | RSHEQ | BITANDEQ | BITXOREQ | BITOREQ
42 | EQ | NEQ | LT | LE | GT | GE
43 | IF | ELSE | WHILE | FOR | CONTINUE | BREAK
46 | UNARY | ASNOP (* dummy *)
47 | EXTERN | VAR | INT | TSTRING | QUESTION | COLON | COMMA | STRUCT | NULL | LBRACKET | RBRACKET | ARROW | DOT | NEW
48 | PLUSPLUS | MINUSMINUS
52 | programx of A.program
58 | explist of A.exp list
62 | simpoption of A.stm option
63 | elseoption of A.stm list option
64 | idents of A.ident list
67 | extdecl of A.ident * A.function
68 | paramlist of T.variable list
70 | typedecl of T.ident * T.typedef
71 | memberlist of (T.ident * T.vtype) list
72 | member of (T.ident * T.vtype)
73 | function of A.ident * A.function
74 | vardecl of T.variable list
75 | vardecls of T.variable list
77 %verbose (* print summary of errors *)
78 %pos int (* positions *)
95 %left STAR SLASH PERCENT
97 %left LPAREN LBRACKET ARROW DOT
101 program : programx (programx)
103 programx : decls (decls)
104 | programx function (AUP.append_function programx function)
108 | IDENT (T.Typedef IDENT)
109 | vtype STAR (T.Pointer vtype)
110 | vtype LBRACKET RBRACKET
113 decls : (Symbol.empty, Symbol.empty)
114 | typedecl decls (AUP.append_typedef decls typedecl)
115 | extdecl decls (AUP.append_function decls extdecl)
117 extdecl : EXTERN vtype IDENT LPAREN RPAREN SEMI
118 (IDENT, markfunction (A.Extern (vtype, []), (EXTERNleft, SEMIright)))
119 | EXTERN vtype IDENT LPAREN paramlist RPAREN SEMI
120 (IDENT, markfunction (A.Extern (vtype, paramlist), (EXTERNleft, SEMIright)))
122 paramlist : param COMMA paramlist (param :: paramlist)
125 param : IDENT COLON vtype (IDENT, vtype)
127 typedecl : STRUCT IDENT LBRACE RBRACE SEMI
128 (IDENT, marktypedef (T.Struct ([]), (STRUCTleft, SEMIright)))
129 | STRUCT IDENT LBRACE memberlist RBRACE SEMI
130 (IDENT, marktypedef (T.Struct (memberlist), (STRUCTleft, SEMIright)))
132 memberlist : member memberlist (member :: memberlist)
135 member : IDENT COLON vtype SEMI (IDENT, vtype)
137 function : vtype IDENT LPAREN paramlist RPAREN LBRACE vardecls stms RBRACE
138 (IDENT, markfunction (A.Function (vtype, paramlist, vardecls, stms), (vtypeleft, RBRACEright)))
139 | vtype IDENT LPAREN RPAREN LBRACE vardecls stms RBRACE
140 (IDENT, markfunction (A.Function (vtype, [], vardecls, stms), (vtypeleft, RBRACEright)))
143 | vardecl vardecls (vardecl @ vardecls)
145 vardecl : VAR idents COLON vtype SEMI
146 (map (fn x => (x, vtype)) idents)
148 idents : IDENT ([IDENT])
149 | IDENT COMMA idents (IDENT :: idents)
152 | stm stms (stm :: stms)
154 stm : simp SEMI (simp)
158 simp : exp ASSIGN exp %prec ASNOP
159 (A.Assign(exp1, exp2))
160 | exp asnop exp %prec ASNOP
161 (A.AsnOp(asnop, exp1, exp2))
162 | exp PLUSPLUS %prec ASNOP
163 (A.AsnOp(A.PLUS, exp, A.ConstExp(0w1)))
164 | exp MINUSMINUS %prec ASNOP
165 (A.AsnOp(A.MINUS, exp, A.ConstExp(0w1)))
166 | exp (markstm (A.Effect (exp), (expleft, expright)))
168 control : IF LPAREN exp RPAREN block elseoption
169 (markstm ((A.If (exp, block, elseoption)), (IFleft, elseoptionright)))
170 | WHILE LPAREN exp RPAREN block
171 (markstm ((A.While (exp, block)), (WHILEleft, blockright)))
172 | FOR LPAREN simpoption SEMI exp SEMI simpoption RPAREN block
173 (markstm ((A.For (simpoption1, exp, simpoption2, block)), (FORleft, blockright)))
174 | CONTINUE SEMI (markstm ((A.Continue), (CONTINUEleft, SEMIright)))
175 | BREAK SEMI (markstm ((A.Break), (BREAKleft, SEMIright)))
176 | RETURN exp SEMI (markstm ((A.Return exp), (RETURNleft, SEMIright)))
178 elseoption : ELSE block (SOME block)
185 | LBRACE stms RBRACE (stms)
187 exp : LPAREN exp RPAREN (exp)
188 | INTNUM (mark (A.ConstExp(INTNUM),(INTNUMleft,INTNUMright)))
189 | STRING (mark (A.StringExp(STRING),(STRINGleft,STRINGright)))
190 | IDENT (mark (A.Var(IDENT), (IDENTleft,IDENTright)))
191 | exp DOT IDENT (mark (A.Member(exp, IDENT), (expleft, IDENTright)))
192 | exp ARROW IDENT (mark (A.DerefMember(exp, IDENT), (expleft, IDENTright)))
193 | STAR exp %prec UNARY (mark (A.Dereference(exp), (STARleft, expright)))
194 | exp LBRACKET exp RBRACKET
195 (mark (A.ArrIndex(exp1, exp2), (exp1left, exp2right)))
196 | exp PLUS exp (mark (A.OpExp (A.PLUS, [exp1,exp2]), (exp1left,exp2right)))
197 | exp MINUS exp (mark (A.OpExp (A.MINUS, [exp1,exp2]), (exp1left,exp2right)))
198 | exp STAR exp (mark (A.OpExp (A.TIMES, [exp1,exp2]), (exp1left,exp2right)))
199 | exp SLASH exp (mark (A.OpExp (A.DIVIDEDBY, [exp1,exp2]), (exp1left,exp2right)))
200 | exp PERCENT exp (mark (A.OpExp (A.MODULO, [exp1,exp2]), (exp1left,exp2right)))
201 | exp LSH exp (mark (A.OpExp (A.LSH, [exp1,exp2]), (exp1left,exp2right)))
202 | exp RSH exp (mark (A.OpExp (A.RSH, [exp1,exp2]), (exp1left,exp2right)))
203 | exp LOGOR exp (mark (A.OpExp (A.LOGOR, [exp1,exp2]), (exp1left,exp2right)))
204 | exp LOGAND exp (mark (A.OpExp (A.LOGAND, [exp1,exp2]), (exp1left,exp2right)))
205 | exp BITOR exp (mark (A.OpExp (A.BITOR, [exp1,exp2]), (exp1left,exp2right)))
206 | exp BITAND exp (mark (A.OpExp (A.BITAND, [exp1,exp2]), (exp1left,exp2right)))
207 | exp BITXOR exp (mark (A.OpExp (A.BITXOR, [exp1,exp2]), (exp1left,exp2right)))
208 | exp EQ exp (mark (A.OpExp (A.EQ, [exp1,exp2]), (exp1left,exp2right)))
209 | exp NEQ exp (mark (A.OpExp (A.NEQ, [exp1,exp2]), (exp1left,exp2right)))
210 | exp LT exp (mark (A.OpExp (A.LT, [exp1,exp2]), (exp1left,exp2right)))
211 | exp LE exp (mark (A.OpExp (A.LE, [exp1,exp2]), (exp1left,exp2right)))
212 | exp GT exp (mark (A.OpExp (A.GT, [exp1,exp2]), (exp1left,exp2right)))
213 | exp GE exp (mark (A.OpExp (A.GE, [exp1,exp2]), (exp1left,exp2right)))
214 | NULL (mark (A.Null, (NULLleft, NULLright)))
215 | IDENT LPAREN RPAREN (mark (A.FuncCall(IDENT, []), (IDENTleft, RPARENright)))
216 | IDENT LPAREN explist RPAREN
217 (mark (A.FuncCall(IDENT, explist), (IDENTleft, RPARENright)))
218 | NEW LPAREN vtype RPAREN
219 (mark (A.New (vtype), (NEWleft, RPARENright)))
220 | NEW LPAREN vtype LBRACKET exp RBRACKET RPAREN
221 (mark (A.NewArr (vtype, exp), (NEWleft, RPARENright)))
222 | MINUS exp %prec UNARY (mark (A.OpExp (A.NEGATIVE, [exp]), (MINUSleft,expright)))
223 | BITNOT exp %prec UNARY (mark (A.OpExp (A.BITNOT, [exp]), (BITNOTleft,expright)))
224 | BANG exp %prec UNARY (mark (A.OpExp (A.BANG, [exp]), (BANGleft,expright)))
225 | exp QUESTION exp COLON exp
226 (mark (A.Conditional (exp1, exp2, exp3), (exp1left, exp3right)))
228 explist : exp ([exp])
229 | exp COMMA explist (exp :: explist)
231 asnop : PLUSEQ (A.PLUS)
234 | SLASHEQ (A.DIVIDEDBY)
235 | PERCENTEQ (A.MODULO)
239 | BITANDEQ (A.BITAND)
240 | BITXOREQ (A.BITXOR)