Parsem
Crystal library for Parsec-like parser combinators, which allow you to construct complex parsers out of simpler ones. Usually, this leads to highly compact parsing code, with a structure that very much resembles the grammar itself.
Heavily inspired by FootlessParser, a parser combinator library for Swift.
Installation
-
Add the dependency to your
shard.yml:dependencies: parsem: github: ThatsJustCheesy/parsem -
Run
shards install
Usage
Begin by finding or creating a right-recursive grammar for the language you want to parse. Then translate the grammar into Parsem parsers.
You'll make frequent use of these combinators:
- Sequencing operators: Run the left parser, then the right parser
- Left-yield
<<- Keeps only the result of the left parser
- Right-yield
>>- Keeps only the result of the right parser
- Proc-apply
<=>- Effectively keeps the result of both parsers, but must be used in conjunction with
^(map operator) or a related convenience method
- Effectively keeps the result of both parsers, but must be used in conjunction with
- Left-yield
- Choice operator
|- Runs the left parser; if it fails without consuming any input, runs the right parser instead
- Map operator
^- Partially applies the (left) proc with the (right) parser's result as the first argument. Supply any additional arguments with
<=>(sequencing proc-apply operator)
- Partially applies the (left) proc with the (right) parser's result as the first argument. Supply any additional arguments with
Docs
Please clone the repository, run crystal docs, and open the resulting docs/index.html.
Examples
CSV parser
require "parsem"
include Parsem
# Adapted from https://github.com/kareman/FootlessParser#csv-parser
# Thanks!
DELIMITER = ','
QUOTE = '"'
NEWLINE = '\n'
quoted_cell = token(QUOTE) >> not(QUOTE).repeat(..).join << token(QUOTE)
unquoted_cell = none_of([DELIMITER, NEWLINE]).repeat(..).join
cell = quoted_cell | unquoted_cell
row = (cell << token(DELIMITER)).repeat(..).extend <=> cell
csv = (row << token(NEWLINE)).repeat(..).extend <=> row
More (complex) examples
Please see spec/examples for more, including an arithmetic expression parser and a pseudo-JSON parser.
Contributing
- Fork it (https://github.com/ThatsJustCheesy/parsem/fork)
- Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin my-new-feature) - Create a new Pull Request
Contributors
- Ian Gregory - creator and maintainer