This example demonstrates rule schemata. frown List.lg Try expr (lexer "a (b c d) e (f g)") :: Maybe Expr > module List > where > import Char > > data Expr = Id String > | Call String [Expr] > deriving (Show) > > type Result = Maybe > > %{ > > Terminal = Ident {String} > | "(" = LPar > | ")" = RPar > | "," = Comma; > > --test; > --test : many (Ident {}) {is}; > > :: expr {Expr}; > expr {Call s es} : Ident {s}, many aexpr {es}; > > :: aexpr {Expr}; > aexpr {Id s} : Ident {s}; > {e} | "(", expr {e}, ")"; List scheme (predefined). > {- > :: many x {[a]} <- x {a}; > many x {[]} : ; > {as ++ [a]} | many x {as}, x {a}; > -} > > }% > > frown ts = fail "syntax error" > > data Terminal = Ident String | LPar | RPar | Comma > deriving (Show) > > lexer :: String -> [Terminal] > lexer [] = [] > lexer ('(' : cs) = LPar : lexer cs > lexer (')' : cs) = RPar : lexer cs > lexer (',' : cs) = Comma : lexer cs > lexer (c : cs) > | isAlpha c = let (n, cs') = span isAlphaNum cs > in Ident (c : n) : lexer cs' > | otherwise = lexer cs