Search code examples
rustoperator-precedencepeg

How does precedence works in rust-peg?


I have trouble in understanding pecedence! in rust-peg crate. Take a look at this code:

peg::parser! { grammar example() for str {
    rule letter() -> &'input str = x:$(['a'..='z' | 'A'..='A'])

    rule ident() -> &'input str = x:$(letter()+)

    rule _ = [' ' | '\t' | '\n']*

    rule expr() -> String = precedence! {
        variable:@ _ "=" _ value:(@) {
            format!("assign(&mut {}, {})", variable, value)
        }

        --

        "*" _ x:expr() {
            format!("*{}", x)
        }

        --

        ident:ident() {
            String::from(ident)
        }
    }

    pub rule multiple() -> String = _ expr:expr() ** _ _ {
        expr.join("")
    }
} }

fn main() {
    println!("{}", example::multiple("*a = gg").unwrap());
}

It will print *assign(&mut a, gg) instead of assign(&mut *a, gg). Why? I thought that * rule has higher precedence than =?


Solution

  • While I was typing my question I noticed that = looks like x:@ _ "=" _ y:@, but * like "*" _ x:expr(). So I replaced expr() to @("*" _ x:@) and it worked! It printed assign(&mut *a, gg), just as I wanted. I decided to ask & answer that question anyway, maybe it will be useful for someone else :)