{- frown Lambda.lg -} > module Lambda > where > import Char > > type Var = String > > data Expr = Var Var > | App Expr Expr > | Abs Var Expr > deriving (Show) > > %{ > > Terminal = Ident {String} > | Dot as "." > | LPar as "(" > | RPar as ")" > | Backslash as "fun"; > > Nonterminal = expr {Expr} > | aexprs {[Expr]} > | aexpr {Expr}; > > expr {Abs x e} : "fun", Ident {x}, ".", expr {e}; > {foldl1 App es} | aexprs {es}; > > aexprs {[e]} : aexpr {e}; > {es ++ [e]} | aexprs {es}, aexpr {e}; > > aexpr {Var x} : Ident {x}; > {e} | "(", expr {e}, ")"; > > }% > > frown ts = fail "syntax error" > > data Terminal = Ident String > | Dot > | LPar > | RPar > | Backslash > deriving (Show) > > lexer :: String -> [Terminal] > lexer [] = [] > lexer ('.' : cs) = Dot : lexer cs > lexer ('(' : cs) = LPar : lexer cs > lexer (')' : cs) = RPar : lexer cs > lexer ('\\' : cs) = Backslash : lexer cs > lexer (c : cs) > | isAlpha c = Ident (c : n) : lexer cs' > | otherwise = lexer cs > where (n, cs') = span isAlphaNum cs