Экономный ParseError - PullRequest
       15

Экономный ParseError

0 голосов
/ 26 февраля 2019

Копаясь глубже в грамматику и PEG в частности, я хотел иметь DSL со следующим синтаксисом:

a OR (b AND c)

Я использую parsimoniousздесь со следующей грамматикой:

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)'))

Однако, это терпит неудачу для вышеупомянутого текста с

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

Почему?Разве я не указал term как ( term ) или term?
Почему вместо этого выбирается правило для variable (что, конечно, не получается)?

1 Ответ

0 голосов
/ 26 февраля 2019

Первое, что есть в expr - это term, так что именно это ищет синтаксический анализатор.

A term в вашей грамматике - либо

( term )

, либо

variable operator variable

И ввод:

a OR (b AND c)

Это не начинается с (, поэтому единственный способ, которым это может быть term, это если он соответствует variable operator variable.a является variable;OR - это operator.Итак, следующая вещь, которую нужно сопоставить - это variable.


Возможно, вы хотите:

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