Warning
Grako has been superseded by TatSu. Do not use Grako for new code. Use either TatSu or seek out an alternative PEG parser generator like Pegen instead.
Important
In its current form, this project only works with Python 3.8.
This project is a "Hello, World" example showing how to use Grako to generate a parser with operator precedence and custom semantic actions. The resulting example application parses and evaluates simple infix math expressions.
Run uv sync to set up a virtual environment with Grako installed. calc will also be available in the virtual environment.
If you modify the grammar file calc.ebnf, then run the following to regenerate the parser.py source:
grako -o src/calc/parser.py calc.ebnfWarning
Despite the grammar looking correct, there is currently an issue with negation not working correctly.
After the > prompt appears, you can type a math expression as a sequence of decimal numbers and operators. Press enter to have the expression evaluated. The result will print on the following line. Another prompt will then appear. When finished, use Ctrl+C to exit.
The calc application recognizes the following operators:
| Operator | Description |
|---|---|
(x) |
Grouping |
-x |
Negation |
^ |
Exponentiation |
* |
Multiplication |
/ |
Division |
+ |
Addition |
- |
Subtraction |
- Operator precedence is achieved by encoding it as nested rules within the EBNF grammar.
- Lower precedence operators appear first.
- Operators with the same level of precedence appear together as alternatives in the same rule.
- Binary operators are specified as an optional list.
- This makes it trivial to reduce the AST for a given expression to just a single value within the semantic action.
- Higher precedence operators must be resolved by the parser by it recusing through the lower precedence grammar rules which come before it.
- This results in an AST where the higher precedence expressions appear lower in the tree.
- This means the expressions which contain a higher precedence operator will be evaluated before all others.