您可以推荐哪种Python工具来解析编程语言?它应该允许源内语言语法的可读表示,并且它应该能够扩展到复杂的语言(具有像Python本身一样复杂的语法)。
当我搜索时,我主要找到pyparsing,我将对此进行评估,但当然我对其他选择感兴趣。
编辑:奖励点,如果它附带了良好的错误报告和附加到语法树元素的源代码位置。
答案 0 :(得分:30)
我真的很喜欢pyPEG。它的错误报告不是很友好,但它可以向AST添加源代码位置。
pyPEG没有单独的词法分析器,这会使解析Python本身很难(我认为CPython会识别词法分析器中的缩进和dedent),但我使用pyPEG为C#的子集构建解析器,但工作量极少
改编自fdik.org/pyPEG/的例子:这样的简单语言:
function fak(n) {
if (n==0) { // 0! is 1 by definition
return 1;
} else {
return n * fak(n - 1);
};
}
该语言的pyPEG解析器:
def comment(): return [re.compile(r"//.*"),
re.compile("/\*.*?\*/", re.S)]
def literal(): return re.compile(r'\d*\.\d*|\d+|".*?"')
def symbol(): return re.compile(r"\w+")
def operator(): return re.compile(r"\+|\-|\*|\/|\=\=")
def operation(): return symbol, operator, [literal, functioncall]
def expression(): return [literal, operation, functioncall]
def expressionlist(): return expression, -1, (",", expression)
def returnstatement(): return keyword("return"), expression
def ifstatement(): return (keyword("if"), "(", expression, ")", block,
keyword("else"), block)
def statement(): return [ifstatement, returnstatement], ";"
def block(): return "{", -2, statement, "}"
def parameterlist(): return "(", symbol, -1, (",", symbol), ")"
def functioncall(): return symbol, "(", expressionlist, ")"
def function(): return keyword("function"), symbol, parameterlist, block
def simpleLanguage(): return function
答案 1 :(得分:11)
我建议您查看我的图书馆:https://github.com/erezsh/lark
它可以解析所有无上下文的语法,自动构建AST(带行和列号),并接受EBNF格式的语法,这被认为是标准。
它可以轻松地解析像Python这样的语言,并且它可以比用Python编写的任何其他解析库更快地完成。
答案 2 :(得分:8)
pyPEG(我创作的工具)有一个用于错误报告的跟踪工具。
只需设置pyPEG.print_trace = True
,pyPEG就会让您全面了解内部发生的情况。
答案 3 :(得分:4)
答案 4 :(得分:3)
对于更复杂的解析器,我会使用pyparsing。 Pyparsing
这是主页
中的解析示例from pyparsing import Word, alphas
greet = Word( alphas ) + "," + Word( alphas ) + "!" # <-- grammar defined here
hello = "Hello, World!"
print hello, "->", greet.parseString( hello )
答案 5 :(得分:2)
如果您正在评估PyParsing,我认为您应该查看funcparserlib:http://pypi.python.org/pypi/funcparserlib
它有点类似,但根据我的经验,生成的代码更清晰。
答案 6 :(得分:2)
Ned Batchelder对python解析工具进行了调查,显然他不断更新(最后更新于2010年7月):
http://nedbatchelder.com/text/python-parsers.html
如果我今天需要解析器,我会推出自己的递归下降解析器,或者可能使用PLY或LEPL - 根据我的需要以及我是否愿意引入外部依赖。我个人不会将PyParsing用于任何非常复杂的事情。
答案 7 :(得分:1)
对于简单任务,我倾向于使用shlex模块。
有关python语言解析的评估,请参阅http://wiki.python.org/moin/LanguageParsing。
答案 8 :(得分:0)
Antlr生成LL(*)解析器。这可能很好,但有时删除所有左递归可能很麻烦。
如果你是LALR(1)-savvy,你可以使用PyBison。它具有与Yacc类似的语法,如果你知道它是什么。此外,有很多人知道yacc是如何工作的。