parser Triv: top Expression -- Expressions Expression :: Integer = Spacing v:Additive !Char -> { v } Additive :: Integer = l:Additive "+":Symbol r:Multitive -> { l + r } / l:Additive "-":Symbol r:Multitive -> { l - r } / v:Multitive -> { v } Multitive :: Integer = l:Multitive "*":Symbol r:Primary -> { l * r } / l:Multitive "/":Symbol r:Primary -> { l `div` r } / l:Multitive "%":Symbol r:Primary -> { l `mod` r } / v:Primary -> { v } Primary :: Integer = v:Decimal -> { v } / "(":Symbol v:Additive ")":Symbol -> { v } -- Decimal literals Decimal :: Integer = v:Digits Spacing -> { v } Digits :: Integer = v:Digits d:Digit -> { v * 10 + toInteger d } / d:Digit -> { toInteger d } Digit :: Int = c:Char &{isDigit c} -> { digitToInt c } -- Symbols Symbol :: String = s:SymChars Spacing -> { s } SymChars :: String = "+" / "-" / "*" / "/" / "%" / "(" / ")" -- Spacing between tokens Spacing :: {()} = SpaceChar* -> { () } SpaceChar :: Char = c:Char &{isSpace c} -> { c } { eval :: String -> Integer eval str = case trivExpression (trivParse "expression" str) of Parsed v _ _ -> v NoParse e -> error (show e) }