+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)