Upcoming SlideShare
×

# Parsec

465 views

Published on

Published in: Technology, Education
1 Like
Statistics
Notes
• Full Name
Comment goes here.

Are you sure you want to Yes No
• Be the first to comment

Views
Total views
465
On SlideShare
0
From Embeds
0
Number of Embeds
5
Actions
Shares
0
4
0
Likes
1
Embeds 0
No embeds

No notes for slide

### Parsec

1. 1. A Very Quick Tour of Parsec For the LA Haskell User Group Setup: :set +m :set -XNoMonomorphismRestriction import Text.Parsec import Control.Monad
2. 2. Types :i Parsec ParsecT :i State
3. 3. Escaping the Monad :t runParser :t runParserT :t parse :t parseTest
4. 4. Demonstration parseTest (char 'a') "a" parseTest (char 'a') "ab" parseTest (char 'a') "d"
5. 5. Simple Parsers :t oneOf :t letter :t digit :t space
6. 6. Do Notation fmap f p Parse using p and apply f to the result p >>= q Parse using p first, and then using q, possibly using the result of p. do { x ← … ; y ← … ; … } Combine several parse results
7. 7. Modifying Parsers :t many :t count :t chainl :t chainr
8. 8. Parsing Phone Book Entries let tel = do g1 <- count 3 digit; char '-' g2 <- count 3 digit char '-' g3 <- count 4 digit return (g1, g2, g3)
9. 9. Parsing Phone Book Entries let name = many1 letter let fullName = do last <- name char ',' space first <- name return (first, last)
10. 10. Parsing Phone Book Entries let phoneBook = do (first, last) <- fullName space char '(' (g1, g2, g3) <- tel char ')' return (first, last, g1, g2, g3)
11. 11. Parsing Phone Book Entries parseTest phoneBook "Freeman, Phillip (555-555-5555)"
12. 12. Combining Parsers :t sepBy :t (<|>)
13. 13. Handling Failure :t try :t <?>
14. 14. Handling Multiple First Names let nameSep = try \$ do space notFollowedBy (char '(') let fullName = do last <- name char ',' space rest <- sepBy1 name nameSep return \$ rest ++ [last]
15. 15. Handling Multiple First Names let phoneBook = do names <- fullName space char '(' (g1, g2, g3) <- tel char ')' return (names, g1, g2, g3)
16. 16. Parsing Phone Book Entries parseTest phoneBook "Freeman, Phillip Antony (555-555- 5555)"
17. 17. User State Parsec(T) is a state monad, so we can carry around user state as well as the parser's internal state. :t getState :t setState :t modifyState
18. 18. Example - { an bn | n ≥ 0 } let a = liftM2 (curry fst) (char 'a') (modifyState succ) an bn = do as <- many a n <- getState bs <- count n \$ char 'b' eof return \$ as ++ bs
19. 19. Example - { an bn | n ≥ 0 } runParser an bn 0 "" "aaabb" runParser an bn 0 "" "aabb" runParser an bn 0 "" "aabbb"
20. 20. Example – Print Debugging let char' c = lift (print c) >> char c chars = many \$ (char' 'a') <|> (char' 'b') runParserT chars () "" "aabb"
21. 21. Expression Parsers import Text.Parsec.Expr :t buildExpressionParser :i Operator OperatorTable Assoc
22. 22. Example - Expression Parsers let number = fmap read \$ many1 digit bracket = between (char '(') (char ')') numExpr atom = bracket <|> number numExpr = buildExpressionParser [ [ Infix (do { char '/'; return (/) }) AssocRight , Infix (do { char '*'; return (*) }) AssocRight ] , [ Infix (do { char '+'; return (+) }) AssocRight , Infix (do { char '-'; return (-) }) AssocRight ] , [ Prefix \$ do { char '-'; return negate } ] ] atom
23. 23. Example - Expression Parsers parseText numExpr “(1+2*4)/3”
24. 24. Language Definitions import Text.Parsec.Token import Text.Parsec.Language :i GenLanguageDef GenTokenParser
25. 25. Language Definitions let langDef = haskellStyle -- { ... } let parser = makeTokenParser langDef let stringLiteral' = stringLiteral parser integer' = integer parser float' = float parser lexeme' = lexeme parser
26. 26. Language Definitions parseTest stringLiteral' ""Test"" parseTest (lexeme' stringLiteral') ""Test" {-# Comment #-}"