c preprocessor - que - Uso del preprocesador C para otros idiomas distintos de C
ifdef en c (12)
La entrada de Wikipedia para el preprocesador C dice:
El lenguaje de las directivas de preprocesador es independiente de la gramática de C , por lo que el preprocesador de C también se puede utilizar de forma independiente para procesar otros tipos de archivos.
¿Cómo se puede hacer esto? ¿Algún ejemplo o técnica?
EDITAR: Sí, estoy más interesado en el procesamiento de macros. Aunque probablemente no sea aconsejable o no pueda mantenerse, sería útil saber qué es posible.
Al usar el compilador de Microsoft, creo que (lo busqué, no lo he probado) que es la opción del compilador / P.
Es de suponer que otros compiladores tienen opciones similares (o, para algunos compiladores, el preprocesador podría ser un ejecutable diferente, que normalmente es ejecutado implícitamente por el compilador pero que también puede ejecutar explícitamente por separado).
Básicamente, lo que dice es que los preprocesadores no tienen nada que ver con la sintaxis de C. Son básicamente analizadores simples que siguen un conjunto de reglas. Así que podrías usar preprocesadores de la misma manera que usarías 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 ejecutas el preprocesador y obtendrás.
3.141 no es un número irracional.
El preprocesador de C también puede ser invocado por el Compilador de Haskell de Glasgow (GHC) antes de compilar el código de Haskell, al pasar el indicador -cpp
.
Hace un tiempo trabajé en un proyecto que usaba imake
para la generación de makefile. Como recuerdo, fue básicamente la sintaxis del preprocesador c para generar los archivos make.
He oído hablar de personas que utilizan el preprocesador C en el código de Ada. Ada no tiene preprocesador , por lo que debe hacer algo como eso si desea preprocesar su código.
Sin embargo, fue una decisión concienzuda de diseño no darle una, por lo que hacer esto es muy poco-Ada. No sugeriría que nadie haga esto.
Muchos compiladores de C tienen una marca que les dice que solo preprocesen. Con gcc es la bandera -E. p.ej:
$ gcc -E -
#define FOO foo
bar FOO baz
saldrá:
# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "<stdin>"
bar foo baz
Con otros compiladores de C tendrás que consultar los manuales para ver cómo cambiar al modo de preprocesamiento solamente.
Podría implementar el preprocesador de C en el compilador para otro idioma.
Podría usarlo para preprocesar cualquier tipo de archivo de texto, pero hay cosas mucho mejores para ese propósito.
Por ejemplo, ensamblador. Si bien muchos ensambladores tienen su propia forma de #incluir encabezados y # definir macros, puede ser útil usar el preprocesador de C para esto. GNU make, por ejemplo, tiene reglas implícitas para convertir los archivos * .S en archivos * .s ejecutando el preprocesador (''cpp''), antes de enviar el archivo * .s al ensamblador GNU (''como'').
Por lo general, puede invocar el compilador de C con una opción para preprocesar solo (e ignorar cualquier instrucción #line). Toma esto como un simple ejemplo:
<?php
function foo()
{
#ifdef DEBUG
echo "Some debug info.";
#endif
echo "Foo!";
}
foo();
Definimos un archivo fuente PHP con sentencias de preproceso. Luego podemos preprocesarlo (gcc también puede hacer esto):
cl -nologo -EP foo.php > foo2.php
Dado que DEBUG
no está definido, el primer echo
se elimina. Además, las líneas que comienzan con # son comentarios en PHP, por lo que no tiene que preprocesarlos para una compilación de "depuración".
Edit: Desde que preguntaste por macros. Esto también funciona bien y podría usarse para generar código repetitivo, etc.
Puede llamar directamente a CPP:
cpp <file>
En lugar de llamarlo a través de gcc:
gcc -E filename
Sin embargo, tenga en cuenta que, como se menciona en el mismo artículo de Wikipedia, el lenguaje del preprocesador C no está realmente equipado para uso general:
Sin embargo, dado que el preprocesador de C no tiene características de algunos otros preprocesadores, como macros recursivas, expansión selectiva según la cita, evaluación de cadenas en condicionales y integridad de Turing, es muy limitado en comparación con un procesador de macros más general como m4 .
¿Ha considerado incursionar con un lenguaje de procesamiento de macros más flexible, como el m4 mencionado anteriormente?
Sí, se puede hacer analizando su propio idioma a través del preprocesador gcc (por ejemplo, ''gcc -E'').
Hemos hecho esto en mi trabajo con nuestro lenguaje específico. Tiene bastantes ventajas:
- Puedes usar las sentencias de inclusión de C (#include) que son muy poderosas
- Puedes usar tus construcciones #ifdef
- Puede definir Constantes (# definir MAGIC_NUMBER 42) o funciones de macro (# definir min (x, y) ((x (<(y)? (X): (y))
... y las otras cosas en el procesador c.
SIN EMBARGO, también hereda las construcciones de C inseguras y la causa es tener un preprocesador no integrado con su idioma principal. Piense en la macro mínima y haga algo como:
a = 2;
b = 3;
c = min(a--, b--);
Solo piense qué valor tendrán ayb después de la función min.
Lo mismo es cierto acerca de las constantes no tipificadas que introduce
Ver el libro Safer C para más detalles.
Suponiendo que está utilizando GCC, puede tomar cualquier archivo de texto simple, independientemente de su contenido, y ejecutar:
gcc -E filename
Cualquier directriz de preprocesador en el archivo será procesada por el preprocesador y GCC se cerrará.
El punto es que no importa cuál sea el contenido real del archivo de texto, ya que todo lo que le importa al preprocesador son sus propias directivas.