Skip to main content

Crate gazelle_macros

Crate gazelle_macros 

Source
Expand description

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)

Macros§

gazelle
Define a grammar and generate a type-safe parser.