Parsec (parser)
Parsec is a library for writing parsers in Haskell.[3] It is based on higher-order parser combinators, so a complicated parser can be made out of many smaller ones.[4] It has been reimplemented in many other languages, including Erlang,[5] Elixir,[6] OCaml,[7] Racket,[8] and F#,[9][10] as well as imperative languages such as C#,[11] and Java.[12]
Original author(s) | Daan Leijen, Paolo Martini, Antoine Latter |
---|---|
Developer(s) | Herbert Valerio Riedel, Derek Elkins, Antoine Latter, Roman Cheplyaka, Ryan Scott |
Initial release | November 2, 2006[1] |
Stable release | 3.1.14.0
/ August 10, 2019[2] |
Repository | github |
Written in | Haskell |
Operating system | Linux, macOS, Windows |
Platform | Haskell Platform |
Type | Parser combinator, Library |
License | BSD-3 |
Website | hackage |
Because a parser combinator-based program is generally slower than a parser generator-based program,[13] Parsec is normally used for small domain-specific languages, while Happy is used for compilers such as GHC.[14]
Other Haskell parser combinator libraries that have been derived from Parsec include Megaparsec[15] and Attoparsec.[16]
Parsec is free software released under the BSD-3-Clause license.[17]
Example
Parsers written in Parsec start with simpler parsers, such as ones that recognize certain strings, and combine them to build a parser with more complicated behavior. For example, digit
parses a digit, and string
parses a specific string (like "hello"
).
Parser combinator libraries like Parsec provide utility functions to run the parsers on real values. A parser to recognize a single digit from a string can be split into two functions: one to create the parser, and a main
function that calls one of these utility functions (parse
in this case) to run the parser:
import Text.Parsec -- has general parsing utility functions
import Text.Parsec.Char -- contains specific basic combinators
type Parser = Stream s m Char => ParsecT s u m String
parser :: Parser
parser = string "hello"
main :: IO ()
main = print (parse parser "<test>" "hello world")
-- prints 'Right "hello"'
We define a Parser
type to make the type signature of parser
easier to read. If we wanted to alter this program, say to read either the string "hello"
or the string "goodbye"
, we could use the operator <|>
, provided by the Alternative
typeclass, to combine two parsers into a single parser that tries either:
parser = string "hello" <|> string "goodbye"
References
- "parsec 2.0". Hackage. Retrieved 3 September 2019.
- "Releases". Github. Retrieved 3 September 2019.
- "Parsec on Haskell wiki". Haskell Wiki. Retrieved 29 May 2017.
- Leijen, Daan; Meijer, Erik (July 2001). "Parsec: Direct Style Monadic Parser Combinators For The Real World" (PDF). Microsoft Research. Retrieved 22 November 2014.
- "Parsec Erlang". BitBucket. Retrieved 23 November 2014.
- "Nimble Parsec". Github. Retrieved 18 December 2018.
- "Parsec OCaml" (PDF). The OCaml Summer Project. Retrieved 23 November 2014.
- "Megaparsack: Practical Parser Combinators".
- "XParsec by corsis". XParsec. Retrieved 29 May 2017.
- "FParsec". Quanttec. Retrieved 29 May 2017.
- "CSharp monad". Github. Retrieved 10 December 2014.
- "JParsec". Github. Retrieved 14 October 2016.
- "What is the difference between parser generators and parser combinators?". Quora. Retrieved 2022-10-19.
- "The Glasgow Haskell Compiler (AOSA Vol. 2)". The Architecture of Open Source Applications. Retrieved 23 November 2014.
- "megaparsec: Monadic parser combinators". Hackage. Retrieved 2018-09-10.
- "attoparsec: Fast combinator parsing for bytestrings and text". Hackage. Retrieved 2018-09-10.
- "Parsec". 25 October 2021.