Я пытаюсь анализировать выражения с помощью pyparsing и могу сделать это с помощью infix_notation
, но проблема в том, что он соответствует строкам, которые не имеют операций, и просто соответствует аргументу base_expr. Это проблема, потому что допустимые ключевые слова могут сопоставляться с помощью base_expr.
Я использую это как infix_notation
expression = infix_notation(Word(
printables,
exclude_chars="** ~ + - * / % & | ^ != == <= >= < > ! , += -= *= /= %= <<= >>= &= |= ^="
),
[
("**", 2, OpAssoc.LEFT),
(one_of("~ + -"), 1, OpAssoc.RIGHT),
(one_of("* / % *= /= %="), 2, OpAssoc.LEFT),
(one_of("<< >> <<= >>="), 2, OpAssoc.LEFT),
(one_of("& | ^ &= |= ^="), 2, OpAssoc.LEFT),
(one_of("+ - += -="), 2, OpAssoc.LEFT),
(one_of("!= == <= >= < >"), 2, OpAssoc.LEFT),
(one_of("&& ||"), 2, OpAssoc.LEFT),
("!", 1, OpAssoc.RIGHT),
])
Проблемное совпадение это
Word(
printables,
exclude_chars="** ~ + - * / % & | ^ != == <= >= < > ! , += -= *= /= %= <<= >>= &= |= ^="
)
Таким образом, это будет соответствовать ключевому слову «else», которое мне не нужно, но оно также должно соответствовать переменным в выражении типа «else1 += else2».
Как бы вы это сделали?
Обычный способ отличить ключевые слова от идентификаторов — определить выражение для любого ключевого слова, подобное этому (получите список всех ключевых слов Python, но вы можете определить свой собственный список):
from keyword import kwlist
any_keyword = pp.one_of(kwlist, as_keyword=True)
infix_term = Word(
printables,
exclude_chars="** ~ + - * / % & | ^ != == <= >= < > ! , += -= *= /= %= <<= >>= &= |= ^="
)
operand = ~any_keyword + infix_term
expression = infix_notation(operand,
... etc. ...
Обратите внимание, что ваше выражение Word(printables, ...)
для infix_term будет соответствовать практически чему угодно, включая ......
, целые числа, числа с плавающей запятой и т. д. Кроме того, аргумент exclude_chars не разбивает строку на операторы, а просто использует все символы в строке. Таким образом, вы не сможете использовать «-10» в качестве термина, поскольку «-» находится в наборе exclude_chars. Так что подумайте еще немного о том, как лучше всего определить ваши операнды.
Наконец, ваш список операторов infix_notation довольно длинный, и это будет sloooooooowwwww синтаксический анализатор, если вы не включите синтаксический анализ packrat (используя ParserElement.enable_packrat()
.