I have an example grammar:
WHITESPACE = _{ " " }
identifier = @{ ASCII_ALPHA ~ (ASCII_ALPHANUMERIC | "_")* }
int_literal = { DECIMAL_NUMBER+ }
plusminus = { "+" | "-" }
expr = { int_literal ~ (plusminus ~ int_literal)* }
formula = { identifier ~ ":=" ~ expr }
file = { formula ~ EOI }
and a few structs mapped:
#[derive(Debug, FromPest)]
#[pest_ast(rule(Rule::int_literal))]
pub struct IntLiteral {
#[pest_ast(outer(with(span_into_str), with(str::parse::< i64 >), with(Result::unwrap)))]
pub value: i64
}
#[derive(Debug, FromPest)]
#[pest_ast(rule(Rule::plusminus))]
pub struct PlusMinus {
#[pest_ast(outer(with(span_into_str), with(String::from)))]
pub op: String,
}
#[derive(FromPest, Debug)]
#[pest_ast(rule(Rule::expr_tail))]
pub struct ExprTail {
pub op: PlusMinus,
pub operand: IntLiteral,
}
#[derive(FromPest, Debug)]
#[pest_ast(rule(Rule::expr))]
pub struct Expr {
pub head: IntLiteral,
pub tail: Vec<ExprTail>,
}
Problem is, ExprTail
is never mapped to anything, because there's no named rule for #[pest_ast(rule(???))]
.
It also doesn't work if I make Expr::tail
a Vec<(PlusMinus, IntLiteral)>
.
Of course, I can make an explicit grammar rule:
...
expr_tail = {plusminus ~ int_literal}
expr = { int_literal ~ expr_tail* }
...
but I wouldn't like to pollute grammar with excess terminals because of implementation limitations.
Is there a way to map ExprTail
with the initial grammar?