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 =
?
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 :)