A pure Python Scannerless LR/GLR parser
Project description
[![Build Status](https://travis-ci.org/igordejanovic/parglare.svg?branch=master)](https://travis-ci.org/igordejanovic/parglare)
[![Coverage Status](https://coveralls.io/repos/github/igordejanovic/parglare/badge.svg?branch=master)](https://coveralls.io/github/igordejanovic/parglare?branch=master)
[![Docs](https://img.shields.io/badge/docs-latest-green.svg)](http://igordejanovic.net/parglare/)
![Status](https://img.shields.io/pypi/status/parglare.svg)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
![Python versions](https://img.shields.io/pypi/pyversions/parglare.svg)
![parglare logo](https://raw.githubusercontent.com/igordejanovic/parglare/master/docs/images/parglare-logo.png)
A pure Python LR/GLR parser with integrated scanner.
For more information see [the docs](http://www.igordejanovic.net/parglare/).
## Quick intro
This is just a small example to get the general idea. This example shows how to
parse and evaluate expressions with 5 operations with different priority and
associativity. Evaluation is done using semantic/reduction actions.
The whole expression evaluator is done in under 30 lines of code!
```python
from parglare import Parser, Grammar
grammar = r"""
E: E '+' E {left, 1}
| E '-' E {left, 1}
| E '*' E {left, 2}
| E '/' E {left, 2}
| E '^' E {right, 3}
| '(' E ')'
| number;
number: /\d+(\.\d+)?/;
"""
actions = {
"E": [lambda _, nodes: nodes[0] + nodes[2],
lambda _, nodes: nodes[0] - nodes[2],
lambda _, nodes: nodes[0] * nodes[2],
lambda _, nodes: nodes[0] / nodes[2],
lambda _, nodes: nodes[0] ** nodes[2],
lambda _, nodes: nodes[1],
lambda _, nodes: nodes[0]],
"number": lambda _, value: float(value),
}
g = Grammar.from_string(grammar)
parser = Parser(g, debug=True, actions=actions)
result = parser.parse("34 + 4.6 / 2 * 4^2^2 + 78")
print("Result = ", result)
# Output
# -- Debuging/tracing output with detailed info about grammar, productions,
# -- terminals and nonterminals, DFA states, parsing progress,
# -- and at the end of the output:
# Result = 700.8
```
## Install
- Stable version:
```
$ pip install parglare
```
- Development version:
```
$ git clone git@github.com:igordejanovic/parglare.git
$ pip install -e parglare
```
## License
MIT
## Python versions
Tested with 2.7, 3.3-3.6
## Credits
Initial layout/content of this package was created with [Cookiecutter](https://github.com/audreyr/cookiecutter) and the [audreyr/cookiecutter-pypackage](https://github.com/audreyr/cookiecutter-pypackage) project template.
# History
- 2017-08-09 Version 0.2
- GLR parsing. Support for epsilon grammars, cyclic grammars and grammars with
infinite ambiguity.
- Lexical recognizers. Parsing the stream of arbitrary objects.
- Error recovery. Builtin default recovery, custom user defined.
- Common semantic actions.
- Documentation.
- pglr CLI command.
- Automata visualization, GLR visual tracing.
- Lexical disambiguation improvements.
- Support for epsilon grammar (empty productions).
- Support for comments in grammars.
- `finish` and `prefer` terminal rules.
- Change in the grammar language `=` - > `:`
- Additions to examples and tests.
- Various optimizations and bug fixes.
- 2017-02-02 - Version 0.1
- Textual syntax for grammar specification. Parsed with parglare.
- SLR and LALR tables calculation (LALR is the default)
- Scannerless LR(1) parsing
- Scanner is integrated into parsing. This give more power as the token
recognition is postponed and done in the parsing context at the current
parsing location.
- Declarative associativity and priority based conflict resolution for
productions
- See the `calc` example, or the quick intro bellow.
- Lexical disambiguation strategy.
- The default strategy is longest-match first and then `str` over `regex`
match (i.e. the most specific match). Terminal priority can be provided
for override if necessary.
- Semantic actions and default actions which builds the parse tree (controlled
by `actions` and `default_actions` parameters for the `Parser` class).
- If no actions are provided and the default actions are explicitely
disabled parser works as a recognizer, i.e. no reduction actions are
called and the only output of the parser is whether the input was
recognized or not.
- Support for language comments/whitespaces using special rule `LAYOUT`.
- Debug print/tracing (set `debug=True` and/or `layout_debug=True`to the
`Parser` instantiation).
- Tests
- Few examples (see `examples` folder)
[![Coverage Status](https://coveralls.io/repos/github/igordejanovic/parglare/badge.svg?branch=master)](https://coveralls.io/github/igordejanovic/parglare?branch=master)
[![Docs](https://img.shields.io/badge/docs-latest-green.svg)](http://igordejanovic.net/parglare/)
![Status](https://img.shields.io/pypi/status/parglare.svg)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
![Python versions](https://img.shields.io/pypi/pyversions/parglare.svg)
![parglare logo](https://raw.githubusercontent.com/igordejanovic/parglare/master/docs/images/parglare-logo.png)
A pure Python LR/GLR parser with integrated scanner.
For more information see [the docs](http://www.igordejanovic.net/parglare/).
## Quick intro
This is just a small example to get the general idea. This example shows how to
parse and evaluate expressions with 5 operations with different priority and
associativity. Evaluation is done using semantic/reduction actions.
The whole expression evaluator is done in under 30 lines of code!
```python
from parglare import Parser, Grammar
grammar = r"""
E: E '+' E {left, 1}
| E '-' E {left, 1}
| E '*' E {left, 2}
| E '/' E {left, 2}
| E '^' E {right, 3}
| '(' E ')'
| number;
number: /\d+(\.\d+)?/;
"""
actions = {
"E": [lambda _, nodes: nodes[0] + nodes[2],
lambda _, nodes: nodes[0] - nodes[2],
lambda _, nodes: nodes[0] * nodes[2],
lambda _, nodes: nodes[0] / nodes[2],
lambda _, nodes: nodes[0] ** nodes[2],
lambda _, nodes: nodes[1],
lambda _, nodes: nodes[0]],
"number": lambda _, value: float(value),
}
g = Grammar.from_string(grammar)
parser = Parser(g, debug=True, actions=actions)
result = parser.parse("34 + 4.6 / 2 * 4^2^2 + 78")
print("Result = ", result)
# Output
# -- Debuging/tracing output with detailed info about grammar, productions,
# -- terminals and nonterminals, DFA states, parsing progress,
# -- and at the end of the output:
# Result = 700.8
```
## Install
- Stable version:
```
$ pip install parglare
```
- Development version:
```
$ git clone git@github.com:igordejanovic/parglare.git
$ pip install -e parglare
```
## License
MIT
## Python versions
Tested with 2.7, 3.3-3.6
## Credits
Initial layout/content of this package was created with [Cookiecutter](https://github.com/audreyr/cookiecutter) and the [audreyr/cookiecutter-pypackage](https://github.com/audreyr/cookiecutter-pypackage) project template.
# History
- 2017-08-09 Version 0.2
- GLR parsing. Support for epsilon grammars, cyclic grammars and grammars with
infinite ambiguity.
- Lexical recognizers. Parsing the stream of arbitrary objects.
- Error recovery. Builtin default recovery, custom user defined.
- Common semantic actions.
- Documentation.
- pglr CLI command.
- Automata visualization, GLR visual tracing.
- Lexical disambiguation improvements.
- Support for epsilon grammar (empty productions).
- Support for comments in grammars.
- `finish` and `prefer` terminal rules.
- Change in the grammar language `=` - > `:`
- Additions to examples and tests.
- Various optimizations and bug fixes.
- 2017-02-02 - Version 0.1
- Textual syntax for grammar specification. Parsed with parglare.
- SLR and LALR tables calculation (LALR is the default)
- Scannerless LR(1) parsing
- Scanner is integrated into parsing. This give more power as the token
recognition is postponed and done in the parsing context at the current
parsing location.
- Declarative associativity and priority based conflict resolution for
productions
- See the `calc` example, or the quick intro bellow.
- Lexical disambiguation strategy.
- The default strategy is longest-match first and then `str` over `regex`
match (i.e. the most specific match). Terminal priority can be provided
for override if necessary.
- Semantic actions and default actions which builds the parse tree (controlled
by `actions` and `default_actions` parameters for the `Parser` class).
- If no actions are provided and the default actions are explicitely
disabled parser works as a recognizer, i.e. no reduction actions are
called and the only output of the parser is whether the input was
recognized or not.
- Support for language comments/whitespaces using special rule `LAYOUT`.
- Debug print/tracing (set `debug=True` and/or `layout_debug=True`to the
`Parser` instantiation).
- Tests
- Few examples (see `examples` folder)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
parglare-0.2.tar.gz
(759.2 kB
view hashes)
Built Distribution
parglare-0.2-py2.py3-none-any.whl
(37.8 kB
view hashes)
Close
Hashes for parglare-0.2-py2.py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 45175878b349e07f2ce643561461ea361c117dc8706b374d9ea478d13f57f457 |
|
MD5 | 14e8bcd106c2d116556e93a1869b7b57 |
|
BLAKE2b-256 | 7b8e2d747dca067a965a93c4a64b45f9605d05ec42c6af76d9831c2ea6350b50 |