{ module Parser where import Lexer import Core.Grammar } %name parseTokens %tokentype { Token } %error { parseError } %token int { T TokenInt p $$ } var { T TokenSym p $$ } '+' { T TokenAdd p _ } '-' { T TokenMin p _ } '*' { T TokenMul p _ } '/' { T TokenDiv p _ } '=' { T TokenAssign p _ } lambda { T TokenLamVars p _ } '.' { T TokenLamExpr p _ } lt { T TokenLT p _ } lte { T TokenLTE p _ } eq { T TokenEQ p _ } neq { T TokenNEQ p _ } gte { T TokenGTE p _ } gt { T TokenGT p _ } and { T TokenAnd p _ } or { T TokenOr p _ } let { T TokenLet p _ } letrec { T TokenLetRec p _ } in { T TokenIn p _ } case { T TokenCase p _ } of { T TokenOf p _ } arrow { T TokenArrow p _ } Pack { T TokenPack p _ } '{' { T TokenLBrace p _ } '}' { T TokenRBrace p _ } '(' { T TokenLParen p _ } ')' { T TokenRParen p _ } ';' { T TokenSemiColon p _ } ',' { T TokenComma p _ } %right ';' in %nonassoc gt lt gte lte eq neq '.' Pack int var arrow '}' '{' '(' ')' %left '+' '-' %left '*' '/' and or %% program : sc { [$1] } | sc ';' program { $1 : $3 } sc : var vars '=' expr { ($1, $2, $4) } vars : { [] } | var vars { $1 : $2 } expr : expr aexpr { EAp $1 $2 } | expr '+' expr { EAp (EAp (EVar "+") $1) $3 } | expr '-' expr { EAp (EAp (EVar "-") $1) $3 } | expr '*' expr { EAp (EAp (EVar "*") $1) $3 } | expr '/' expr { EAp (EAp (EVar "/") $1) $3 } | expr and expr { EAp (EAp (EVar "and") $1) $3 } | expr or expr { EAp (EAp (EVar "or") $1) $3 } | expr lt expr { EAp (EAp (EVar "<") $1) $3 } | expr lte expr { EAp (EAp (EVar "<=") $1) $3 } | expr eq expr { EAp (EAp (EVar "==") $1) $3 } | expr neq expr { EAp (EAp (EVar "/=") $1) $3 } | expr gte expr { EAp (EAp (EVar ">=") $1) $3 } | expr gt expr { EAp (EAp (EVar ">") $1) $3 } | let defns in expr { ELet nonRecursive $2 $4 } | letrec defns in expr { ELet recursive $2 $4 } | case expr of alts { ECase $2 $4 } | lambda var vars '.' expr { ELam ($2 : $3) $5 } | aexpr { $1 } aexpr : var { EVar $1 } | int { ENum (read $1 :: Int) } | Pack '{' int ',' int '}' '('exprs')' { EConstr (read $3 :: Int) (read $5 :: Int) $8} | '('expr')' { $2 } exprs : { [] } | exprsH { $1 } exprsH : expr { [$1] } | expr ',' exprsH { $1 : $3 } defns : defn { [$1] } | defn ';' defns { $1 : $3 } defn : var '=' expr { ($1, $3) } alts : alt ';' { [$1] } | alt ';' alts { $1 : $3 } alt : lt int gt vars arrow expr { ((read $2 :: Int), $4, $6) } { type IsRec = Bool recursive :: IsRec recursive = True nonRecursive :: IsRec nonRecursive = False parseError :: [Token] -> a parseError ts = case ts of [] -> error "unexpected end of file" token@(T t p s):_ -> error $ "parse error " ++ showPos p ++ " - unexpected '" ++ show token ++ "'" }