我必须使用 Python (pyparse) 解析未明确定义的遗留文件格式。
它属于大括号家族(事实上,必须解析任意大括号格式是一个反复出现的问题,因为人们总是喜欢“XML 太冗长了,让我们发明自己的格式”)。
所以我有类似的东西
Variable = [1, 2]
Variable2 = {
Variable,
"Literal",
}
Variable[1] = Variable2
Namespace::Function(argument, {"string literal",
100})
换行符在表达式之外很重要(像 C 中的
;
那样的分隔语句),但在任何类型的大括号中都不重要({}
、()
和 []
)。
为了理解它,需要对其进行解析:
因此,对于上面的示例,AST 应该如下所示:
Root
* Brace: \n
* Token: 'Variable ='
* Brace: []
* Token: '1'
* Token: '2'
* Brace: \n
* Token: 'Variable2 ='
* Brace: {}
* Token: 'Variable'
* Token: '"Literal"'
* Brace: \n
* Token: 'Variable'
* Brace: []
* Token: '1'
* Token: '= Variable2'
* Brace: \n
* Token: 'Namespace:Function'
* Brace: ()
* Token: 'argument'
* Brace: {}
* Token: '"string literal"'
* Token: '100'
在 Python 中表示为:
[
Brace('\n', [
'Variable =',
Brace('[]', ['1', '2'])
]),
...
问题是
(我使用了一个专用的解析器包来执行(1),但结果是(2)完全无法用于任何进一步的步骤,所以我再次尝试,这次使用
pyparsing
。)
使用“pyparsing”解析卷曲基本格式:
pyparsing
创建处理变量、文字、不同类型括号 ('[]','{}','()')
的规则。使用 nestedExpr
表示嵌套结构。from pyparsing import Word, alphas, nums, nestedExpr, quotedString, Group, ZeroOrMore, LineEnd
identifier = Word(alphas + "_", alphas + nums + "_")
literal = quotedString
square_braces = nestedExpr('[', ']', content=identifier | literal)
curly_braces = nestedExpr('{', '}', content=identifier | literal | square_braces)
parentheses = nestedExpr('(', ')', content=identifier | curly_braces)
statement = Group(identifier + '=' + (square_braces | curly_braces | parentheses))
grammar = ZeroOrMore(statement + LineEnd().suppress())
Brace
类来表示不同的大括号类型。class Brace:
def __init__(self, brace_type, children):
self.brace_type = brace_type
self.children = children
def create_ast_node(tokens):
return Brace(tokens[0], tokens[1:])
statement.setParseAction(create_ast_node)
解析您的输入并生成 AST
input_text = """
Variable = [1, 2]
Variable2 = {
Variable,
"Literal",
}
"""
result = grammar.parseString(input_text)
print(result)
这种方法可以有效地解析自定义大括号格式,并将输出组织成结构化、可用的形式。我希望我的定义有帮助!