/usr/share/doc/frown-doc/examples/other/TermX.g is in frown-doc 0.6.2.3-4.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 | {-
This example illustrates the use of multiple attributes that are
simultaneously evaluated.
frown TermX.g
Try
start (lexer "87-(8+23)") :: IO (Int,Expr)
-}
module TermX
where
import Char
type Op = Int -> Int -> Int
data AddOp = Plus | Minus
deriving (Show)
data Expr = Add Expr AddOp Expr
| Const Int
deriving (Show)
type Result = IO
%{
Terminal = NAT {Int} | ADDOP {Op} {AddOp} | LPAR | RPAR | EOF;
Nonterminal = start {Int} {Expr} | expr {Int} {Expr} | term {Int} {Expr};
start {v} {e}
: expr {v} {e}, EOF;
expr {v1 `f` v2} {Add e1 op e2}
: expr {v1} {e1}, ADDOP {f} {op}, term {v2} {e2};
expr {v} {e}
: term {v} {e};
term {n} {Const n}
: NAT {n};
term {v} {e}
: LPAR, expr {v} {e}, RPAR;
}%
frown ts = fail "syntax error"
data Terminal = NAT Int | ADDOP Op AddOp | LPAR | RPAR | EOF
lexer :: String -> [Terminal]
lexer [] = [EOF]
lexer ('+' : cs) = ADDOP (+) Plus : lexer cs
lexer ('-' : cs) = ADDOP (-) Minus : lexer cs
lexer ('(' : cs) = LPAR : lexer cs
lexer (')' : cs) = RPAR : lexer cs
lexer (c : cs)
| isDigit c = let (n, cs') = span isDigit cs
in NAT (read (c : n)) : lexer cs'
| otherwise = lexer cs
|