Parsimonious ParseError

419 Views Asked by At

Digging deeper into grammars and PEG in special, I wanted to have a DSL with the following syntax:

a OR (b AND c)

I am using parsimonious here with the following grammar:

from parsimonious.grammar import Grammar
grammar = Grammar(
    """
    expr            = (term operator term)+
    term            = (lpar term rpar) / (variable operator variable)
    operator        = and / or
    or              = _? "OR" _?
    and             = _? "AND" _?
    variable        = ~r"[a-z]+"
    lpar            = "("
    rpar            = ")"
    _               = ~r"\s*"
    """
)
print(grammar.parse('a OR (b AND c)'))

However, this fails for the above text with

parsimonious.exceptions.ParseError: Rule 'variable' didn't match at '(b AND c)' (line 1, column 6).

Why? Haven't I specified term as ( term ) or term ?
Why does it choose the rule for variable instead (which of course fails) ?

1

There are 1 best solutions below

1
On BEST ANSWER

The first thing in expr is a term, so that's what the parser looks for.

A term in your grammar is either

( term )

or

variable operator variable

And the input is

a OR (b AND c)

That doesn't start with a ( so the only way it can be a term is if it matches variable operator variable. a is a variable; OR is an operator. So the next thing to match is variable.


Perhaps what you want is:

expr = term (operator term)*
term = (lpar expr rpar) / variable