在缩短和简化的伪代码中,我有如下内容:
arg = Forward()
...
...
func_call = somestuff + arg
term = ... | ... | arg
expression = infix_notation(term, operator_rules)
...
...
arg <<= expression | func_call | ... | ...
...
statement = var + ASSIGN + expression
code_line = Optional(White()) + (statement | func_call | expression) + Optional(dbl_slash_comment).leaveWhitespace()
所以我不知道如何在这里解决的问题是,我需要几乎相同的代码,但在operator_rules
中有不同的parse_action.如果expression
是这里最后定义的东西(不依赖于任何Forward()
组件),那么我只需要创建一个模块,在其中保存其他所有内容,然后只需将term
导入两个不同的模块,并根据需要在operator_rules
中使用不同的解析操作来使用不同的expression
infix_notation.
我目前的解决方案是使用此代码创建两个相同的模块,然后修改其中一个模块中的parse_action函数.但这感觉像是一种糟糕的做法.如果我需要更改此解析器中的某些内容,则需要在两个模块中都进行更改.
我觉得在这里我对pyparsing的工作原理一无所知.
我知道可以使用set_parse_action()
来导入ParserElement并重写其解析操作,但不知道如何使用infix_notation元素来实现.Another issue是向前定义的arg依赖于infix_notation元素,所以即使我只需导入expression
并在infix_notation中重写其解析操作,也不会重写expression
和向前定义的arg
之后的元素,对吗?
我try 将整个解析器放在一个函数中,然后使用查看输入的if语句创建具有不同运算符规则的infix_notation.它是有效的,但这看起来很笨重,仍然不能解决"一些涉及到远期定义项的元素的导入".事实上,由于我现在已经将所有内容放在一个函数中,所以我甚至不能导入最后的code_line
个ParserElement以在我定义条件 struct 的另一个模块中使用.
因此,我认为问题有两个方面:
- 有什么方法可以覆盖infix_notation的OPERATOR_RULES(包括解析操作和运算符规则的总列表)吗?(为什么我真的需要它-部分原因是随着嵌套表达式的数量增加,执行时间似乎呈指数增长,所以我根据要解析的字符串限制了定义的运算符的数量).
- 在infix_notation中用作
term
的前向定义元素似乎阻止了我导入infix_notation元素来重写operator_rules
,如果这是可能的话.
我甚至不确定这里是否有一个优雅的解决方案可以让代码保持干燥,但任何见解/建议都是非常感谢的!