2008-10-27 18 views
22

Quiero realizar algunas transformaciones en el código fuente C. Necesito una herramienta en Linux que genere un AST completo desde el código fuente para que pueda aplicar mis transformaciones en este AST y luego convertirlo de nuevo al código fuente C. Intenté ELSA pero no está siendo compilado. (Estoy usando Ubuntu 8.4). ¿Alguien puede sugerir una mejor herramienta/aplicación?AST desde el código C

+0

Creo OPENÇ ++ es lo más cerca que obtendrá en este momento. –

Respuesta

0

¿Qué le parece tomar gcc y escribir un back-end personalizado para ello? Nunca lo hice ni siquiera trabajé en el código fuente de gcc, así que no sé qué tan difícil sería.

+1

¿Y cómo lo va a hacer para regenerar el código fuente después de aplicar las transformaciones? –

2

www.antlr.org

+0

Si bien la distribución predeterminada de ANTLR no contiene un analizador C, hay un número de ellos flotando, solo googleelos. Saludos, Sebastiaan –

+2

Hay analizadores C basados ​​en ANTLR. No sé si alguno de ellos puede regenerar la fuente desde un AST (modificado). –

5

Hay dos proyectos que yo sepa, y que podría ser de utilidad:

Ambos analizar un código fuente C estándar para permitir más análisis y transformación. No los he usado, así que debes verificarlos por ti mismo si se ajustan a tus necesidades.

La sugerencia de usar GCC también es válida, por supuesto. Aunque sé que no hay mucha documentación sobre este aspecto de gcc.

+0

CIL no regenera el código fuente, AFAIK. –

+0

Por lo que puedo deducir, CIL requiere que escriba sus análisis AST en OCaml; C soporte está planeado. –

0

Usted puede intentar generar AST (árbol de sintaxis abstracta) usando Lexx y yacc en Linux:

lex and yacc

from lex and yacc to ast

+0

El problema sería tener una gramática lex bastante completa para C, que no es una tarea fácil debido al preprocesador C, escribir reglas, etc. –

+0

Sí, lo sé, pero Lex y Yacc son herramientas muy potentes, así que me he equivocado un poco con ellas así que pensé que ayudaría a alguien con esta pregunta. Como C es un poco primitivo y, por supuesto, no es una tarea fácil, estoy totalmente de acuerdo con usted. – milot

+0

Requiere que baje y escriba sucio [MELT] (http://gcc-melt.org/) extensiones. –

17

recomendaría clang. Tiene una implementación de C bastante completa con la mayoría de las extensiones de gcc, y el código es muy comprensible. Su implementación en C++ es incompleta, pero si solo te importa generar AST a partir del código C, eso debería estar bien. Dependiendo de lo que quieras hacer, puedes usar clang como una biblioteca y trabajar directamente con los AST, o puedes enviar clang a la consola.

+1

Es absolutamente. Así es como funciona toda la funcionalidad de reescritura de clang-cc. Para un ejemplo concreto, consulte http://llvm.org/svn/llvm-project/cfe/trunk/lib/Frontend/RewriteBlocks.cpp, que es lo que sucede cuando ejecuta 'clang-cc -rewrite-blocks'. –

10

Ver pycparser - un generador AST pura en Python para C.

+0

Solo soporte C99. Puede ser suficiente para muchos. No fue para mí –

2

Nuestra DMS Software Reengineering Toolkit se ha utilizado en los sistemas enormes C, análisis, analizar, transformar y regenerar el código C. Se ejecuta en Windows y se ejecutará en Linux en Wine, pero maneja el código C de estilo Linux (GCC).

No puedo enfatizar lo suficiente la capacidad de recorrer el código fuente C: analizar, construir árboles, transformar, regenerar código C compilable con los comentarios y bien impreso o con la sangría del programador original. Algunas de las otras respuestas aquí sugieren sistemas que pueden hacer eso de manera robusta.

El hecho de que DMS está diseñado para llevar a cabo transformaciones de programa (a diferencia de otros sistemas sugeridos en las respuestas aquí) también es una gran ventaja. DMS proporciona coincidencias y reescrituras del patrón de árbol; aumenta esto con un control total y análisis de flujo de datos que se utilizarán para ampliar las condiciones que le gustaría igualar. Una herramienta que pretende ser un compilador es solo eso, y le costará mucho convencerlo de que no sea un compilador, y en su lugar sea un motor de transformación como solicitó el OP.

Véase https://stackoverflow.com/a/2173477/120163 por ejemplo ASTs producidos por DMS.

1

que he hecho pequeñas cantidades de trabajo sobre las transformaciones de fuente a fuente y encontré CIL a ser muy poderosa para esta tarea. CIL tiene la ventaja de ser un marco diseñado específicamente para el análisis y transformación de fuentes estáticas. También puede procesar código con cualquier cantidad de extensiones específicas de GCC feas (se ha usado para procesar el kernel de Linux, como un ejemplo). Lamentablemente, está escrito en OCAML, y los análisis/transformaciones creadas con él también deben escribirse en OCAML, que podría ser problemático si nunca lo has usado.

Alternativamente, se supone que clang tiene una base de código relativamente fácil de piratear y ciertamente puede usarse para producir C AST.

+0

Sí, CIL regenerará el código C compilable (por ejemplo, ¿qué ocurre con los comentarios?) Simplemente no es un código fuente reconocible por el programador original. Eso hace que CIL sea útil para el razonamiento y las optimizaciones de código, pero no para transformar el código de un programador. –

0

"Traté ELSA pero no está recibiendo compilado. (Estoy usando Ubuntu 8.4)"

El código fuente de Elkhound y Elsa, la versión de 2005.08.22b scottmcpeak.com/elkhound/ está desactualizado (archivos antiguos de encabezado .h de estilo de C++).

Elsa está trabajando y es parte de Oink: http://www.cubewano.org/oink/#Gettingthecode Lo acabo de hacer funcionar ahora bajo Ubuntu 9.10.

+0

Elsa admite abiertamente que no maneja todo el código fuente no válido en su página de inicio. –

+1

Elsa es un generador de analizador sintáctico, por lo que transformar el código (parte de salida de ese proceso) será un desafío. –

4

Para obtener resultados AST XML puede intentar utilizar cscan desde MarpaX::Languages::C::AST. La salida se parecerá a:

xml <cscan> <typedef_hash> <typedef id="GLenum" before="unsigned int" after="" file="/usr/include/GL/gl.h"/> ...