Search code examples
parsingrustgrammarpegpest

Parser expression grammar - how to match any string excluding a single character?


I'd like to write a PEG that matches filesystem paths. A path element is any character except / in posix linux.

There is an expression in PEG to match any character, but I cannot figure out how to match any character except one.

The peg parser I'm using is PEST for rust.


Solution

  • You could find the PEST syntax in https://docs.rs/pest/0.4.1/pest/macro.grammar.html#syntax, in particular there is a "negative lookahead"

    !a — matches if a doesn't match without making progress

    So you could write

    !["/"] ~ any
    

    Example:

    // cargo-deps: pest
    
    #[macro_use] extern crate pest;
    use pest::*;
    
    fn main() {
        impl_rdp! {
            grammar! {
                path = @{ soi ~ (["/"] ~ component)+ ~ eoi }
                component = @{ (!["/"] ~ any)+ }
            }
        }
    
        println!("should be true: {}", Rdp::new(StringInput::new("/bcc/cc/v")).path());
        println!("should be false: {}", Rdp::new(StringInput::new("/bcc/cc//v")).path());
    }