2010-12-03 14 views
13

¿Existe alguna implementación conocida de la herramienta de preprocesador C implementada en Python o JavaScript? Estoy buscando una forma de preprocesar de forma robusta el código fuente C (y C) y quiero poder procesar, por ejemplo, compilación condicional y macros sin invocando una herramienta CPP externa o una biblioteca de código nativo. Otro posible caso de uso es el procesamiento previo dentro de una aplicación web, dentro del navegador web.Implementación de un preprocesador C en Python o JavaScript?

implementaciones Hasta ahora, he encontrado en Java, Perl, y por supuesto, C y C nuevo. Puede ser plausible utilizar uno de los compiladores C to JavaScript ahora disponibles.

Las herramientas PLY (Python Lex y Yacc) incluyen un cpp implementado en Python.

+0

"Una herramienta externa de CPP" normalmente se integra en el compilador. ¿Para qué necesitas esto? –

+0

Eso parece mucho trabajo para poco beneficio. ¿Por qué sería esto importante? –

+0

** Puedes ** implementarlo siempre tú mismo: el preprocesador es extremadamente simple (de hecho, creo que es regular, por lo que ni siquiera necesitarías gramáticas libres de contexto para interpretarlo). –

Respuesta

6

Consulte PLY, una implementación de Lex y Yacc en Python que contiene un cpp tool implemented in python usando el PLY lexer. También está pycparser, un analizador construido sobre PLY para el lenguaje C.

+2

Lamentablemente, pycparser no es compatible con el código C, excepto después de invocar el preprocesador. – grrussel

+0

pycparser puede [invocar el preprocesador] (https://bitbucket.org/eliben/pycparser/#interaction-with-the-c-preprocessor) – kynan

0

Si antlr se puede utilizar con Python/Javascript (Dudo mucho que este último), se puede obtener una gramática del sitio antlr: http://www.antlr.org/grammar/1166665121622/Cpp.tar

Si no es así, podría ser un buen comienzo de todos modos - simplemente convertir a una gramática entendida por su generador de analizador favorito.

+2

Desafortunadamente, la parte más difícil de implementar un preprocesador es la lógica personalizada que debe escribirse para la sustitución de macro y la evaluación de expresión de rango restringido. –

1

Puede crear un enlace de pitón alrededor del preprocesador de clang c.

+0

libclang viene con enlaces de Python hoy en día. Ver [Análisis en C++ en Python con Clang] (http://eli.thegreenplace.net/2011/07/03/parsing-c-in-python-with-clang/). – prideout

1

El sistema de compilación de Firefox hace algo similar para su Chrome. Un archivo fuente llamado jar.mn lista todos los archivos XUL/JS necesarios y, opcionalmente, estos archivos se preprocesan antes de enviarlos. Por lo tanto, la secuencia de comandos que ships los archivos también invoca un mini- preprocessor.

7

Salida pypreprocessor

también se puede conocer en PYPI (Python Package Index) por lo que puede ser descargado directamente a través de la pipa.

Si está buscando utilizar sentencias #define y #ifdef para realizar una compilación condicional simple, debería satisfacer sus necesidades. Puede ejecutarlo como una secuencia de comandos independiente y especificar un archivo de entrada (que puede estar en cualquier idioma) para procesar o puede importarlo como un módulo de python y usarlo para autoconsumir la fuente de Python.

pypreprocessor hace no apoyo:

  • macro reemplazo
  • operaciones
  • lógicos (. Ie || & &)
  • operaciones matemáticas (. Ie + - * /)
  • preprocesador de líneas múltiples directivas

Es una herramienta diseñada específicamente para compilación condicional, no metaprogramación.

Aquí hay un ejemplo de cómo procesar un archivo C utilizando pypreprocessor como un proceso independiente:

from pypreprocessor import pypreprocessor 

pypreprocessor.defines.append('debug') 
pypreprocessor.input = 'input_file.c' 
pypreprocessor.output = 'output_file.c' 
pypreprocessor.removeMeta = True 

pypreprocessor.parse() 

La aplicación es bastante simple.

defines.append ('debug'):

tiene el mismo efecto que la adición de una directiva 'depuración #define' en el fichero. Esta es solo una forma conveniente de establecer define.

pypreprocessor.input = 'input_file.c':

Establece el archivo que desea procesar.

pypreprocessor.output = 'output_file.c':

Conjuntos donde está el archivo de salida a.

pypreprocessor.removeMeta = True:

Elimina todas las directivas del preprocesador que se encuentran en el archivo. Esto incluye todos los #define, #ifdef, #undefine, #else, etc. del archivo fuente. Esto es útil para crear una versión de producción "limpia" de la fuente menos todos los códigos condicionales y las directivas que no se utilizan. Este paso también es completamente opcional. Si no agrega esto, cualquier código que no entre en una condición definida se comentará automáticamente.

Por ejemplo:

#define debug 

#ifdef debug 
print('this will appear in the postprocessed code') 
#else 
#print('this will be commented out in the postprocessed code') 
#endif 

Si usted necesita el reemplazo macro para, por ejemplo, cambiar la fuente de un idioma a otro pyprocessor no soporta esto todavía. En teoría, no requeriría mucho trabajo agregar, pero el lexer tendría que extenderse primero para omitir las palabras clave que aparecen en las cadenas de texto.

SideNote: También es compatible con python2x y python3k.

Descargo de responsabilidad: soy el autor de pypreprocessor.

+0

cuál es la nueva ubicación del proyecto, ya que Google Code anunció que se está cerrando ¿pronto? Gracias. – 0xC0000022L

+0

@ 0xC0000022L Eventualmente, https://github.com/evanplaice/pypreprocessor. Por ahora, el proyecto está 'archivado' y todavía accesible en Google Code. –

+1

@ 0xC0000022L El proyecto se ha movido y el repositorio se ha convertido de Mercurial a Git. Queda un poco de trabajo para actualizar la documentación y enviar la última versión (es decir, 0.5.0) a PYPI, pero esas deberían estar disponibles para mañana. –