import Parsing -- 2015 Lecture week 5A part 1 -- Introducing a small library for Parsing strings into things -- parse :: Parser a -> String -> Maybe (a, String) -- See -- http://www.cse.chalmers.se/edu/course/TDA452/FPLectures/doc/Parsing.html for the API summary import Data.Char import Data.Maybe -- Example, parse phone numbers into the following data PhoneNr = Global Int Int | Local Int deriving Show -- Local 7372076 -- Global 46 73720766 -- Library: digit, oneOrMore -- Built-in parsers: read nat :: Parser Int -- a simple natural number parser nat = do ds <- oneOrMore digit return $ read ds -- Library: (+++) phoneNr :: Parser PhoneNr -- try to parse it as a local then a global number phoneNr = local +++ global global = do char '+' cc <- countryCode localbit <- nat return $ Global cc localbit local = do n <- nat return $ Local n -- equivalent to -- Local `fmap` nat countryCode :: Parser Int countryCode = do d1 <- digit d2 <- digit return $ read [d1,d2] -- Library: sat and chain phoneList :: Parser [PhoneNr] -- list of space separated phone numbers phoneList = chain phoneNr (sat isSpace) --------------------------------------------------- data Expr = Num Integer | Add Expr Expr | Mul Expr Expr deriving (Eq ,Show ) -- instance Show Expr where -- show = showExpr -- Main goal, to define a top level parser readExpr :: String -> Maybe Expr readExpr s = let s' = filter (not.isSpace) s in -- remove space first case parse expr s' of Just(e,"") -> Just e --no junk after successful parse _ -> Nothing num :: Parser Expr num = do ds <- oneOrMore digit return $ Num (read ds) -- equivalently: Num `fmap` nat -- leave negative nums as exercise -- Parsing arithmetic expressions: -- expressions are a sum of one or more terms -- terms are products of one or more factors -- factors are an expression in brackets or a number factor = num +++ do char '(' e <- expr char ')' return e term = do fs <- chain factor (char '*') return $ foldr1 Mul fs expr = do fs <- chain term (char '+') return $ foldr1 Add fs -- foldr1 Add [Num 1, Num 2, Num 3] == Add (Num 1) (Add (Num 2) (Num 3))