1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
|
{-
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
|