yhirose / cpp-peglib

A single file C++ header-only PEG (Parsing Expression Grammars) library
MIT License
916 stars 113 forks source link

String token rule problem #284

Closed reinyzni closed 1 year ago

reinyzni commented 1 year ago

Hi,

I have defined grammar as following:

    EXPRESSION                   <- CONDITION
    CONDITION                    <- MULTIPLICATIVE (ConditionOperator MULTIPLICATIVE)?
    MULTIPLICATIVE               <- CALL (MultiplicativeOperator CALL)*
    CALL                         <- PRIMARY (EXPRESSION)?
    PRIMARY                      <- COUNT_FUNC / EXISTS_FUNC / MUST_FUNC / XPATH_FUNC / XPATH_REGEX_FUNC / XPATH_MATCH_REGEX_FUNC / XPATH_KEY_BASED_FUNC / XPATH_KEY_REGEX_REPLACE_FUNC / '(' EXPRESSION ')' / REFERENCE / Keyword / Number / String / IF_STATEMENT
    COUNT_FUNC                   <- 'count' '(' MULTIPLICATIVE ')'
    EXISTS_FUNC                  <- 'exists' '(' MULTIPLICATIVE ')'
    MUST_FUNC                    <- 'must' '(' CONDITION ')'
    XPATH_FUNC                   <- 'xpath' '(' String ')'
    XPATH_REGEX_FUNC             <- 'xpath_regex' '(' String ')'
    XPATH_MATCH_REGEX_FUNC       <- 'xpath_match_regex' '(' String (',' String){2} ')'
    XPATH_KEY_BASED_FUNC         <- 'xpath_key_based' '(' String ',' String ')'
    XPATH_KEY_REGEX_REPLACE_FUNC <- 'xpath_key_regex_replace' '(' String ',' String ')'
    REFERENCE                    <- '@'
    IF_STATEMENT                 <- 'if' '(' CONDITION ')' 'then' '(' EXPRESSION ')'

    # Token Rules
    ConditionOperator           <- < [=~&|] >
    MultiplicativeOperator      <- '%'
    String                      <- "'" < ([^'] .)* > "'"
    Number                      <- < [0-9]+ >

    Keyword                     <- ('if' / 'then' / 'else' / 'true' / 'false') ![a-zA-Z]
    %whitespace                 <- [ \t\r\n]***

and the following expression to parse: if (xpath('/platform/port[@key]/breakout-mode/value') ~ 'none') then (must(exists(xpath_key_based('/interface/gigabit-ethernet[@key]', '/platform/port[@key]')) = false)) For the above expression I got the following error: 1:137 syntax error, unexpected '/', expecting <String>, ','. But if I add leading character '/' on the beginning of the string '/interface/gigabit-ethernet[@key]', the expression is able to pass successfully: if (xpath('/platform/port[@key]/breakout-mode/value') ~ 'none') then (must(exists(xpath_key_based('//interface/gigabit-ethernet[@key]', '/platform/port[@key]')) = false)) Can someone help me to fix my grammar to avoid adding leading character "/" to my string?

Cheers!

mingodad commented 1 year ago

If you remove the dot in "'" < ([^'] .)* > "'" it seems to work (it becomes "'" < [^']* > "'") .

reinyzni commented 1 year ago

Thank you @mingodadfor so quick response! Your solution works for me. I'm very appreciated for that! I should be more careful about regex expression next time.