Lepl - это универсальный анализатор рекурсивного спуска для Python, который я поддерживаю.
Это похоже на pyparsing в том, что оба парсера вы пишете прямо в Python. Вот пример, который анализирует и оценивает арифметическое выражение:
>>> from operator import add, sub, mul, truediv
>>> # ast nodes
... class Op(List):
... def __float__(self):
... return self._op(float(self[0]), float(self[1]))
...
>>> class Add(Op): _op = add
...
>>> class Sub(Op): _op = sub
...
>>> class Mul(Op): _op = mul
...
>>> class Div(Op): _op = truediv
...
>>> # tokens
>>> value = Token(UnsignedFloat())
>>> symbol = Token('[^0-9a-zA-Z \t\r\n]')
>>> number = Optional(symbol('-')) + value >> float
>>> group2, group3 = Delayed(), Delayed()
>>> # first layer, most tightly grouped, is parens and numbers
... parens = ~symbol('(') & group3 & ~symbol(')')
>>> group1 = parens | number
>>> # second layer, next most tightly grouped, is multiplication
... mul_ = group1 & ~symbol('*') & group2 > Mul
>>> div_ = group1 & ~symbol('/') & group2 > Div
>>> group2 += mul_ | div_ | group1
>>> # third layer, least tightly grouped, is addition
... add_ = group2 & ~symbol('+') & group3 > Add
>>> sub_ = group2 & ~symbol('-') & group3 > Sub
>>> group3 += add_ | sub_ | group2
... ast = group3.parse('1+2*(3-4)+5/6+7')[0]
>>> print(ast)
Add
+- 1.0
`- Add
+- Mul
| +- 2.0
| `- Sub
| +- 3.0
| `- 4.0
`- Add
+- Div
| +- 5.0
| `- 6.0
`- 7.0
>>> float(ast)
6.833333333333333
>>> 1+2*(3-4)+5/6+7
6.833333333333333
Основные преимущества Lepl по сравнению с pyparsing заключаются в том, что он немного более мощный (он может компилировать себя в регулярные выражения в местах для скорости, обрабатывать левые рекурсивные грамматики, использует трамплины для избежания исчерпания пространства стека). Основными недостатками является то, что он моложе, чем pyparsing, поэтому не имеет такое же количество пользователей или как большое и поддерживающее сообщество.