-- An example demonstrating how to connect a Happy parser to an Alex lexer. { import Tokens_posn } %name calc %tokentype { Token } %token let { Let _ } in { In _ } int { Int _ $$ } var { Var _ $$ } '=' { Sym _ '=' } '+' { Sym _ '+' } '-' { Sym _ '-' } '*' { Sym _ '*' } '/' { Sym _ '/' } '(' { Sym _ '(' } ')' { Sym _ ')' } %% Exp :: { Exp } Exp : let var '=' Exp in Exp { LetE $2 $4 $6 } | Exp1 { $1 } Exp1 : Exp1 '+' Term { PlusE $1 $3 } | Exp1 '-' Term { MinusE $1 $3 } | Term { $1 } Term : Term '*' Factor { TimesE $1 $3 } | Term '/' Factor { DivE $1 $3 } | Factor { $1 } Factor : '-' Atom { NegE $2 } | Atom { $1 } Atom : int { IntE $1 } | var { VarE $1 } | '(' Exp ')' { $2 } { data Exp = LetE String Exp Exp | PlusE Exp Exp | MinusE Exp Exp | TimesE Exp Exp | DivE Exp Exp | NegE Exp | IntE Int | VarE String deriving Show main:: IO () main = interact (show.runCalc) runCalc :: String -> Exp runCalc = calc . alexScanTokens happyError :: [Token] -> a happyError tks = error ("Parse error at " ++ lcn ++ "\n") where lcn = case tks of [] -> "end of file" tk:_ -> "line " ++ show l ++ ", column " ++ show c where AlexPn _ l c = token_posn tk }