/usr/share/doc/frown-doc/examples/other/Calc.g is in frown-doc 0.6.1-14.
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 | {-
A simple desk calculator.
frown Calc.g
Try
expr (lexer "1+2*4") :: [Int]
-}
module Calc
where
import Char
instance Show (a -> b) where show _ = "<function>"
type Op = Int -> Int -> Int
type Result = []
%{
Terminal = NAT {Int} | ADDOP {Op} | MULOP {Op} | LPAR | RPAR | *EOF;
Nonterminal = *expr {Int} | term {Int} | factor {Int};
expr {v1 `op` v2} : expr {v1}, ADDOP {op}, term {v2};
expr {e} : term {e};
term {v1 `op` v2} : term {v1}, MULOP {op}, factor {v2};
term {e} : factor {e};
factor {e} : LPAR, expr {e}, RPAR;
factor {n} : NAT {n};
}%
frown ts = fail ("syntax error: " ++ show ts)
data Terminal = NAT Int | ADDOP Op | MULOP Op | LPAR | RPAR | EOF
deriving (Show)
lexer :: String -> [Terminal]
lexer [] = [EOF]
lexer ('+' : cs) = ADDOP (+) : lexer cs
lexer ('-' : cs) = ADDOP (-) : lexer cs
lexer ('*' : cs) = MULOP (*) : lexer cs
lexer ('/' : cs) = MULOP div : 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
|