]> Joshua Wise's Git repositories - snipe.git/blob - parse/l1.grm
41af15bd351a2b637e9f68bb1cae90b02eb430c9
[snipe.git] / parse / l1.grm
1 (* L1 Compiler
2  * L1 grammar
3  * Author: Kaustuv Chaudhuri <kaustuv+@cs.cmu.edu>
4  * Modified: Frank Pfenning <fp@cs.cmu.edu>
5  *)
6
7 structure A = Ast
8
9 (* for simplicity, we only mark expressions, not statements *)
10
11 (* mark e with region (left, right) in source file *)
12 fun mark (e, (left, right)) = A.Marked (Mark.mark' (e, ParseState.ext (left, right)))
13
14 (* create lval from expression; here just an id *)
15 (* generates error if not an identifier *)
16 fun make_lval (A.Var(id)) ext = id
17   | make_lval (A.Marked(marked_exp)) ext =
18       make_lval (Mark.data marked_exp) (Mark.ext marked_exp)
19   | make_lval _ ext = ( ErrorMsg.error ext "not a variable" ;
20                         Symbol.bogus )
21
22 (* expand_asnop (exp1, "op=", exp2) region = "exp1 = exp1 op exps"
23  * or = "exp1 = exp2" if asnop is "="
24  * generates error if exp1 is an lval (identifier)
25  * syntactically expands a compound assignment operator
26  *)
27 fun expand_asnop (exp1, NONE, exp2) (left, right) =
28       A.Assign(make_lval exp1 NONE, exp2)
29   | expand_asnop (exp1, SOME(oper), exp2) (left, right) =
30       A.Assign(make_lval exp1 NONE,
31                mark(A.OpExp(oper, [exp1, exp2]), (left, right)))
32
33 %%
34 %header (functor L1LrValsFn (structure Token : TOKEN))
35
36 %term 
37    EOF
38  | SEMI
39  | INTNUM of Word32.word
40  | IDENT of Symbol.symbol
41  | RETURN
42  | PLUS | MINUS | STAR | SLASH | PERCENT
43  | ASSIGN | PLUSEQ | MINUSEQ | STAREQ | SLASHEQ | PERCENTEQ
44  | LBRACE | RBRACE
45  | LPAREN | RPAREN
46  | UNARY | ASNOP (* dummy *)
47
48 %nonterm 
49    program of A.program
50  | stms of A.stm list
51  | stm of A.stm
52  | simp of A.stm
53  | return of A.stm
54  | exp of A.exp
55  | asnop of A.oper option
56
57 %verbose                                (* print summary of errors *)
58 %pos int                                (* positions *)
59 %start program
60 %eop EOF
61 %noshift EOF
62
63 %name L1
64
65 %left PLUS MINUS
66 %left STAR SLASH PERCENT
67 %right UNARY
68 %left LPAREN
69
70 %%
71
72 program    : LBRACE stms return RBRACE
73                                    (stms@[return])
74
75 return     : RETURN exp SEMI       (A.Return exp)
76
77 stms       :                       ([])
78            | stm stms              (stm :: stms)
79
80 stm        : simp SEMI             (simp)
81 simp       : exp asnop exp %prec ASNOP
82                                    (expand_asnop (exp1, asnop, exp2) (exp1left, exp2right))
83
84 exp        : LPAREN exp RPAREN     (exp)
85            | INTNUM                (mark (A.ConstExp(INTNUM),(INTNUMleft,INTNUMright)))
86            | IDENT                 (mark (A.Var(IDENT), (IDENTleft,IDENTright)))
87            | exp PLUS exp          (mark (A.OpExp (A.PLUS, [exp1,exp2]), (exp1left,exp2right)))
88            | exp MINUS exp         (mark (A.OpExp (A.MINUS, [exp1,exp2]), (exp1left,exp2right)))
89            | exp STAR exp          (mark (A.OpExp (A.TIMES, [exp1,exp2]), (exp1left,exp2right)))
90            | exp SLASH exp         (mark (A.OpExp (A.DIVIDEDBY, [exp1,exp2]), (exp1left,exp2right)))
91            | exp PERCENT exp       (mark (A.OpExp (A.MODULO, [exp1,exp2]), (exp1left,exp2right)))
92            | MINUS exp %prec UNARY (mark (A.OpExp (A.NEGATIVE, [exp]), (MINUSleft,expright)))
93
94 asnop      : ASSIGN                (NONE)
95            | PLUSEQ                (SOME(A.PLUS))
96            | MINUSEQ               (SOME(A.MINUS))
97            | STAREQ                (SOME(A.TIMES))
98            | SLASHEQ               (SOME(A.DIVIDEDBY))
99            | PERCENTEQ             (SOME(A.MODULO))
This page took 0.019875 seconds and 2 git commands to generate.