changeset 30:8bf7ca2663d2

Advanced AdditionParser
author Markus Kaiser <markus.kaiser@in.tum.de>
date Sat, 12 Jan 2013 14:36:43 +0000
parents 53732b9605c7
children d14aab8bbf36
files exercises/src/AdditionParser2.hs
diffstat 1 files changed, 53 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/exercises/src/AdditionParser2.hs	Sat Jan 12 14:36:43 2013 +0000
@@ -0,0 +1,53 @@
+module AdditionParser2 where
+
+import Data.Char
+import Parser
+
+data Token = Num Int | Plus | Times | LeftPar | RightPar deriving (Show, Eq)
+
+-- Scanner (Lexer)
+digitS :: Parser Char Int
+digitS = one isDigit >>> digitToInt
+
+numberS :: Parser Char Int
+numberS = list1 (one isDigit) >>> (\n -> read n :: Int)
+
+additionS :: Parser Char [Token]
+additionS = list (spaces *** token >>> snd) *** spaces >>> fst
+    where
+        spaces = list $ item ' '
+        token = item '(' >>> const LeftPar |||
+                item ')' >>> const RightPar |||
+                item '+' >>> const Plus |||
+                item '*' >>> const Times |||
+                numberS >>> Num
+
+-- Parser
+additionP :: Parser Token Int
+additionP = additionP1 *** optional (item Plus *** additionP >>> snd) >>> ints
+    where
+        ints (x, Just y) = x + y
+        ints (x, _) = x
+
+additionP1 :: Parser Token Int
+additionP1 = additionP2 *** optional (item Times *** additionP1 >>> snd) >>> ints
+    where
+        ints (x, Just y) = x * y
+        ints (x, _) = x
+
+additionP2 :: Parser Token Int
+additionP2 =
+    one isNum >>> int |||
+    enclose LeftPar RightPar additionP
+    where
+        isNum (Num _) = True
+        isNum (_) = False
+        int (Num n) = n
+
+-- Composition
+additionSP :: String -> Maybe (Int, [Token])
+additionSP xs = case additionS xs of
+                    Just (ys, []) -> additionP ys
+                    _ -> Nothing
+
+test = additionSP "2*4+10+(2+2)*2"