5 releases (3 breaking)
Uses new Rust 2024
| 0.9.3 | Mar 10, 2026 |
|---|---|
| 0.9.1 | Mar 2, 2026 |
| 0.9.0 |
|
| 0.3.0 | Feb 18, 2026 |
| 0.1.0 | Feb 10, 2026 |
#134 in Parser tooling
39,452 downloads per month
545KB
13K
SLoC
Procedural macros for Gazelle parser generator.
This crate provides the gazelle! macro that allows defining grammars
in Rust with type-safe parsers generated at compile time.
Example
use gazelle_macros::gazelle;
use gazelle::Precedence;
gazelle! {
grammar expr {
start expr;
terminals {
NUM: _,
LPAREN, RPAREN,
prec OP: _
}
expr = NUM => num
| expr OP expr => binop
| LPAREN expr RPAREN => paren;
}
}
struct Eval;
impl gazelle::ErrorType for Eval {
type Error = core::convert::Infallible;
}
impl expr::Types for Eval {
type Num = f64;
type Op = char;
type Expr = f64;
}
impl gazelle::Action<expr::Expr<Eval>> for Eval {
fn build(&mut self, node: expr::Expr<Eval>) -> Result<f64, Self::Error> {
Ok(match node {
expr::Expr::Num(n) => n,
expr::Expr::Binop(l, op, r) => match op {
'+' => l + r, '-' => l - r, '*' => l * r, '/' => l / r, _ => 0.0,
},
expr::Expr::Paren(e) => e,
})
}
}
let mut parser = expr::Parser::<Eval>::new();
let mut eval = Eval;
parser.push(expr::Terminal::Num(1.0), &mut eval).unwrap();
parser.push(expr::Terminal::Op('+', Precedence::Left(1)), &mut eval).unwrap();
parser.push(expr::Terminal::Num(2.0), &mut eval).unwrap();
parser.push(expr::Terminal::Op('*', Precedence::Left(2)), &mut eval).unwrap();
parser.push(expr::Terminal::Num(3.0), &mut eval).unwrap();
let result = parser.finish(&mut eval).map_err(|(_, e)| e).unwrap();
assert_eq!(result, 7.0); // 1 + (2 * 3)
Dependencies
~310–730KB
~17K SLoC