2009-07-08 45 views
14

La entrada de Wikipedia para los C Preprocessor estados:Usando el preprocesador C para idiomas distintos del C

El lenguaje de preprocesador directivas es agnóstico a la gramática de C, por lo que el C preprocesador puede también ser utilizado de forma independiente para procesar otros tipos de archivos .

¿Cómo se puede hacer esto? ¿Algún ejemplo o técnica?

EDITAR: Sí, estoy principalmente interesado en el procesamiento de macro. Aunque probablemente no sea aconsejable o mantenible, aún sería útil saber qué es posible.

+5

¿Qué necesita hacer con el preprocesador? Si solo necesita macroprocesamiento, puede usar m4: http://www.gnu.org/software/m4/ – dwhall

+0

woah, m4? ¿Es enserio? Pensé que era una cosa bien olvidada para la mayoría de las personas. ¿Dónde se usa hoy en día? Una cosa que sé es que se usa para compilar los archivos .cf de sendmail. – shylent

+1

m4 puede seguir utilizándose cuando ejecuta configure; hacer; hacer la instalación Mire de cerca a configurar. –

Respuesta

16

Puede llamar CPP directamente:

cpp <file> 

En lugar de llamar a través de gcc:

gcc -E filename 

hacer la nota sin embargo, que, como se menciona en el mismo artículo de Wikipedia, el lenguaje de C preprocesador no es realmente equipada para uso de propósito general:

sin embargo, desde el preprocesador C no tiene características de algunos othe r preprocesadores, tales como macros recursivas, expansión selectiva según para cotizaciones, evaluación de cadenas en condicionales, y Turing integridad, es muy limitado en comparación con un procesador macro más general como m4.

¿Ha considerado incursionar con un lenguaje de macroprocesamiento más flexible, como el m4 antes mencionado, por ejemplo?

+2

+1 para la referencia a 'm4'. Tradicionalmente, este ha sido el preprocesador de elección para tareas complejas; CPP es muy primitivo en comparación. – ephemient

+6

No puede realmente "divertirse" con CPP. m4 por otro lado es un campo minado de disfrute; solo tiene que superar la joroba inicial de dolor. – kjfletch

+0

m4 se ve interesante, gracias a todos los que mencionaron eso. – user4812

0

Puede implementar el preprocesador C en el compilador para otro idioma.

Puede usarlo para preprocesar cualquier tipo de archivo de texto, pero hay cosas mucho mejores para ese propósito.

1

Normalmente puede invocar el compilador de C con una opción para preprocesar solamente (e ignorar cualquier instrucción #line). Tome esto como un simple ejemplo:

<?php 
function foo() 
{ 
#ifdef DEBUG 
    echo "Some debug info."; 
#endif 
    echo "Foo!"; 
} 

foo(); 

Definimos un archivo fuente PHP con declaraciones de preproceso. Podemos entonces se preprocesar (gcc puede hacer esto, también):

cl -nologo -EP foo.php > foo2.php 

Desde DEBUG no está definido es despojado de la primera echo. Además, aquí las líneas que comienzan con # son comentarios en PHP, por lo que no es necesario preprocesarlas para una compilación de "depuración".

Editar: Desde que ha preguntado acerca de las macros. Esto también funciona bien y podría usarse para generar código repetitivo, etc.

+0

¿La gente realmente está haciendo este tipo de cosas? – Geo

+1

@Geo, sí lo son. Perl tiene (o solía tener) una opción de línea de comandos para ejecutar el script de Perl a través de CPP antes de dejar que el analizador en él, por ejemplo. Si todo lo que necesita es un manejo #ifdef para activar y desactivar bloques de código o #include para compartir líneas de origen, cpp es realmente una herramienta de elección bastante buena. – RBerteig

2

Muchos compiladores de C tienen una bandera que les indica que solo preprocesen. Con gcc es la bandera -E. por ejemplo: la producción

$ gcc -E -     
#define FOO foo 
bar FOO baz 

voluntad:

# 1 "<stdin>" 
# 1 "<built-in>" 
# 1 "<command-line>" 
# 1 "<stdin>" 

bar foo baz 

con otros compiladores de C que tendrá que comprobar los manuales para ver cómo swithc a modo de preproceso-solamente.

+3

Quizás quieras que tu ejemplo realmente haga algo. – dborba

+0

Heh. Buen punto. Fijo. –

0

Básicamente lo que está diciendo es que los preprocesadores no tienen nada que ver con la sintaxis C. Básicamente son analizadores simples que siguen un conjunto de reglas. Así que podrías usar preprocesadores como si usaras sed o awk para algunas tareas tontas. Sin embargo, no me preguntes por qué querrías hacerlo.

Por ejemplo, en un archivo de texto:

#define pi 3.141 

pi is not an irrational number. 

entonces se corre el preprocesador & se obtendría.

3.141 no es un número irracional.

2

Por ejemplo, Ensamblador.Si bien muchos ensambladores tienen su propia forma de #incluir encabezados y #definir macros, puede ser útil usar el preprocesador C para esto. La creación de GNU, por ejemplo, tiene reglas implícitas para convertir archivos * .S en archivos * .s al ejecutar el preprocesador ('cpp'), antes de alimentar el archivo * .s al ensamblador GNU ('como').

+0

Aunque dependiendo del caso de una sola letra del nombre del archivo había una opción de diseño pobre allí ... donde hice lo equivalente en otros proyectos, he usado .asm o .src para la fuente "real" código, y el .s estándar para el código emitido por cpp. Desafortunadamente, hay muchos desarrolladores (incluso usando herramientas Gnu) que viven en sistemas de archivos que no pueden distinguir los nombres solo por caso. NTFS se predetermina para preservar las mayúsculas y minúsculas, pero no distingue entre mayúsculas y minúsculas, por ejemplo. – RBerteig

+0

No dije que era una opción * inteligente *.;-) – DevSolar

+0

En realidad, GNU Make no lo ejecuta a través del preprocesador C (al menos no directamente), sino que lo ejecuta mediante el compilador C '$ (CC)', este método funciona en sistemas de archivos sensibles a mayúsculas y minúsculas ya que no requieren dos archivos de nombre similar. –

1

Usando el compilador de Microsoft, creo (Acabo de mirar hacia arriba, no lo he probado) que es el /P compiler option.

Otros compiladores presumiblemente tienen opciones similares (o, para algunos compiladores, el preprocesador podría ser realmente un ejecutable diferente, que generalmente se ejecuta implícitamente por el compilador pero que también se puede ejecutar explícitamente por separado).

1

Suponiendo que está usando GCC, que puede tomar cualquier archivo de texto simple y llano, independientemente de su contenido, y ejecute:

gcc -E filename

Cualquier directivas del preprocesador en el fichero serán procesados ​​por el preprocesador y GCC luego salga

El punto es que no importa cuál es el contenido real del archivo de texto es, ya que todo el preprocesador preocupa es su propio directivas.

2

Sí, se puede hacer mediante el análisis de su propio idioma a través del preprocesador GCC (por ejemplo, 'gcc -E').

Hemos hecho esto en mi trabajo con nuestra nuestra, un lenguaje específico. Tiene bastantes ventajas:

  • Puede utilizar C de las sentencias de inclusión (# include) que es muy potente
  • Puede utilizar sus construcciones #ifdef
  • Puede definir Constantes (# define MAGIC_NUMBER 42) o funciones de macro (#define min (x, y) ((x (< (y) (x):?. (y))

... y las otras cosas en el procesador c

SIN EMBARGO, también heredas el construcciones C inseguras, y tener un preprocesador no integrado con su idioma principal es la causa de ello. Piense en el mínimo algo macro y haciendo como:

a = 2; 
b = 3; 

c = min(a--, b--); 

Basta con pensar qué valor A y B tendrán después de la función min?

Lo mismo es cierto acerca de las constantes no escrito que usted introduce

ver el libro Safer C para más detalles.

+0

Consulte su ejemplo de código fuente ... '2', porque los operadores postfix-increment/decomen son malos, no por nada que tenga que ver con el macro preprocesador de C. Como JavaScript, existe una cantidad de "C: The Bad Parts", y postfix-'++'/'--' son un buen ejemplo. Mi sugerencia es olvidar que existen y ** solo usar prefix-'++'/'--' ** _ (por ejemplo' min (- a, --b); 'y' for (int i = 0; i

1

He oído hablar de personas que usan el preprocesador C en código Ada. Ada has no preprocessor, por lo que tienes que hacer algo como eso si quieres preprocesar tu código.

Sin embargo, fue una decisión de diseño consciente para no darle una, así que haciendo esto es muy poco Ada. No recomendaría que nadie haga esto.

1

Hace un tiempo hice un trabajo en un proyecto que utiliza para la generación de imake makefile. Según recuerdo, básicamente era la sintaxis del preprocesador c para generar los archivos make.

Cuestiones relacionadas