-- Bonus lecture, Part 1: Another example of "instructions" -- Instructions for parsing import Parsing -- A small library for Parsing strings into things -- parse :: Parser a -> String -> Maybe (a, String) import Data.Char import Data.Maybe -- Example: parsing phone numbers in one of two formats: data PhoneNr = Global Int Int | Local Int deriving Show showNr (Global cc n) = "+" ++ show cc ++ " " ++ show n showNr (Local n) = '0':show n work = Local 7372076 home = Global 46 73720766 -- Library: char, digit countryCode :: Parser Int countryCode = do char '+' d1 <- digit d2 <- digit return (read [d1,d2]) -- Library functions: oneOrMore nat :: Parser Int nat = do ds <- oneOrMore digit return (read ds) -- Library: (+++) phoneP:: Parser PhoneNr phoneP = localP +++ globalP where localP = do n <- nat return \$ Local n globalP = do cc <- countryCode char ' ' n <- nat return (Global cc n) -- Library: sat and chain phoneList :: Parser [PhoneNr] -- list of comma- or semicolon- separated phone numbers phoneList = chain phoneP (sat sep) -- (char ';' +++ char ',') -- sat where sep c = c `elem` ";," --------------------------------------------------- data Expr = Num Int | Add Expr Expr | Mul Expr Expr deriving (Eq ,Show ) -- Parsing arithmetic expressions: expr,term,factor :: Parser Expr -- expressions are a sum of one or more terms expr = do es <- chain term (char '+') return \$ foldr1 Add es -- terms are products of one or more factors term = do fs <- chain factor (char '*') return \$ foldr1 Mul fs -- factors are an expression in brackets or a number factor = bracketed +++ num where bracketed = do char '(' e <- expr char ')' return e num = do n <- nat -- negative numbers as an exercise return \$ Num n