Reputation: 2199
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
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