In pest.rs, pest-ast crate, how do I map struct to nested anonymous groups?

160 views Asked by At

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?

0

There are 0 answers