8 releases
0.0.8 | Dec 19, 2022 |
---|---|
0.0.7 | Dec 27, 2020 |
0.0.6 | Jun 14, 2020 |
0.0.5 | Apr 30, 2019 |
0.0.1 | Jan 12, 2018 |
#8 in #lalrpop
23KB
473 lines
LALRPOP parser for procedural macro input
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.
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
Licensed under either of Apache License, Version 2.0 or MIT license at your option.Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
Dependencies
~0–1.9MB
~26K SLoC