-(* L2 Compiler
- * L2 grammar
+(* L3 Compiler
+ * L3 grammar
* Author: Kaustuv Chaudhuri <kaustuv+@cs.cmu.edu>
* Modified: Frank Pfenning <fp@cs.cmu.edu>
* Modified: Joshua Wise <jwise@andrew.cmu.edu>
mark(A.OpExp(oper, [exp1, exp2]), (left, right)))
%%
-%header (functor L2LrValsFn (structure Token : TOKEN))
+%header (functor L3LrValsFn (structure Token : TOKEN))
%term
EOF
| LBRACE | RBRACE
| LPAREN | RPAREN
| UNARY | ASNOP (* dummy *)
+ | EXTERN | VAR | INT | COLON | COMMA
%nonterm
program of A.program
| simp of A.stm
| return of A.stm
| exp of A.exp
+ | explist of A.exp list
| control of A.stm
| asnop of A.oper option
| block of A.stm list
| simpoption of A.stm option
| elseoption of A.stm list option
+ | idents of A.ident list
+ | vtype of A.vtype
+ | extdecls of A.function list
+ | extdecl of A.function
+ | paramlist of A.variable list
+ | param of A.variable
+ | functions of A.function list
+ | function of A.function
+ | vardecl of A.variable list
+ | vardecls of A.variable list
%verbose (* print summary of errors *)
%pos int (* positions *)
%eop EOF
%noshift EOF
-%name L2
+%name L3
%left LOGOR
%left LOGAND
%%
-program : LBRACE stms RBRACE
- (stms)
+program : extdecls functions (extdecls @ functions)
+
+vtype : INT (A.Int)
+
+extdecls : ([])
+ | extdecl extdecls (extdecl :: extdecls)
+
+extdecl : EXTERN vtype IDENT LPAREN RPAREN SEMI
+ (A.Extern (vtype, IDENT, []))
+ | EXTERN vtype IDENT LPAREN param RPAREN SEMI
+ (A.Extern (vtype, IDENT, [param]))
+ | EXTERN vtype IDENT LPAREN paramlist RPAREN SEMI
+ (A.Extern (vtype, IDENT, paramlist))
+
+paramlist : param COMMA paramlist (param :: paramlist)
+ | param ([param])
+
+param : IDENT COLON vtype (IDENT, vtype)
+
+functions : ([])
+ | function functions (function :: functions)
+
+function : vtype IDENT LPAREN RPAREN LBRACE vardecls stms RBRACE
+ (A.Function (vtype, IDENT, [], vardecls, stms))
+ | vtype IDENT LPAREN paramlist RPAREN LBRACE vardecls stms RBRACE
+ (A.Function (vtype, IDENT, paramlist, vardecls, stms))
+
+vardecls : ([])
+ | vardecl vardecls (vardecl @ vardecls)
+
+vardecl : VAR idents COLON vtype SEMI
+ (map (fn x => (x, vtype)) idents)
+
+idents : IDENT ([IDENT])
+ | IDENT COMMA idents (IDENT :: idents)
stms : ([])
| stm stms (stm :: stms)
-stm : simp SEMI (simp)
- | control (control)
- | SEMI (A.Nop)
+stm : simp SEMI (simp)
+ | control (control)
+ | SEMI (A.Nop)
simp : exp asnop exp %prec ASNOP
(expand_asnop (exp1, asnop, exp2) (exp1left, exp2right))
| exp LE exp (mark (A.OpExp (A.LE, [exp1,exp2]), (exp1left,exp2right)))
| exp GT exp (mark (A.OpExp (A.GT, [exp1,exp2]), (exp1left,exp2right)))
| exp GE exp (mark (A.OpExp (A.GE, [exp1,exp2]), (exp1left,exp2right)))
+ | IDENT LPAREN RPAREN (mark (A.FuncCall(IDENT, []), (IDENTleft, RPARENright)))
+ | IDENT LPAREN exp RPAREN
+ (mark (A.FuncCall(IDENT, [exp]), (IDENTleft, RPARENright)))
+ | IDENT LPAREN explist RPAREN
+ (mark (A.FuncCall(IDENT, explist), (IDENTleft, RPARENright)))
| MINUS exp %prec UNARY (mark (A.OpExp (A.NEGATIVE, [exp]), (MINUSleft,expright)))
| BITNOT exp %prec UNARY (mark (A.OpExp (A.BITNOT, [exp]), (BITNOTleft,expright)))
| BANG exp %prec UNARY (mark (A.OpExp (A.BANG, [exp]), (BANGleft,expright)))
+explist : exp ([exp])
+ | exp COMMA explist (exp :: explist)
+
asnop : ASSIGN (NONE)
| PLUSEQ (SOME(A.PLUS))
| MINUSEQ (SOME(A.MINUS))