MaintainerCS 131, Programming Languages (Melissa O'Neill, Chris Stone, Ben Wiedermann)
Safe HaskellSafe

ParserCombinators

Description

 

Synopsis

Documentation

(>>=:) :: Functor parser => parser a -> (a -> b) -> parser b infixl 1 #

Given a parser, transform its result by passing it through a provided function

(>>:) :: Functor parser => parser a -> b -> parser b infixl 1 #

Given a parser, ignore is result and instead, if the parser succeeds always return a specific value.

(<+>) :: Applicative parser => parser a -> parser b -> parser (a, b) infixl 6 #

Given two parsers, p and q, makes a new parser for "p then q" that 1. runs the first parser on the input 2. runs the second parser on what remains in the input 3. returns a pair of their results If either of the parsers fail, the whole thing fails.

(<:>) :: Applicative parser => parser a -> parser [a] -> parser [a] infixr 5 #

Given two parsers, p and q, makes a new parser for "p then q" that 1. runs the first parser on the input to generate a thing 2. runs the second parser on what remains in the input to make a list of the same kind of thing 3. returns a list of things If either of the parsers fail, the whole thing fails.

(<++>) :: Applicative parser => parser [a] -> parser [a] -> parser [a] infixr 5 #

Given two parsers, p and q, makes a new parser for "p then q" that 1. runs the first parser on the input to generate a list 2. runs the second parser on what remains in the input to generate another list 3. concatenate the two lists If either of the parsers fail, the whole thing fails.

(<+->) :: Applicative parser => parser a -> parser b -> parser a infixl 6 #

(<-+>) :: Applicative parser => parser a -> parser b -> parser b infixl 6 #

(<-+->) :: Applicative parser => parser a -> parser b -> parser () infixl 6 #

(<=>) :: MonadPlus parser => parser a -> (a -> Bool) -> parser a infix 7 #

Given a parser and a predicate, return the result of the parser only if it also satisfies the predicate.

(<??>) :: Parser a -> String -> Parser a infixl 3 #

Given a parser p, makes a new parser where if p fails, the new parser also fails, but unconditionally replaces p's error message with errMsg. All error information from p (including how far it got) is thrown away. (This operator uses || which is identical to | except that it handles error messages slightly differently).

(<???>) :: Parser a -> String -> Parser a infixl 3 #

Given a parser p, makes a new parser where if p fails, the new parser also fails, but it can replace a parser's failure error message with a new one. But unlike ??, we only do the replacement if the parser got *nowhere* with things. If it made some headway at all, we let its error message stand, in the hope it'll be more useful.

char :: Char -> Parser Char #

Returns c, if c is the next character in the input

getCharThat :: (Char -> Bool) -> Parser Char #

Return a character result only if the character satisfies a given predicate

digit :: Parser Char #

Parse a single character that is a digit

letter :: Parser Char #

Parse a single alphabetic character (uppercase or lowercase)

space :: Parser Char #

Parse a character that is whitespace (e.g., space, tab, newline, etc.)

alphanum :: Parser Char #

Parse a character that is either a digit or a letter

sym :: Char -> Parser Char #

Like char but skips any whitespace that precedes the char.

openparen :: Parser Char #

Parses the character '('

closeparen :: Parser Char #

Parses the character ')'

parens :: Parser a -> Parser a #

Given a parser p, succeeds if the input string contains a parenthesis-delimited string that matches the parser p.

openbrace :: Parser Char #

Parses the character '{'

closebrace :: Parser Char #

Parses the character '}'

braces :: Parser a -> Parser a #

Given a parser p, succeeds if the input string contains a braces-delimited string that matches the parser p.

text :: String -> Parser String #

Like string but skips any whitespace that precedes the string.

string :: String -> Parser String #

Returns a specific sequence of characters, if those are exactly the next characters in the input

litstring :: Parser String #

A string literal is a sequence of string characters inside quotation marks, optionally surrounded by some whitespace.

stringchar :: Parser Char #

A string character is either any character that is not a double quote, or the escape sequence " (which we interpret as a double quote character inside our string)

whitespace :: Parser () #

A parser that ignores whitespace (by consuming it from the input and returning unit).

skipws :: Parser a -> Parser a #

Returns a parser that parses what p does, but skips any whitespace that appears at the beginning of the input string.

identifier :: Parser String #

Parse an identifier, defined here as a letter, followed by zero or more alphanumeric characters.

ident :: Parser String #

Like identifier but skips any whitespace that precedes the identifier.

reservedword :: String -> Parser String #

A parser for a reserved word. A reserved word has the same restrictions as an identifier, but also has a particular name (e.g., "while")

rword :: String -> Parser String #

Like reservedWord but skips any whitespace that precedes the reserved word.

number :: Parser Integer #

Parse an Integer

num :: Parser Integer #

Like number but skips any whitespace that precedes the number.

double :: Parser Double #

Parses a double, ignoring whitespace

many1 :: Parser a -> Parser [a] #

Equivalent to some (because some people like to call the "some" parser "many1")

skipMany :: Alternative f => f a -> f () #

Like many but instead of returning the results, throws them away.

skipMany1 :: Alternative parser => parser a -> parser () #

Like many1 but instead of returning the results, throws them away.

optional :: (Alternative parser, Alternative t) => parser a -> parser (t a) #

Tries to parse a p, but also succeeds if it doesn't find a p You can think of the type of optional as being either optional :: Parser a -> Parser (Maybe a) optional :: Parser a -> Parser [a] but actually we use a more general type. This code uses Monads and point-free style.

perhaps :: (Alternative p, Monad m, Alternative m) => p (m a) -> p (m a) #

Like optional p, but has different type, it assumes we're trying to parse something type that has a built-in notion of emptiness (e.g., strings with "", lists with [], etc.), specifically something with mzero value. If we can't parse the thing, we return that empty value. You can think of the type of perhaps as being either perhaps :: Parser String -> Parser String perhaps :: Parser [a] -> Parser [a] perhaps :: Parser (Maybe a) -> Parser (Maybe a) but actually we use a more general type. This code uses Monads and point-free style.

manyEndingWith :: Alternative parser => parser b -> parser a -> parser [a] #

Equivalent to many p +- end *except* that it the above might give error messages related to not being able to parse end (because many always succeeds), whereas this version can give the best error message out of the one for not parsing p and not parsing end.

In practice, our strategy of choosing the deepest error message should mean that we don't need this function.

someEndingWith :: Alternative parser => parser b -> parser a -> parser [a] #

Equivalent to some p +- end *except* that it the above might give error messages related to not being able to parse end (because some always succeeds if it can read at least one p), whereas this version can give the best error message out of the one for not parsing p and not parsing end.

In practice, our strategy of choosing the deepest error message should mean that we don't need this function.

between :: Applicative parser => parser open -> parser close -> parser a -> parser a #

Parse something that is surrounded by delimiters (e.g., parentheses). Note the order of its arguments: it takes the parser's delimiters *first*, and *then* the thing to parse inside them

sepBy1 :: Alternative parser => parser a -> parser sep -> parser [a] #

Given two parsers p and sep, succeeds if the input string contains a sep-delimited sequence of one or more things that match p. The delimiters will be thrown away and we'll be left with a list of all the matches for p.

sepBy :: Alternative parser => parser a -> parser sep -> parser [a] #

Given two parsers p and sep, succeeds if the input string contains a sep-delimited sequence of zero or more things that match p. The delimiters will be thrown away and we'll be left with a (possibly empty) list of all the matches for p.

endBy :: Alternative parser => parser a -> parser sep -> parser [a] #

Similar to sepBy, but the delimiter must also appear at the end.

endBy1 :: Alternative parser => parser a -> parser sep -> parser [a] #

Similar to sepBy1, but the delimiter must also appear at the end.

chainr1 :: Alternative parser => parser a -> parser (a -> a -> a) -> parser a #

Adapts foldr to work on parse results

chainr1weak :: Parser a -> Parser (a -> a -> a) -> Parser a #

Non-greedy chainr1 The above definition of chainr1 is greedy, if it sees "1 + 2 + 3 + !", it'll fail the whole parse at the "!" rather than successfully parsing "1 + 2 + 3" and leaving the "+ !" unread. That's usually a good thing because it gives better error messages, but sometimes in a more ambigious grammar it'll cause problems. This version gives that latter behavior.

chainl1 :: Alternative parser => parser a -> parser (a -> a -> a) -> parser a #

Adapts foldl to work on parse results

module ParserBase