Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/thatsjustcheesy/parsem
Parsec-like parser combinators for Crystal
https://github.com/thatsjustcheesy/parsem
crystal parsec parser parser-combinators
Last synced: about 1 month ago
JSON representation
Parsec-like parser combinators for Crystal
- Host: GitHub
- URL: https://github.com/thatsjustcheesy/parsem
- Owner: ThatsJustCheesy
- License: mit
- Created: 2022-07-06T01:48:43.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2022-11-17T04:15:20.000Z (about 2 years ago)
- Last Synced: 2023-05-22T19:33:45.561Z (over 1 year ago)
- Topics: crystal, parsec, parser, parser-combinators
- Language: Crystal
- Homepage:
- Size: 57.6 KB
- Stars: 11
- Watchers: 1
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# 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.
[parsec]: https://wiki.haskell.org/Parsec
[footlessparser]: https://github.com/kareman/FootlessParser## Installation
1. Add the dependency to your `shard.yml`:
```yaml
dependencies:
parsem:
github: ThatsJustCheesy/parsem
```2. 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
- 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)### Docs
Please clone the repository, run `crystal docs`, and open the resulting `docs/index.html`.
### Examples
#### CSV parser
```crystal
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_cellrow = (cell << token(DELIMITER)).repeat(..).extend <=> cell
csv = (row << token(NEWLINE)).repeat(..).extend <=> row
```#### More (complex) examples
Please see [`spec/examples`](spec/examples) for more, including an arithmetic expression parser and a pseudo-JSON parser.
## Contributing
1. Fork it ()
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create a new Pull Request## Contributors
- [Ian Gregory](https://github.com/ThatsJustCheesy) - creator and maintainer