我强烈推荐pyparsing:
与传统的 lex/yacc 方法或使用正则表达式相比,pyparsing 模块是创建和执行简单语法的另一种方法。
由于类名一目了然,并且使用了“+”、“|” ,因此该语法的 Python 表示非常
易读。和 '^' 运算符定义。从 parseString() 返回的解析结果可以作为嵌套列表、字典或具有命名属性的对象进行访问。
示例代码(来自 pyparsing 文档的 Hello world):
from pyparsing import Word, alphas
greet = Word( alphas ) + "," + Word( alphas ) + "!" # <-- grammar defined here
hello = "Hello, World!"
print (hello, "->", greet.parseString( hello ))
输出:
Hello, World! -> ['Hello', ',', 'World', '!']
编辑:这是您的示例语言的解决方案:
from pyparsing import *
import json
identifier = Word(alphas + nums + "_")
expression = identifier("lhs") + Suppress("=") + identifier("rhs")
struct_vals = delimitedList(Group(expression | identifier))
structure = Group(identifier + nestedExpr(opener="{", closer="}", content=struct_vals("vals")))
grammar = delimitedList(structure)
my_string = "something{name1, name2, opt1=2, opt2=text}, something_else{name3, opt1=58}"
parse_result = grammar.parseString(my_string)
result_list = parse_result.asList()
def list_to_dict(l):
d = {}
for struct in l:
d[struct[0]] = {}
for ident in struct[1]:
if len(ident) == 2:
d[struct[0]][ident[0]] = ident[1]
elif len(ident) == 1:
d[struct[0]][ident[0]] = None
return d
print json.dumps(list_to_dict(result_list), indent=2)
输出:(漂亮地打印为 JSON)
{
"something_else": {
"opt1": "58",
"name3": null
},
"something": {
"opt1": "2",
"opt2": "text",
"name2": null,
"name1": null
}
}
使用pyparsing API作为探索 pyparsing 功能和了解我的解决方案的细微差别的指南。我发现掌握这个库的最快方法是在您自己想出的一些简单语言上进行尝试。