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 (* for simplicity, we only mark expressions, not statements *)
13 (* mark e with region (left, right) in source file *)
14 fun mark (e, (left, right)) = A.Marked (Mark.mark' (e, ParseState.ext (left, right)))
15 fun markstm (e, (left, right)) = A.MarkedStm (Mark.mark' (e, ParseState.ext (left, right)))
17 (* create lval from expression; here just an id *)
18 (* generates error if not an identifier *)
19 fun make_lval (A.Var(id)) ext = id
20 | make_lval (A.Marked(marked_exp)) ext =
21 make_lval (Mark.data marked_exp) (Mark.ext marked_exp)
22 | make_lval _ ext = ( ErrorMsg.error ext "not a variable" ;
25 (* expand_asnop (exp1, "op=", exp2) region = "exp1 = exp1 op exps"
26 * or = "exp1 = exp2" if asnop is "="
27 * generates error if exp1 is an lval (identifier)
28 * syntactically expands a compound assignment operator
30 fun expand_asnop (exp1, NONE, exp2) (left, right) =
31 A.Assign(make_lval exp1 NONE, exp2)
32 | expand_asnop (exp1, SOME(oper), exp2) (left, right) =
33 A.Assign(make_lval exp1 NONE,
34 mark(A.OpExp(oper, [exp1, exp2]), (left, right)))
37 %header (functor L2LrValsFn (structure Token : TOKEN))
42 | INTNUM of Word32.word
43 | IDENT of Symbol.symbol
45 | PLUS | MINUS | STAR | SLASH | PERCENT | LSH | RSH | LOGOR | LOGAND | BITAND | BITXOR | BITOR | BITNOT | BANG
46 | ASSIGN | PLUSEQ | MINUSEQ | STAREQ | SLASHEQ | PERCENTEQ | LSHEQ | RSHEQ | BITANDEQ | BITXOREQ | BITOREQ
47 | EQ | NEQ | LT | LE | GT | GE
48 | IF | ELSE | WHILE | FOR | CONTINUE | BREAK
51 | UNARY | ASNOP (* dummy *)
61 | asnop of A.oper option
63 | simpoption of A.stm option
64 | elseoption of A.stm list option
66 %verbose (* print summary of errors *)
67 %pos int (* positions *)
83 %left STAR SLASH PERCENT
89 program : LBRACE stms RBRACE
93 | stm stms (stm :: stms)
95 stm : simp SEMI (simp)
99 simp : exp asnop exp %prec ASNOP
100 (expand_asnop (exp1, asnop, exp2) (exp1left, exp2right))
102 control : IF LPAREN exp RPAREN block elseoption
103 (markstm ((A.If (exp, block, elseoption)), (IFleft, elseoptionright)))
104 | WHILE LPAREN exp RPAREN block
105 (markstm ((A.While (exp, block)), (WHILEleft, blockright)))
106 | FOR LPAREN simpoption SEMI exp SEMI simpoption RPAREN block
107 (markstm ((A.For (simpoption1, exp, simpoption2, block)), (FORleft, blockright)))
108 | CONTINUE SEMI (markstm ((A.Continue), (CONTINUEleft, SEMIright)))
109 | BREAK SEMI (markstm ((A.Break), (BREAKleft, SEMIright)))
110 | RETURN exp SEMI (markstm ((A.Return exp), (RETURNleft, SEMIright)))
112 elseoption : ELSE block (SOME block)
119 | LBRACE stms RBRACE (stms)
121 exp : LPAREN exp RPAREN (exp)
122 | INTNUM (mark (A.ConstExp(INTNUM),(INTNUMleft,INTNUMright)))
123 | IDENT (mark (A.Var(IDENT), (IDENTleft,IDENTright)))
124 | exp PLUS exp (mark (A.OpExp (A.PLUS, [exp1,exp2]), (exp1left,exp2right)))
125 | exp MINUS exp (mark (A.OpExp (A.MINUS, [exp1,exp2]), (exp1left,exp2right)))
126 | exp STAR exp (mark (A.OpExp (A.TIMES, [exp1,exp2]), (exp1left,exp2right)))
127 | exp SLASH exp (mark (A.OpExp (A.DIVIDEDBY, [exp1,exp2]), (exp1left,exp2right)))
128 | exp PERCENT exp (mark (A.OpExp (A.MODULO, [exp1,exp2]), (exp1left,exp2right)))
129 | exp LSH exp (mark (A.OpExp (A.LSH, [exp1,exp2]), (exp1left,exp2right)))
130 | exp RSH exp (mark (A.OpExp (A.RSH, [exp1,exp2]), (exp1left,exp2right)))
131 | exp LOGOR exp (mark (A.OpExp (A.LOGOR, [exp1,exp2]), (exp1left,exp2right)))
132 | exp LOGAND exp (mark (A.OpExp (A.LOGAND, [exp1,exp2]), (exp1left,exp2right)))
133 | exp BITOR exp (mark (A.OpExp (A.BITOR, [exp1,exp2]), (exp1left,exp2right)))
134 | exp BITAND exp (mark (A.OpExp (A.BITAND, [exp1,exp2]), (exp1left,exp2right)))
135 | exp BITXOR exp (mark (A.OpExp (A.BITXOR, [exp1,exp2]), (exp1left,exp2right)))
136 | exp EQ exp (mark (A.OpExp (A.EQ, [exp1,exp2]), (exp1left,exp2right)))
137 | exp NEQ exp (mark (A.OpExp (A.NEQ, [exp1,exp2]), (exp1left,exp2right)))
138 | exp LT exp (mark (A.OpExp (A.LT, [exp1,exp2]), (exp1left,exp2right)))
139 | exp LE exp (mark (A.OpExp (A.LE, [exp1,exp2]), (exp1left,exp2right)))
140 | exp GT exp (mark (A.OpExp (A.GT, [exp1,exp2]), (exp1left,exp2right)))
141 | exp GE exp (mark (A.OpExp (A.GE, [exp1,exp2]), (exp1left,exp2right)))
142 | MINUS exp %prec UNARY (mark (A.OpExp (A.NEGATIVE, [exp]), (MINUSleft,expright)))
143 | BITNOT exp %prec UNARY (mark (A.OpExp (A.BITNOT, [exp]), (BITNOTleft,expright)))
144 | BANG exp %prec UNARY (mark (A.OpExp (A.BANG, [exp]), (BANGleft,expright)))
146 asnop : ASSIGN (NONE)
147 | PLUSEQ (SOME(A.PLUS))
148 | MINUSEQ (SOME(A.MINUS))
149 | STAREQ (SOME(A.TIMES))
150 | SLASHEQ (SOME(A.DIVIDEDBY))
151 | PERCENTEQ (SOME(A.MODULO))
152 | LSHEQ (SOME(A.LSH))
153 | RSHEQ (SOME(A.RSH))
154 | BITOREQ (SOME(A.BITOR))
155 | BITANDEQ (SOME(A.BITAND))
156 | BITXOREQ (SOME(A.BITXOR))