module ReadExprMonadic where -- Taking advantage of the instance Parser Monad import Parsing import Data.Char import Test.QuickCheck ---------------------------------------- data Expr = Num Integer | Add Expr Expr | Mul Expr Expr deriving (Eq,Show) {- BNF grammar: (not Haskell!) ::= | "+" ::= | "*" ::= "(" ")" | -} -- we could use reads to define this as before, but this would be dependent on the -- internal representation of the parser num = pmap Num int nat :: Parser Integer nat = -- pmap read $ oneOrMore digit do ds <- oneOrMore digit return (read ds) int = nat +++ negative where negative = -- char '-' >-> pmap (\x -> -x) nat do char '-' n <- nat return (-n) -- expr = chain term '+' Add -- term = chain factor '*' Mul factor = char '(' >-> expr <-< char ')' +++ num expr = do t <- term char '+' e <- expr return (Add t e) +++ term term = do f <- factor char '*' t <- term return (Mul f t) +++ factor {- BNF grammar: (not Haskell!) ::= | "+" ::= | "*" ::= "(" ")" | -} chain p c f = do a <- p as <- zeroOrMore (char c >-> p) return (foldr1 f (a:as)) --pmap (foldr1 f) $ p <:> zeroOrMore (char c >-> p)