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 60 61 62 63 64 65 66 67 68 69 70 71 72
|
This example demonstrates rule schemata.
frown Schemes.lg
Try
expr (lexer "a (b c, d) e (f, g)") :: Maybe Expr
> module Schemes
> where
> import Char
>
> data Expr = Id String
> | Call String [Expr]
> | Tuple [Expr]
> deriving (Show)
>
> type Result = Maybe
>
> %{
>
> Terminal = Ident {String}
> | "(" = LPar
> | ")" = RPar
> | "," = Comma;
>
> :: expr {Expr};
> expr {Call s es} : Ident {s}, many aexpr {es};
>
> :: aexpr {Expr};
> aexpr {Id s} : Ident {s};
> {Tuple es} | "(", sepBy expr comma {es}, ")";
>
> :: comma;
> comma : ",";
Schemes (predefined).
> {-
> :: many x {[a]} <- x {a};
> many x {s []} : many' x {s};
>
> :: many' x {[a] -> [a]} <- x {a};
> many' x {\ as -> as} : ;
> {\ as -> s (a : as)} | many' x {s}, x {a};
>
> :: sepBy x sep {[a]} <- x {a}, sep;
> sepBy x sep {[]} : ;
> {as} | sepBy1 x sep {as};
>
> :: sepBy1 x sep {[a]} <- x {a}, sep;
> sepBy1 x sep {[a]} : x {a};
> {a : as} | x {a}, sep, sepBy1 x sep {as};
> -}
> }%
>
> 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
|