lalrproc 0.0.3

Procedural macro built on LALRPOP
Documentation

LALRPOP parser for procedural macro input

Build Status

This crate demostrates a proof of concept of using the LALRPOP parser generator framework to parse input tokens in a Rust procedural macro.

Macros

The procedural macros in this example are s_expr! and s_type! which expand to a string literal S-expression representation of the Rust expression or type given in the input.

extern crate lalrproc;
use lalrproc::{s_expr, s_type};

fn main() {
    // Expands to "(+ (* 1 2) (* 3 4))"
    let e = s_expr!(1 * 2 + 3 * 4);

    // Expands to "(Reference 'a mut (Path module T))"
    let t = s_type!(&'a mut module::T);
}

Parser

The input parsing is handled entirely by LALRPOP. In particular, Syn and proc-macro2 are not involved.

All of the features of LALRPOP are available to the LALRPOP grammar. For example here is a subset of the expression grammar illustrating the parsing of something like 1 * 2 + 3 * 4 into the syntax tree (+ (* 1 2) (* 3 4)).

pub Expr: Box<Expr> = {
    Expr ExprOp Factor => Box::new(Expr::Binary(<>)),
    Factor,
};

ExprOp: BinOp = {
    "+" => BinOp::Add,
    "-" => BinOp::Sub,
};

Factor: Box<Expr> = {
    Factor FactorOp Component => Box::new(Expr::Binary(<>)),
    Component,
};

FactorOp: BinOp = {
    "*" => BinOp::Mul,
    "/" => BinOp::Div,
};

Component: Box<Expr> = {
    Literal => Box::new(Expr::Lit(<>)),
    Path => Box::new(Expr::Path(<>)),
    "(" <Expr> ")",
};

Error reporting

If the input does not conform to the grammar expected by the procedural macro, the error from LALRPOP is rendered in a way that indicates the problematic token and gives the tokens that would have been accepted by the grammar in that position.

error: failed to parse macro input
  --> tests/test.rs:17:25
   |
17 |     let e = s_expr!(1 + : / 2);
   |                         ^
   |
   = note: unrecognized token `:`
   = note: expected one of `(`, identifier, or literal

License