¿Qué herramienta de Python me puede recomendar para analizar lenguajes de programación? Debería permitir una representación legible de la gramática del lenguaje dentro de la fuente, y debería poder escalar a lenguajes complicados (algo con una gramática tan compleja como, por ejemplo, Python).

Cuando busco, encuentro principalmente pyparsing, que evaluaré, pero por supuesto estoy interesado en otras alternativas.

Editar: puntos de bonificación si viene con buenos informes de errores y ubicaciones de código fuente adjuntas a elementos de árbol de sintaxis.

31
Stefan Majewsky 4 jul. 2011 a las 17:09

9 respuestas

La mejor respuesta

Realmente me gusta pyPEG. Su informe de errores no es muy amigable, pero puede agregar ubicaciones de código fuente al AST.

PyPEG no tiene un lexer separado, lo que dificultaría el análisis de Python (creo que CPython reconoce la sangría y la sangría en el lexer), pero he usado pyPEG para construir un analizador para el subconjunto de C # con sorprendentemente poco trabajo.

Un ejemplo adaptado de fdik.org/pyPEG/: un simple lenguaje como este:

function fak(n) {
    if (n==0) { // 0! is 1 by definition
        return 1;
    } else {
        return n * fak(n - 1);
    };
}

Un analizador pyPEG para ese idioma:

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
32
djromero 12 abr. 2017 a las 16:52

Antlr genera analizadores LL (*). Eso puede ser bueno, pero a veces eliminar toda recursividad izquierda puede ser engorroso.

Si tiene conocimientos de LALR (1), puede usar PyBison. Tiene una sintaxis similar a Yacc, si sabes lo que es. Además, hay muchas personas que saben cómo funciona el yacc.

0
Thaddee Tyl 8 jul. 2011 a las 10:36

Para la tarea simple , tiendo a usar la shlex.

Consulte http://wiki.python.org/moin/LanguageParsing para evaluar el análisis del lenguaje en python .

1
Fredrik Pihl 4 jul. 2011 a las 13:24

PyPEG (una herramienta que escribí) tiene una función de rastreo para informar de errores.

Simplemente configure pyPEG.print_trace = True y pyPEG le dará un rastro completo de lo que está sucediendo dentro.

9
Michael Allen 10 dic. 2015 a las 22:48

Antlr es lo que debe mirar http://www.antlr.org

Eche un vistazo a este http://www.antlr.org/wiki/display/ANTLR3 / Antlr3PythonTarget

4
Ankur Gupta 4 jul. 2011 a las 13:11

Le recomendaría que revise mi biblioteca: https://github.com/erezsh/lark

Puede analizar TODAS las gramáticas sin contexto, crea automáticamente un AST (con números de línea y columna) y acepta la gramática en formato EBNF, que se considera el estándar.

Puede analizar fácilmente un lenguaje como Python, y puede hacerlo más rápido que cualquier otra biblioteca de análisis escrita en Python.

13
Erez 16 mar. 2017 a las 17:37

Ned Batchelder realizó una encuesta sobre las herramientas de análisis de Python, que aparentemente mantiene actualizadas (última actualización en julio de 2010):

http://nedbatchelder.com/text/python-parsers.html

Si fuera a necesitar un analizador hoy, rodaría mi propio analizador de descenso recursivo, o posiblemente usaría PLY o LEPL - dependiendo de mis necesidades y de si estaba o no dispuesto a introducir una dependencia externa . Yo personalmente no usaría PyParsing para algo muy complicado.

2
Matt Anderson 8 jul. 2011 a las 13:35

Para un analizador más complicado, usaría pyparsing. Pyparsing

Aquí está el ejemplo analizado de la página de inicio

from pyparsing import Word, alphas
greet = Word( alphas ) + "," + Word( alphas ) + "!" # <-- grammar defined here
hello = "Hello, World!"
print hello, "->", greet.parseString( hello )
4
Jakob Bowyer 4 jul. 2011 a las 13:15

Si está evaluando PyParsing, creo que debería mirar funcparserlib: http://pypi.python.org/ pypi / funcparserlib

Es un poco similar, pero en mi experiencia el código resultante es mucho más limpio.

2
Alexander Solovyov 4 jul. 2011 a las 13:54