]> Joshua Wise's Git repositories - snipe.git/blob - parse/l2.grm
6376e1cd2b978e2df0ded8e93d1f0577042c25b9
[snipe.git] / parse / l2.grm
1 (* L2 Compiler
2  * L2 grammar
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>
7  *)
8
9 structure A = Ast
10
11 (* for simplicity, we only mark expressions, not statements *)
12
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)))
16
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" ;
23                         Symbol.bogus )
24
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
29  *)
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)))
35
36 %%
37 %header (functor L2LrValsFn (structure Token : TOKEN))
38
39 %term 
40    EOF
41  | SEMI
42  | INTNUM of Word32.word
43  | IDENT of Symbol.symbol
44  | RETURN
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
49  | LBRACE | RBRACE
50  | LPAREN | RPAREN
51  | UNARY | ASNOP (* dummy *)
52
53 %nonterm 
54    program of A.program
55  | stms of A.stm list
56  | stm of A.stm
57  | simp of A.stm
58  | return of A.stm
59  | exp of A.exp
60  | control of A.stm
61  | asnop of A.oper option
62  | block of A.stm list
63  | simpoption of A.stm option
64  | elseoption of A.stm list option
65
66 %verbose                                (* print summary of errors *)
67 %pos int                                (* positions *)
68 %start program
69 %eop EOF
70 %noshift EOF
71
72 %name L2
73
74 %left LOGOR
75 %left LOGAND
76 %left BITOR
77 %left BITXOR
78 %left BITAND
79 %left EQ NEQ
80 %left LT LE GT GE
81 %left LSH RSH
82 %left PLUS MINUS
83 %left STAR SLASH PERCENT
84 %right UNARY
85 %left LPAREN
86
87 %%
88
89 program    : LBRACE stms RBRACE
90                                     (stms)
91
92 stms       :                        ([])
93            | stm stms               (stm :: stms)
94
95 stm        : simp SEMI (simp)
96            | control (control)
97            | SEMI (A.Nop)
98
99 simp       : exp asnop exp %prec ASNOP
100                                     (expand_asnop (exp1, asnop, exp2) (exp1left, exp2right))
101
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)))
111
112 elseoption : ELSE block             (SOME block)
113            |                        (NONE)
114
115 simpoption :                        (NONE)
116            | simp                   (SOME simp)
117
118 block      : stm                    ([stm])
119            | LBRACE stms RBRACE     (stms)
120
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)))
145
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))
This page took 0.026636 seconds and 2 git commands to generate.