%{ (* Parser for a small functional language (uML). One-argument functions only. sestoft@dina.kvl.dk * 2001-02-22, 2002-02-24 *) open Absyn; %} %token CSTINT %token NAME %token CSTBOOL %token ANDALSO ELSE END FALSE IF IN LET NOT ORELSE THEN TRUE %token PLUS MINUS TIMES EQ DIV MOD %token EQ NE GT LT GE LE %token LPAR RPAR %token EOF %left ELSE /* lowest precedence */ %left ORELSE %left ANDALSO %left EQ NE %nonassoc GT LT GE LE %left PLUS MINUS %left TIMES DIV MOD %nonassoc NOT /* highest precedence */ %start Main %type Main Expr AtExpr Const %type AppExpr %% Main: Expr EOF { $1 } ; Expr: AtExpr { $1 } | AppExpr { $1 } | IF Expr THEN Expr ELSE Expr { If($2, $4, $6) } | NOT Expr { Prim("!", [$2]) } | Expr PLUS Expr { Prim("+", [$1, $3]) } | Expr MINUS Expr { Prim("-", [$1, $3]) } | Expr TIMES Expr { Prim("*", [$1, $3]) } | Expr DIV Expr { Prim("/", [$1, $3]) } | Expr MOD Expr { Prim("%", [$1, $3]) } | Expr EQ Expr { Prim("=", [$1, $3]) } | Expr NE Expr { Prim("<>", [$1, $3]) } | Expr GT Expr { Prim(">", [$1, $3]) } | Expr LT Expr { Prim("<", [$1, $3]) } | Expr GE Expr { Prim(">=", [$1, $3]) } | Expr LE Expr { Prim("<=", [$1, $3]) } ; AtExpr: Const { $1 } | NAME { Var $1 } | LET NAME EQ Expr IN Expr END { Let($2, $4, $6) } | LET NAME NAME EQ Expr IN Expr END { Letfun($2, $3, $5, $7) } | LPAR Expr RPAR { $2 } ; AppExpr: AtExpr AtExpr { Call($1, $2) } | AppExpr AtExpr { Call($1, $2) } ; Const: CSTINT { CstI($1) } | CSTBOOL { CstB($1) } ;