Anuj Kulkarni
Anuj Kulkarni

Reputation: 2199

PEGJS : Nested pegjs grammar

start
  = intExp

intExp
  = andIntExp
  / orIntExp

andIntExp 
   = integer (andExp intExp)*

orIntExp 
   = integer (orExp intExp)*

andExp 
  = space* "and" space* { return "and";}

orExp 
  = space* "or" space*  { return "or";}

space 
  = [\n \t]

integer "integer"
  = digits:[0-9]+ { return parseInt(digits.join(""), 10); }

I want to parse input like

2 or 2 or 2 or 2 and 2 and 2 but 2 or 2 and 2 is invalid. In short I dont want and and or to occur together within the input. Is there any way to do this with peg, without involving javascript and storing previously seen variable (For which I already have a solution) ?

Upvotes: 1

Views: 388

Answers (1)

Marcelo Camargo
Marcelo Camargo

Reputation: 2298

Parsing expression grammars are deterministic. They try the first match and fail on first mismatch, also, they don't backtrack. You can just negate ambiguous expressions and your grammar will work as expected:

Start
  = IntExpr

IntExpr
  = OrIntExpr
  / AndIntExpr

OrIntExpr
  = Integer _ !"and" ("or" _ OrIntExpr)?

AndIntExpr
  = Integer _ ("and" _ AndIntExpr)?

Integer "integer"
  = digits:[0-9]+ { return parseInt(digits.join(""), 10); }

_ "space"
  = [\n \t]*

Our OurExpr refuses matching if receives and and jumps to the next option.

The following rules have been tested:

1 and 2 and 3 => PASS

1 => PASS

4 or 2 or 1 => PASS

9 and 2 or 3 => FAIL

Upvotes: 2

Related Questions