The standard example: arithmetic expressions (see dragon book p222).

	frown --debug Expr.lg

Try
	expr (lexer "a+b*c+d") :: [Expr]

Tracing the parse:

	frown --debug --trace Expr.g

Try
	expr (lexer "a+b*c+d")

> module Expr
> where
> import Char
>
> data AddOp                    =  Plus  | Minus
>                                  deriving (Show)
> data MulOp                    =  Times | Divide
>                                  deriving (Show)
>
> data Expr                     =  Id String
>                               |  Add Expr AddOp Expr
>                               |  Mul Expr MulOp Expr
>                                  deriving (Show)
>
> type Result                   =  []
>
> %{
>
> Terminal                      =         Ident {String}
>                               |         Addop {AddOp}
>                               |         Mulop {MulOp}
>                               |  "(" =  LPar
>                               |  ")" =  RPar
>                               |        *EOF;
>
>*expr {Expr};
> expr {Add e1 op e2}           :  expr {e1}, Addop {op}, term {e2};
>      {e}                      |  term {e};
>
> term {Expr};
> term {Mul e1 op e2}           :  term {e1}, Mulop {op}, factor {e2};
>      {e}                      |  factor {e};
>
>*factor {Expr};
> factor {e}                    :  "(", expr {e}, ")";
>        {Id s}                 |  Ident {s};
>
> }%
>
> frown ts                      =  fail "syntax error"
> 
> data Terminal                 =  Ident String
>                               |  Addop AddOp
>                               |  Mulop MulOp
>                               |  LPar
>                               |  RPar
>                               |  EOF
>                                  deriving (Show)
>
> lexer                         :: String -> [Terminal]
> lexer []                      =  [EOF]
> lexer ('+' : cs)              =  Addop Plus   : lexer cs
> lexer ('-' : cs)              =  Addop Minus  : lexer cs
> lexer ('*' : cs)              =  Mulop Times  : lexer cs
> lexer ('/' : cs)              =  Mulop Divide : lexer cs
> lexer ('(' : cs)              =  LPar : lexer cs
> lexer (')' : cs)              =  RPar : lexer cs
> lexer (c : cs)
>     | isAlpha c               =  let (n, cs') = span isAlphaNum cs
>                                  in  Ident (c : n) : lexer cs'
>     | otherwise               =  lexer cs
