Parsec | |
---|---|
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.17.0 / April 5, 2024 [2] |
Repository | github |
Written in | Haskell |
Operating system | Linux, macOS, Windows |
Platform | Haskell Platform |
Available in | English |
Type | Parser combinator, library |
License | BSD-2-clause |
Website | hackage |
Parsec is a library for writing parsers written in the programming language 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] F#, [9] [10] and the imperative programming languages C#, [11] and Java. [12]
Because a parser combinator-based program is generally slower than a parser generator-based program,[ citation needed ] Parsec is normally used for small domain-specific languages, while Happy is used for compilers such as the Glasgow Haskell Compiler (GHC). [13]
Other Haskell parser combinator libraries that have been derived from Parsec include Megaparsec [14] and Attoparsec. [15]
Parsec is free software released under the BSD-3-Clause license. [16]
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:
importText.Parsec-- has general parsing utility functionsimportText.Parsec.Char-- contains specific basic combinatorstypeParser=StreamsmChar=>ParsecTsumStringparser::Parserparser=string"hello"main::IO()main=print(parseparser"<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"