rusty_lr
A Yacc-like, procedural macro-based parser generator for Rust supporting LR(1), LALR(1), and GLR parsing strategies.
RustyLR enables you to define context-free grammars (CFGs) directly in Rust using macros or build scripts. It constructs finite state automata at compile time, ensuring efficient and reliable parsing.
Features
- Multiple Parsing Strategies: Supports LR(1), LALR(1), and GLR parsers.
- Procedural Macros: Define grammars using lr1! macro for compile-time parser generation.
- Build Script Integration: Generate parsers via build scripts for complex grammars with detailed error messages.
- Custom Reduce Actions: Define custom actions during reductions to build ASTs or perform computations.
- Grammar Conflict Detection: Automatically detects shift/reduce and reduce/reduce conflicts during parser generation, providing informative diagnostics to help resolve ambiguities.
Installation
Add RustyLR to your Cargo.toml:
[]
= "..."
To use buildscript tools:
[]
= { = "...", = ["build"] }
Or you want to use executable version (optional):
rusty_lr is designed for use with auto-generated code,
either through lr1! macro (default), a build script (with build feature), or the rustylr executable.
When using a buildscript or executable, you can get beautiful and detailed messages generated from your grammar.
Quick Start
Using Procedural Macros
Define your grammar using the lr1! macro:
// this define `EParser` struct
// where `E` is the start symbol
lr1!
This defines a simple arithmetic expression parser.
Using Build Script
For complex grammars, you can use a build script to generate the parser. This will provide more detailed error messages when conflicts occur.
1. Create a grammar file (e.g., src/parser.rs) with the following content:
// Rust code of `use` and type definitions
%% // start of grammar definition
%tokentype u8;
%start E;
%eof b'\0';
E: b'(' E b')'
| a;
...
2. Setup build.rs:
// build.rs
use build;
3. Include the generated source code:
include!;
4. Use the parser in your code:
let mut parser = new; // create <StartSymbol>Parser class
let mut context = new; // create <StartSymbol>Context class
let mut userdata: i32 = 0;
for b in input.chars
println!;
context.feed.unwrap; // feed EOF
let result:i32 = context.accept; // get value of start 'E'
The generated code will include several structs and enums:
<Start>Parser: A struct that holds the parser table.<Start>Context: A struct that maintains the current state and the values associated with each symbol.<Start>State: A type representing a single parser state and its associated table.<Start>Rule: A type representing a single production rule.<Start>NonTerminals: A enum representing all non-terminal symbols in the grammar (and its data).
Note that the actual definitions are bit different if you are building GLR parser.
GLR Parsing
RustyLR offers built-in support for Generalized LR (GLR) parsing, enabling it to handle ambiguous or nondeterministic grammars that traditional LR(1) or LALR(1) parsers cannot process. See GLR.md for details.
Examples
- Calculator: A calculator using
u8as token type. - Json Validator: A JSON validator
- lua 5.4 syntax parser
- Bootstrap: rusty_lr syntax parser is written in rusty_lr itself.
Cargo Features
build: Enable build script tools.fxhash: Use FXHashMap instead ofstd::collections::HashMapfor parser tables.tree: Enable automatic syntax tree construction (For debugging purposes).error: Enable detailed parsing error messages (For debugging purposes).
Syntax
RustyLR's grammar syntax is inspired by traditional Yacc/Bison formats. See SYNTAX.md for details of grammar-definition syntax.
Contribution
- Any contribution is welcome.
- Please feel free to open an issue or pull request.
License (Since 2.8.0)
Either of
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
Images
It is highly recommended to use buildscipt tools or executable instead of procedural macros, to generate readable error messages.
-Reduce/Reduce conflicts

- Shift/Reduce conflicts
