Expand description
A procedural macro for generating pest-based parsers with integrated enum_dispatch
support.
This crate automates the creation of type-safe parser implementations by combining pest grammar definitions
with static dispatch via the enum_dispatch
crate. It generates both parser rules and associated data structures
while establishing a trait-based interface for unified rule handling.
§Features
- Automatic Parser Generation: Converts pest grammar files into executable parsing logic
- Rule-specific Structs: Generates zero-sized structs for each grammar rule
- Static Dispatch Integration: Implements
enum_dispatch
-powered trait unification - Trait-based Interface: Creates a unified API for all parsing rules
§Usage
-
Add dependencies to
Cargo.toml
:[dependencies] pest = "2.5" pest_derive = "2.5" enum_dispatch = "0.3" enum_dispatch_pest_parser = { version = "0.1" } # This crate
-
Define a trait interface for parser rules
-
Apply the
#[pest_parser]
attribute to a struct
§Example
use anyhow::Result;
use enum_dispatch::enum_dispatch;
use enum_dispatch_pest_parser::pest_parser;
use pest::Parser;
// Define parser trait interface
#[enum_dispatch]
trait ParserInterface {
fn parse_rule(&self, arg: &str) -> Result<()>;
}
// Generate parser implementation
#[pest_parser(grammar = "grammar.pest", interface = "ParserInterface")]
pub struct LanguageParser;
// Implement trait for individual rules
#[derive(Default)]
struct Statement;
impl ParserInterface for Statement {
fn parse_rule(&self, arg: &str) -> Result<()> {
/* do something here */
Ok(())
}
}
// Usage example
fn main() -> Result<()> {
let content = read_to_string("input.txt")?;
let _ = LanguageParser::parse(Rule::Statement(Statement {}), &content)?;
node.parse_rule("argument")?;
// Dispatches to Statement::parse_rule automatically
}
§Implementation Notes
§Code Generation Phases
- Base Parser Generation: Uses
pest_generator
to create initial parsing code - Struct Generation:
- Extracts
enum Rule
definition from generated code - Creates unit structs for each variant (e.g.,
struct Statement;
)
- Extracts
- Dispatch Integration:
- Inserts
#[enum_dispatch]
attribute onenum Rule
- Modifies pattern matching to handle struct wrappers
- Adjusts rule instantiation syntax
- Inserts
§Safety & Compatibility
- pest Version Locking:
- Tightly coupled with pest’s code generation output
- Tested with pest 2.5.4 - may break with newer versions
- Fragile Regex Modifications:
- Uses regular expressions for code transformation
- May fail with unusual formatting or comments
- Trait Implementation:
- Users MUST manually implement the trait for generated structs
- Structs are public and reside in root module
§Debugging Tips
- Inspect generated code using:
println!("{}", raw_codes); // Add temporary debug output
- Verify
enum Rule
extraction boundaries - Check regex replacements for rule wrapping
§Limitations
- Requires nightly Rust for procedural macros
- Rule structs pollute root namespace
- Limited error reporting for malformed grammars
Attribute Macros§
- pest_
parser - Generates a pest-based parser with
enum_dispatch
integration for static method dispatch.