[英]PyParsing not behaving as expected with nested grammar
我有一个关于嵌套语法的问题。 你如何让 pyparsing 寻找嵌套的语法结构。
from pyparsing import Word, alphas, alphanums, Suppress, LineEnd, LineStart, nums, Or, Group, OneOrMore, Literal, CaselessLiteral, Combine, Optional
word = Word(alphanums+'_')
object_type = Suppress("object ")+word.setResultsName("object_type")+Suppress('{')+LineEnd()
point = Literal('.')
e = CaselessLiteral('E')
plusorminus = Literal('+') | Literal('-')
number = Word(nums)
integer = Combine( Optional(plusorminus) + number )
floatnumber = Combine( integer +
Optional( point + Optional(number) ) +
Optional( e + integer )
)
attribute = word.setResultsName("attribute")
value = Or([floatnumber, word]).setResultsName("value")
attributes = Group(attribute+value+Suppress(";")+LineEnd())
namespace = Group(object_type+\ OneOrMore(attributes).setResultsName("attributes") + Suppress("}"))
all = OneOrMore(namespace).setResultsName("namespaces")
result = all.parseString(glm)
for n in result.namespaces:
print(n)
以下是我想解析的示例。 第一个命名空间按预期工作。 然而,第二个无法解析。 谁能解释我缺少什么?
"""object object_type1{
attr1 0.0111;
name name_of_object_1;
}
object object_type1{
attr1 0.02;
name name_of_object_2;
object object_type2{
name name_of_object_3;
}
}
"""
要定义递归文法,即,一个术语本身是其定义的一部分,您需要使用 pyparsing 的Forward
类。 在您的情况下, namespace
可以包含属性或嵌套命名空间。 为此,您首先必须为namespace
定义一种占位符:
namespace = Forward()
然后当需要定义内容(包括namespace
作为定义的一部分)时,使用<<=
运算符而不是=
:
namespace <<= Group(object_type + OneOrMore(attributes|namespace).setResultsName("attributes") + Suppress("}"))
all = OneOrMore(namespace).setResultsName("namespaces")
除此之外,您的解析器应该可以正常工作。
还有一些其他提示:
我最近添加了pprint()
方法来简化列出 ParseResults 对象的内容。 尝试result.pprint()
而不是您现在使用的 for 循环。
您实际上并不需要输出中的换行符,因此将所有LineEnd()
术语替换为LineEnd().suppress()
- 这将使您的结果LineEnd().suppress()
。
在这种情况下,我不确定结果名称是否真的对您有用。 但我发现使用expr("name")
比expr.setResultsName("name")
更具可读性。 但任何一种形式都可以正常工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.