kevinmehall / rust-peg

Parsing Expression Grammar (PEG) parser generator for Rust
https://crates.io/crates/peg
MIT License
1.46k stars 106 forks source link

Question about passing atom (char) arguments to rule #382

Closed tetotechy closed 1 month ago

tetotechy commented 1 month ago

It seems to me that

rule any_but(ch: char) -> &'input str
    = $([c if c != ch]*)

works whereas

rule any_but(ch: char) -> &'input str
    = $([^ch]*)

doesn't (it compiles but the behaviour is different, possibly wrong imo), correct? Is there a reason for that? Thanks.

kevinmehall commented 1 month ago

[^ch] is equivalent to [^_] and will always fail -- that expands to basically

match next_char {
    ch => return failure
    _ => next
}

^ just swaps the outcome of the match arms. ch is a pattern that matches any character and binds a new variable, though you can't access that variable because that arm immediately backtracks. It doesn't compare it to the outer ch variable, just like [ch] is different from [c if c == ch].