Safe Haskell | Safe-Infered |
---|
Parser
Description
A parsing module, adapted from "Haskell: The Craft of Functional Programming", 2nd ed., S. Thompson.
- type Parser a b = [a] -> [(b, [a])]
- none :: Parser a b
- success :: b -> Parser a b
- token :: Eq a => a -> Parser a a
- spot :: (a -> Bool) -> Parser a a
- alt :: Parser a b -> Parser a b -> Parser a b
- (>*>) :: Parser a b -> Parser a c -> Parser a (b, c)
- transform :: Parser a b -> (b -> c) -> Parser a c
- optional :: Parser a b -> Parser a [b]
- maxOptional :: Parser a b -> Parser a [b]
- list :: Parser a b -> Parser a [b]
- neList :: Parser a b -> Parser a [b]
- maxList :: Parser a b -> Parser a [b]
- maxNeList :: Parser a b -> Parser a [b]
- spotWhile0 :: (a -> Bool) -> Parser a [a]
- spotWhile1 :: (a -> Bool) -> Parser a [a]
- result :: Parser a b -> [a] -> b
Documentation
type Parser a b = [a] -> [(b, [a])]
The type of parsing functions.
They take a list of objects of type a
e.g., characters, and return a list
of successful parses. Each parse is represented as a pair between the extracted
object, of type b
e.g., integer, and the list of objects designating
the remaining input.
Examples are given below, where bracket
and number
are parsers:
>>>
bracket "(xyz)"
[('(', "xyz)")] - one successful parse
>>>
number 23
[(2, "3"), (23, "")] - two successful parses
>>>
bracket 234
[] - no successful parse
Parses an explicitly given value, without consuming any input.
Examples:
>>>
success 23 "abc"
[(23, "abc")]
token :: Eq a => a -> Parser a a
Recognizes a given token.
Examples:
>>>
token 'a' "abc"
[('a', "bc")]
>>>
token 'a' "bbc"
[]
spot :: (a -> Bool) -> Parser a a
Recognizes a token that satisfies a given property.
Examples:
>>>
spot isLetter "abc"
[('a', "bc")]
>>>
spot isLetter "123"
[]
token
can be defined starting from spot
as below (any of the two options):
token t = spot (== t)
token = spot . (==)
alt :: Parser a b -> Parser a b -> Parser a b
The alternative between two parsers.
The parsing succeeds if any of the two parsers is able to parse. It simply concatenates the lists of parses obtained by the two parsers.
By employing the infix notation, `alt`
, any number of parsers can be
legibly chained.
Examples:
>>>
((token 'a') `alt` (token 'b') `alt` (spot isDigit)) "abc"
[('a', "bc")]
>>>
((token 'a') `alt` (token 'b') `alt` (spot isDigit)) "123"
[('1', "23")]
(>*>) :: Parser a b -> Parser a c -> Parser a (b, c)
The concatenation of two parsers, using a right-associative infix operator.
The parsing succeeds if the first parser is able to parse, starting at the beginning of the input, and the second one is able to parse, starting from the remainder of the input.
Examples:
>>>
((token 'a') >*> (token 'b') >*> (spot isDigit)) "ab2p"
[(('a', ('b', '2')), "p")]
>>>
((token 'a') >*> (token 'b') >*> (spot isDigit)) "abp"
[]
transform :: Parser a b -> (b -> c) -> Parser a c
Applies a given function onto the result of a given parser.
Examples:
>>>
((spot isLetter) `transform` toUpper) "abc"
[('A', "bc")]
optional :: Parser a b -> Parser a [b]
Either recognizes an object or succeeds immediately, given a parser for that object.
The parse result is returned as a list, so an empty match may be indicated.
Examples:
>>>
optional (token 'a') "a"
[("", "a"), ("a", "")]
>>>
optional (token 'a') "b"
[("", "b")]
maxOptional :: Parser a b -> Parser a [b]
Recognizes an object, if it is present, given a parser for that object.
The parse result is returned as a list, so an empty match may be indicated.
Examples:
>>>
maxOptional (token 'a') "a"
[("a", "")]
>>>
maxOptional (token 'a') "b"
[("", "b")]
list :: Parser a b -> Parser a [b]
Parses possibly empty lists of objects, given a parser for a single object.
Examples:
>>>
(list (spot isLetter)) "abc123"
[("", "abc123"), ("a", "bc123"), ("ab", "c123"), ("abc", "123")]
neList :: Parser a b -> Parser a [b]
Parses non-empty lists of objects, given a parser for a single object.
Examples:
>>>
(neList (spot isLetter)) "abc123"
[("a", "bc123"), ("ab", "c123"), ("abc", "123")]
maxList :: Parser a b -> Parser a [b]
Parses the longest, possibly empty, list of objects, given a parser for a single object.
Examples:
>>>
(maxList (spot isLetter)) "abc123"
[("abc", "123")]
>>>
(maxList (spot isLetter)) "123"
[("", "123")]
maxNeList :: Parser a b -> Parser a [b]
Parses the longest non-empty list of objects, given a parser for a single object.
Examples:
>>>
(maxNeList (spot isLetter)) "abc123"
[("abc", "123")]
>>>
(maxNeList (spot isLetter)) "123"
[]
spotWhile0 :: (a -> Bool) -> Parser a [a]
Parses the longest, possibly empty, list of objects, given a property that the objects must satisfy.
Examples:
>>>
(spotWhile0 isLetter) "abc123"
[("abc", "123")]
>>>
(spotWhile0 isLetter) "123"
[("", "123")]
spotWhile1 :: (a -> Bool) -> Parser a [a]
Parses the longest non-empty list of objects, given a property that the objects must satisfy.
Examples:
>>>
(spotWhile1 isLetter) "abc123"
[("abc", "123")]
>>>
(spotWhile1 isLetter) "123"
[]
result :: Parser a b -> [a] -> b
Parses the entire input, using a given parser, and returns the corresponding result, stripping off the remainder part, which is empty anyway, since the input has been completely parsed.
Examples:
>>>
result (spotWhile1 isLetter) "abc"
"abc"
>>>
result (spotWhile1 isLetter) "abc1"
<error>