当没有操作(pyparsing)时,如何阻止 infix_notation 匹配基本表达式?

How do you stop infix_notation from matching the base expression when there are no operations (pyparsing)?

我正在尝试使用 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. ...

请注意,infix_term 的 Word(printables, ...) 表达式将匹配几乎所有内容,包括 ......、整数、浮点数等。此外,exclude_chars 参数不匹配将字符串拆分为运算符,但只使用字符串中的所有字符。所以您不能使用“-10”作为术语,因为“-”在 exclude_chars 的集合中。因此,请多考虑一下如何最好地定义您的操作数。

最后,您的 infix_notation 运算符列表很长,如果您不启用 packrat 解析(使用 ParserElement.enable_packrat().

,这将是一个 sloooooooowwwww 解析器