Expand description
A typed LR(1) parser generator for Rust with runtime operator precedence and a push-based API for natural lexer feedback.
§Quick start
Define a grammar with [gazelle_macros::gazelle!]. A prec terminal carries
Precedence at parse time, so one rule handles all operator levels:
use gazelle_macros::gazelle;
gazelle! {
grammar calc {
start expr;
terminals { NUM: _, prec OP: _ }
expr = expr OP expr => binop | NUM => num;
}
}
struct Eval;
impl gazelle::ErrorType for Eval {
type Error = core::convert::Infallible;
}
impl calc::Types for Eval {
type Num = i64;
type Op = char;
type Expr = i64;
}
impl gazelle::Action<calc::Expr<Self>> for Eval {
fn build(&mut self, node: calc::Expr<Self>) -> Result<i64, Self::Error> {
Ok(match node {
calc::Expr::Binop(l, op, r) => match op {
'+' => l + r, '-' => l - r, '*' => l * r, '/' => l / r,
_ => unreachable!(),
},
calc::Expr::Num(n) => n,
})
}
}Then push tokens with precedence and collect the result:
ⓘ
use gazelle::Precedence;
let mut parser = calc::Parser::<Eval>::new();
let mut actions = Eval;
// Precedence is supplied per-token — the grammar stays flat:
parser.push(calc::Terminal::Num(1), &mut actions)?;
parser.push(calc::Terminal::Op('+', Precedence::Left(1)), &mut actions)?;
parser.push(calc::Terminal::Num(2), &mut actions)?;
parser.push(calc::Terminal::Op('*', Precedence::Left(2)), &mut actions)?;
parser.push(calc::Terminal::Num(3), &mut actions)?;
let result = parser.finish(&mut actions).map_err(|(p, gazelle::ParseError::Syntax { terminal })| p.format_error(terminal, None, None))?;
assert_eq!(result, 7); // 1 + (2 * 3)See examples/expr_eval.rs for a complete runnable version.
§Key features
- Runtime operator precedence:
precterminals carryPrecedenceat parse time, so one grammar rule handles any number of operator levels — including user-defined operators. - Push-based parsing: you drive the loop, so the lexer can inspect parser state between tokens (solves C’s typedef problem).
- CST/AST continuum: set associated types to the generated enum for a
full CST, to a custom type for an AST, or to
Ignoreto discard. - Library API: build
CompiledTables programmatically for dynamic grammars, analyzers, or conflict debuggers.
Re-exports§
pub use grammar::Alt;pub use grammar::Grammar;pub use grammar::Rule;pub use grammar::SymbolId;pub use grammar::Term;pub use grammar::TerminalDef;pub use table::CompiledTable;pub use table::Conflict;pub use runtime::Action;pub use runtime::AstNode;pub use runtime::Cst;pub use runtime::CstParser;pub use runtime::ErrorContext;pub use runtime::ErrorType;pub use runtime::Ignore;pub use runtime::ParseError;pub use runtime::Parser;pub use runtime::Precedence;pub use runtime::RecoveryInfo;pub use runtime::Repair;pub use runtime::Resolution;pub use runtime::Token;pub use lexer::LexerDfa;pub use lexer::OwnedLexerDfa;