使用哪种工具在Python中解析编程语言?

时间:2011-07-04 13:09:28

标签: python parsing

您可以推荐哪种Python工具来解析编程语言?它应该允许源内语言语法的可读表示,并且它应该能够扩展到复杂的语言(具有像Python本身一样复杂的语法)。

当我搜索时,我主要找到pyparsing,我将对此进行评估,但当然我对其他选择感兴趣。

编辑:奖励点,如果它附带了良好的错误报告和附加到语法树元素的源代码位置。

9 个答案:

答案 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

如果我今天需要解析器,我会推出自己的递归下降解析器,或者可能使用PLYLEPL - 根据我的需要以及我是否愿意引入外部依赖。我个人不会将PyParsing用于任何非常复杂的事情。

答案 7 :(得分:1)

对于简单任务,我倾向于使用shlex模块。

有关python语言解析的评估,请参阅http://wiki.python.org/moin/LanguageParsing

答案 8 :(得分:0)

Antlr生成LL(*)解析器。这可能很好,但有时删除所有左递归可能很麻烦。

如果你是LALR(1)-savvy,你可以使用PyBison。它具有与Yacc类似的语法,如果你知道它是什么。此外,有很多人知道yacc是如何工作的。