2011-10-25 34 views
23

Quiero ser capaz de realizar la generación de código de python con una descripción AST.Generador de código Python

He realizado análisis estáticos de C y he creado visitantes AST en python, por lo que me siento relativamente cómodo manipulando un árbol de sintaxis, pero nunca he intentado generar código antes y estoy tratando de determinar la mejor práctica para generar código python .

Específicamente, me encantaría los punteros sobre cómo se genera normalmente la generación automática de código, o cualquier referencia a las bibliotecas dirigidas a python, lo que podría simplificar esta tarea.

Mi objetivo final es intentar algo similar a csmith o una herramienta para hacer que el código de python cumpla con PEP8.

+0

¿Está utilizando un AST personalizado o está creando un Python AST (utilizando, por ejemplo, el módulo 'ast')? –

+0

Lo más probable es que Python AST, utilizando el módulo 'ast'. Me di cuenta de que ANTLR ha atendido un poco a Python, y eso parece un posible camino a seguir, pero parece más sensato quedarse con las partes internas de Python. – mvanveen

Respuesta

16

Es posible que desee echar un vistazo a la herramienta 2to3, desarrollada por los desarrolladores de código Python para convertir automáticamente el código Python 2 al código Python 3. La herramienta primero analiza el código de un árbol, y luego arroja el código "fijo" de Python 3 desde ese árbol.

Este puede ser un buen lugar para comenzar porque es una herramienta Python "oficial" avalada por los desarrolladores principales, y parte de la ruta de migración recomendada de Python 2 a 3.

alternativa, echa un vistazo a la codegen.py module, que genera código Python de vuelta de Python de ast.

Ver también este SO question, que pueden ser relevantes a la suya (no estoy marcando un duplicado, porque no estoy seguro de los alcances de las preguntas se superponen 100%)

4

Generación automática de código se hace comúnmente en las siguientes maneras:

  • declaraciones de impresión que contiene fragmentos de código
  • plantillas de texto con marcadores de posición (macros creo)

En mi humilde opinión, una mejor práctica es:

  • construyó un AST para el fragmento diana, y luego prettyprint

Casi nadie hace esto último, ya que las herramientas son en su mayoría no existe.

La herramienta 2to3 de Python proporciona (creo) el objetivo AST y la impresión bonita.

Pero una pregunta que no hizo, ¿es "generar desde qué?" De alguna manera, debe especificar de forma abstracta lo que desea generar (o no es una ganancia). Y tu herramienta tiene que poder leer esa especificación de alguna manera.

Muchos esquemas de generación de código consisten en escribir código de procedimiento que llama a los mecanismos de generación anteriores; el código de procedimiento actúa como una especificación implícita. Es "fácil" leer la especificación; es solo código en el lenguaje utilizado por el generador de código.

Algunos esquemas de generación de código utilizan algún tipo de estructura de gráfico para proporcionar un marco en el que se cuelgan los fragmentos de especificación, que dirigen la generación de código. Los diagramas de clase UML son un ejemplo clásico. Estos esquemas no son tan fáciles; necesita un "lector de especificaciones" (p., Lector de diagramas UML aka XMI o algo así, o si no está utilizando UML, algún tipo de analizador de especificación).

La herramienta Python 2to3 usa un analizador Python2 para leer la "especificación". Si desea generar código desde Python2, eso estará bien. Sospecho que no quieres hacer eso.

Un enfoque mejor es uno que unifica la capacidad de leer/analizar las especificaciones/poligonal, con la capacidad de producir AST para el idioma de destino.

Nuestro DMS Software Reengineering Toolkit es un sistema de análisis y transformación de programas de propósito general. Analiza "especificaciones" (instancias de gramáticas que puede definir) en AST; también le permitirá construir AST arbitrarios para cualquiera de esas gramáticas, utilizando ya sea código de procedimiento [como se bosquejó anteriormente] o usando patrón-coincidencia/reemplazo (prácticamente exclusivo de DMS). Parte de un front end de DMS es una impresora bonita, que puede regenerar texto de ASTs (estos son probados por el código de ida y vuelta: parse a AST, prettyprint AST, mejor sea el mismo texto).

En caso de que su gramática no se conoce a DMS, que tiene muy buena analizador y generadores prettyprinter, así como otros mecanismos de apoyo para el análisis de los programas. Toda esa maquinaria adicional generalmente no está disponible con los generadores de analizadores clásicos, o con un simple paquete "AST". (No sé qué es 2to3).

La relevancia de esto para Python es que DMS tiene un Python front end y grammars for many other languages.

Por lo tanto, puede analizar su especificación y generar el código de Python utilizando AST seguidos de impresión bonita.

Cuestiones relacionadas