我已经构建了一个原始的解析器,但是我真的希望在pyparsing中使用它。在
我想解析两种类型的字符串。 只解析节点和第二个节点关系的程序
verb node1, node2, ...
以及
^{pr2}$可以指定一个或多个可以引用的节点
另外,您可以通过添加^
来指示一个节点在另一个节点内
verb node1, node2 ^ node3, node4
您还可以使用->
、<-
或<->
指示符来指示节点关系。在
verb node1->node2<->node3
同样,您可以使用^
来指示一个节点在另一个节点内
verb node1->node2^node4<->node3
此格式的概念性BNF如下所示:
这几乎一步一步地映射到pyparsing:
^{pr2}$下一部分最容易使用pyparsing的}:
infixNotation
方法(以前称为operatorPrecedence
)实现。infixNotation
允许我们定义操作的层次结构,并将根据层次结构定义的优先级对解析的输出进行分组。我假设您的'^'
“is inside”运算符应该在二进制'->'
等运算符之前求值。infixNotation
也允许在括号中嵌套,但是没有一个示例显示这是绝对需要的。定义infixNotation
的方法是:指定基本操作数类型,后跟3个元组的列表,每个元组显示运算符,一元运算符、二元运算符或三元运算符的值为1、2或3,运算符的左或右关联性为常量opAssoc.LEFT
或{最后,我们定义了整个表达式,我将其解释为某种命令。以逗号分隔的节点表达式列表可以直接实现为
nodeExpr + ZeroOrMore(Suppress(',') + nodeExpr)
(我们从解析的输出中抑制逗号—它们在解析时很有用,但之后我们只需跳过它们)。但这会出现在所以通常,pyparsing提供了一种方法delimitedList
:“verb”和“nodes”这两个名称会导致在相应表达式中解析的结果与这些名称相关联,这将使解析完成后更容易处理已解析的数据。在
现在要测试解析器:
dump()
方法将解析后的标记打印为嵌套列表,然后列出每个结果名称及其附加值:此时,您只需解析命令,然后基于
verb
,将其分派到执行该谓词的任何适当方法。在但是让我推荐一种结构,我发现这个结构有助于使用Python对象来捕获这种逻辑。定义一个简单的命令类层次结构,在抽象方法
doCommand
中实现各种动词函数:此方法将把分析的结果转换为相应命令类的实例:
但是您也可以将其作为解析时间回调构建到解析器中,这样一旦解析完成,您不仅可以得到一个字符串和子列表的列表,而且可以通过调用其
doCommand
方法来获得一个准备“执行”的对象。为此,只需将tokensToCommand
作为整个nodeCommand
表达式的解析操作:现在我们稍微修改一下测试代码:
因为我们实际上并没有在子类上实现
doCommand
,所以我们得到的只是默认的基类行为,即只回显已解析的谓词和节点列表:(这段代码是用python3,pyparsing 2.0.0运行的。它还将与python2一起运行,pyparsing 1.5.7)
编辑
要将链接表达式
a op b op c
转换为[a,op,b], [b, op, c]
,请使用parse操作将解析后的[a,op,b,op,c]结果重新构造为成对表达式。infixNotation
方法允许您定义一个解析操作以附加到操作符层次结构中的级别。在重新构造链接表达式结果的方法如下所示:
这将构建一个全新的ParseResults来替换原来的链接结果。注意每个
lastexpr op nextexpr
如何保存为自己的子组,然后nextexpr
被复制到lastexpr
,然后循环获得下一个op nextexpr对。在要将此重新格式附加到解析器中,请将其添加为
infixNotation
中该层次结构级别的第四个元素:现在输出:
扩展到:
相关问题 更多 >
编程相关推荐