Страница Примеры на вики-сайте pyparsing содержит пример SimpleBool.py, который будет анализировать и оценивать выражения, такие как:
test = ["p and not q",
"not not p",
"not(p and q)",
"q or not p and r",
"q or not (p and r)",
"p or q or r",
"p or q or r and False",
]
(Хммм, примеров с вложенными паренами нет, но эти также поддерживаются .)
Фактический синтаксический анализатор полностью определен с использованием этого кода:
boolOperand = Word(alphas,max=1) | oneOf("True False")
boolExpr = operatorPrecedence( boolOperand,
[
("not", 1, opAssoc.RIGHT, BoolNot),
("and", 2, opAssoc.LEFT, BoolAnd),
("or", 2, opAssoc.LEFT, BoolOr),
])
В оставшейся части примера приведены реализации BoolNot, BoolOr и BoolAnd. Конструкция operatorPrecedence определяет последовательность операций, их арность и ассоциативность, а также, необязательно, класс, который будет создан с проанализированными элементами. Затем operatorPrecedence позаботится об определении грамматики, включая рекурсивное определение boolExpr во вложенных скобках. Результирующая структура похожа на вложенную AST с использованием данных классов BoolXxx. Эти классы, в свою очередь, определяют eval
методы, так что выражения могут быть проанализированы и оценены с использованием этого кода:
p = True
q = False
r = True
for t in test:
res = boolExpr.parseString(t)[0]
print t,'\n', res, '=', bool(res),'\n'
pyparsing сам по себе является довольно длинным модулем, но это единственный исходный файл, поэтому его площадь установки довольно мала. Лицензия MIT разрешает некоммерческое и коммерческое использование.