如何解析没有分隔符的元组?

How to parse tuples that has no delimiters?

我正在使用 pyparser 并想解析包含树结构的文件,其值存储在等号之后,否则没有实际的分隔符。

除了极少数情况下数据存储在多行之外,我已经完成了所有解析,所以我必须重写解析器不要停止从等号到行尾但从等号获取值到另一个等号(或 end),忽略前面的单词(或忽略 end)。

数据示例:

(
  ItemName = foo
  SomeOtherStuff = bar
  foo1
  foo2
  AString1 = ItemName
  SomeOtherStuff 
)

代码:

equals = Suppress("=")
token = Word(alphanums + "-,./_:*+=#[];")
decimal = Regex(r'-?0|[1-9]\d*').setParseAction(lambda t:int(t[0]))
stringTemplate = token | decimal
sexpList = Group(Suppress("(") + ZeroOrMore(sexp) + Suppress(")")) 
sexp = Forward()

这显然行不通

astring = Group(stringTemplate + equals + stringTemplate)

所以我试过这些:

multilineString = Group(token + equals + OneOrMore(stringTemplate) + ~FollowedBy(stringTemplate + equals))
multilineString = Group(token + equals + OneOrMore(stringTemplate) + NotAny(stringTemplate + equals))
multilineString = Group(token + equals + OneOrMore(stringTemplate) + ~(stringTemplate + equals))

但是没有用。我得到的要么是错误,要么是解析器将所有数据吞噬为一条记录。

您在 ~FollowedBy 的正确轨道上,但这些表达式必须是 OneOrMore 重复表达式的一部分。类似于:

multilineString = Group(token + equals + OneOrMore(stringTemplate + ~FollowedBy(equals)))
for match in multilineString.searchString(test):
    match.pprint()

其他一些评论:

  • 查看 tokendecimalstringTemplate 的定义。就目前而言,您永远不会匹配 decimal 表达式。为避免将 integer 误认为 token,我建议您将 token 更改为 Word(alphas, alphanums + "-,./_:*+=#[];")
  • 您可能需要重新考虑是否要允许“=”作为 token 的一部分。如果有人在 token 和定界符“=”之间省略了 space,那么本应作为定界符的内容将被吸收到 token 键中。
  • 考虑添加结果名称以帮助您访问每个键值对的键和值位:multilineString = Group(token("key") + equals + OneOrMore(stringTemplate + ~FollowedBy(equals))("value"))。然后你可以像 match.keymatch.value 一样访问它们 - 当然你可以只使用列表索引来获取密钥 match[0],但我发现命名访问更容易使用。