]> Joshua Wise's Git repositories - snipe.git/blame - parse/l3.grm
Initial import of l3c
[snipe.git] / parse / l3.grm
CommitLineData
6ade8b0a
JW
1(* L3 Compiler
2 * L3 grammar
0a24e44d
JW
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
9structure A = Ast
10
11(* for simplicity, we only mark expressions, not statements *)
12
13(* mark e with region (left, right) in source file *)
14fun mark (e, (left, right)) = A.Marked (Mark.mark' (e, ParseState.ext (left, right)))
15fun 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 *)
19fun 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 *)
30fun 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%%
6ade8b0a 37%header (functor L3LrValsFn (structure Token : TOKEN))
0a24e44d
JW
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 *)
6ade8b0a 52 | EXTERN | VAR | INT | COLON | COMMA
0a24e44d
JW
53
54%nonterm
55 program of A.program
56 | stms of A.stm list
57 | stm of A.stm
58 | simp of A.stm
59 | return of A.stm
60 | exp of A.exp
6ade8b0a 61 | explist of A.exp list
0a24e44d
JW
62 | control of A.stm
63 | asnop of A.oper option
64 | block of A.stm list
65 | simpoption of A.stm option
66 | elseoption of A.stm list option
6ade8b0a
JW
67 | idents of A.ident list
68 | vtype of A.vtype
69 | extdecls of A.function list
70 | extdecl of A.function
71 | paramlist of A.variable list
72 | param of A.variable
73 | functions of A.function list
74 | function of A.function
75 | vardecl of A.variable list
76 | vardecls of A.variable list
0a24e44d
JW
77
78%verbose (* print summary of errors *)
79%pos int (* positions *)
80%start program
81%eop EOF
82%noshift EOF
83
6ade8b0a 84%name L3
0a24e44d
JW
85
86%left LOGOR
87%left LOGAND
88%left BITOR
89%left BITXOR
90%left BITAND
91%left EQ NEQ
92%left LT LE GT GE
93%left LSH RSH
94%left PLUS MINUS
95%left STAR SLASH PERCENT
96%right UNARY
97%left LPAREN
98
99%%
100
6ade8b0a
JW
101program : extdecls functions (extdecls @ functions)
102
103vtype : INT (A.Int)
104
105extdecls : ([])
106 | extdecl extdecls (extdecl :: extdecls)
107
108extdecl : EXTERN vtype IDENT LPAREN RPAREN SEMI
109 (A.Extern (vtype, IDENT, []))
110 | EXTERN vtype IDENT LPAREN param RPAREN SEMI
111 (A.Extern (vtype, IDENT, [param]))
112 | EXTERN vtype IDENT LPAREN paramlist RPAREN SEMI
113 (A.Extern (vtype, IDENT, paramlist))
114
115paramlist : param COMMA paramlist (param :: paramlist)
116 | param ([param])
117
118param : IDENT COLON vtype (IDENT, vtype)
119
120functions : ([])
121 | function functions (function :: functions)
122
123function : vtype IDENT LPAREN RPAREN LBRACE vardecls stms RBRACE
124 (A.Function (vtype, IDENT, [], vardecls, stms))
125 | vtype IDENT LPAREN paramlist RPAREN LBRACE vardecls stms RBRACE
126 (A.Function (vtype, IDENT, paramlist, vardecls, stms))
127
128vardecls : ([])
129 | vardecl vardecls (vardecl @ vardecls)
130
131vardecl : VAR idents COLON vtype SEMI
132 (map (fn x => (x, vtype)) idents)
133
134idents : IDENT ([IDENT])
135 | IDENT COMMA idents (IDENT :: idents)
0a24e44d
JW
136
137stms : ([])
138 | stm stms (stm :: stms)
139
6ade8b0a
JW
140stm : simp SEMI (simp)
141 | control (control)
142 | SEMI (A.Nop)
0a24e44d
JW
143
144simp : exp asnop exp %prec ASNOP
145 (expand_asnop (exp1, asnop, exp2) (exp1left, exp2right))
146
147control : IF LPAREN exp RPAREN block elseoption
148 (markstm ((A.If (exp, block, elseoption)), (IFleft, elseoptionright)))
149 | WHILE LPAREN exp RPAREN block
150 (markstm ((A.While (exp, block)), (WHILEleft, blockright)))
151 | FOR LPAREN simpoption SEMI exp SEMI simpoption RPAREN block
152 (markstm ((A.For (simpoption1, exp, simpoption2, block)), (FORleft, blockright)))
153 | CONTINUE SEMI (markstm ((A.Continue), (CONTINUEleft, SEMIright)))
154 | BREAK SEMI (markstm ((A.Break), (BREAKleft, SEMIright)))
155 | RETURN exp SEMI (markstm ((A.Return exp), (RETURNleft, SEMIright)))
156
157elseoption : ELSE block (SOME block)
158 | (NONE)
159
160simpoption : (NONE)
161 | simp (SOME simp)
162
163block : stm ([stm])
164 | LBRACE stms RBRACE (stms)
165
166exp : LPAREN exp RPAREN (exp)
167 | INTNUM (mark (A.ConstExp(INTNUM),(INTNUMleft,INTNUMright)))
168 | IDENT (mark (A.Var(IDENT), (IDENTleft,IDENTright)))
169 | exp PLUS exp (mark (A.OpExp (A.PLUS, [exp1,exp2]), (exp1left,exp2right)))
170 | exp MINUS exp (mark (A.OpExp (A.MINUS, [exp1,exp2]), (exp1left,exp2right)))
171 | exp STAR exp (mark (A.OpExp (A.TIMES, [exp1,exp2]), (exp1left,exp2right)))
172 | exp SLASH exp (mark (A.OpExp (A.DIVIDEDBY, [exp1,exp2]), (exp1left,exp2right)))
173 | exp PERCENT exp (mark (A.OpExp (A.MODULO, [exp1,exp2]), (exp1left,exp2right)))
174 | exp LSH exp (mark (A.OpExp (A.LSH, [exp1,exp2]), (exp1left,exp2right)))
175 | exp RSH exp (mark (A.OpExp (A.RSH, [exp1,exp2]), (exp1left,exp2right)))
176 | exp LOGOR exp (mark (A.OpExp (A.LOGOR, [exp1,exp2]), (exp1left,exp2right)))
177 | exp LOGAND exp (mark (A.OpExp (A.LOGAND, [exp1,exp2]), (exp1left,exp2right)))
178 | exp BITOR exp (mark (A.OpExp (A.BITOR, [exp1,exp2]), (exp1left,exp2right)))
179 | exp BITAND exp (mark (A.OpExp (A.BITAND, [exp1,exp2]), (exp1left,exp2right)))
180 | exp BITXOR exp (mark (A.OpExp (A.BITXOR, [exp1,exp2]), (exp1left,exp2right)))
181 | exp EQ exp (mark (A.OpExp (A.EQ, [exp1,exp2]), (exp1left,exp2right)))
182 | exp NEQ exp (mark (A.OpExp (A.NEQ, [exp1,exp2]), (exp1left,exp2right)))
183 | exp LT exp (mark (A.OpExp (A.LT, [exp1,exp2]), (exp1left,exp2right)))
184 | exp LE exp (mark (A.OpExp (A.LE, [exp1,exp2]), (exp1left,exp2right)))
185 | exp GT exp (mark (A.OpExp (A.GT, [exp1,exp2]), (exp1left,exp2right)))
186 | exp GE exp (mark (A.OpExp (A.GE, [exp1,exp2]), (exp1left,exp2right)))
6ade8b0a
JW
187 | IDENT LPAREN RPAREN (mark (A.FuncCall(IDENT, []), (IDENTleft, RPARENright)))
188 | IDENT LPAREN exp RPAREN
189 (mark (A.FuncCall(IDENT, [exp]), (IDENTleft, RPARENright)))
190 | IDENT LPAREN explist RPAREN
191 (mark (A.FuncCall(IDENT, explist), (IDENTleft, RPARENright)))
0a24e44d
JW
192 | MINUS exp %prec UNARY (mark (A.OpExp (A.NEGATIVE, [exp]), (MINUSleft,expright)))
193 | BITNOT exp %prec UNARY (mark (A.OpExp (A.BITNOT, [exp]), (BITNOTleft,expright)))
194 | BANG exp %prec UNARY (mark (A.OpExp (A.BANG, [exp]), (BANGleft,expright)))
195
6ade8b0a
JW
196explist : exp ([exp])
197 | exp COMMA explist (exp :: explist)
198
0a24e44d
JW
199asnop : ASSIGN (NONE)
200 | PLUSEQ (SOME(A.PLUS))
201 | MINUSEQ (SOME(A.MINUS))
202 | STAREQ (SOME(A.TIMES))
203 | SLASHEQ (SOME(A.DIVIDEDBY))
204 | PERCENTEQ (SOME(A.MODULO))
205 | LSHEQ (SOME(A.LSH))
206 | RSHEQ (SOME(A.RSH))
207 | BITOREQ (SOME(A.BITOR))
208 | BITANDEQ (SOME(A.BITAND))
209 | BITXOREQ (SOME(A.BITXOR))
This page took 0.040281 seconds and 4 git commands to generate.