/* Use the expression datatype defined in expressions.ml: */ %{ open Expressions let rec braceListContentsIntoExp seq = match seq with [] -> Const "nil" | e :: s -> App(App(Const "cons",e),braceListContentsIntoExp s) %} /* Define the tokens of the language: */ %token NAT %token BOOL %token STRING VAR %token DBLSEMI LET DOT EQUALS NEQ LPAREN RPAREN COMMA SEMI LBRAC RBRAC FIX PLUS MINUS DIV MOD CARET TIMES OR AND LT GEQ LEQ GT NOT DBLCOLON IF THEN ELSE IN FUN RARROW PIPE LARROW UNIT DUMMY FST SND HEAD TAIL NIL /* Define the "goal" nonterminal of the grammar: */ %start prog %type prog %type exp %type decl %% prog: seqOfDecl DBLSEMI { $1 } seqOfDecl: decl { [$1] } | decl seqOfDecl { $1 :: $2 } decl: LET VAR EQUALS exp { Let($2,$4) } exp: construct_exp { $1 } | other { $1 } construct_exp: IF exp THEN exp ELSE exp { App(App(App(Const "if", $2),$4),$6) } | FIX VAR DOT exp { Rec($2,$4) } | FUN VAR RARROW exp { Fun($2,$4) } other: nonCompar { $1 } | nonCompar2 { $1 } | nonCompar EQUALS other { App(App(Const("eq"),$1),$3) } | nonCompar EQUALS construct_exp { App(App(Const("eq"),$1),$3) } nonCompar: nonComma { $1 } | nonCompar COMMA nonComma { App(App(Const("comma"),$1),$3) } nonCompar2: nonComma2 { $1 } | nonCompar COMMA construct_exp { App(App(Const("comma"),$1),$3) } | nonCompar COMMA nonComma2 { App(App(Const("comma"),$1),$3) } nonComma: nonOr { $1 } | nonComma OR nonOr { App(App(Const("or"),$1),$3) } nonComma2: nonOr2 { $1 } | nonComma OR construct_exp { App(App(Const("or"),$1),$3) } | nonComma OR nonOr2 { App(App(Const("or"),$1),$3) } nonOr: nonAnd { $1 } | nonOr AND nonAnd { App(App(Const("and"),$1),$3) } nonOr2: nonAnd2 { $1 } | nonOr AND construct_exp { App(App(Const("and"),$1),$3) } | nonOr AND nonAnd2 { App(App(Const("and"),$1),$3) } nonAnd: nonPl { $1 } | nonAnd PLUS nonPl { App(App(Const("plus"), $1),$3) } nonAnd2: nonPl2 { $1 } | nonAnd PLUS construct_exp { App(App(Const("plus"), $1),$3) } | nonAnd PLUS nonPl2 { App(App(Const("plus"), $1),$3) } nonPl: nonTm { $1 } | nonPl TIMES nonTm { App(App(Const("times"),$1),$3) } nonPl2: nonTm2 { $1 } | nonPl TIMES construct_exp { App(App(Const("times"),$1),$3) } | nonPl TIMES nonTm2 { App(App(Const("times"),$1),$3) } nonTm: nonApp { $1 } | nonTm nonApp { App($1,$2) } nonTm2: | nonApp construct_exp { App($1,$2) } | nonTm nonApp construct_exp { App(App($1,$2),$3) } nonApp: VAR { Var($1) } | FST { Const("fst") } | SND { Const("snd") } | NAT { Natexp $1 } | BOOL { Boolexp $1 } | STRING { Stringexp $1 } | LPAREN exp RPAREN { $2 }