¿Cómo puedo implementar algo similar a la Objective-C @encode() directiva de compilador ANSI C?

StackOverflow https://stackoverflow.com/questions/2255637

Pregunta

El @codificar la directiva devuelve un const char *, que es un código de tipo de descriptor de los diversos elementos del tipo de dato que se pasó.Ejemplo de la siguiente manera:

struct test
{ int ti ;
  char tc ;
} ;

printf( "%s", @encode(struct test) ) ;
// returns "{test=ic}"

Pude ver el uso de sizeof() para determinar los tipos primitivos - y si se trataba de un objeto, que podría utilizar los métodos de la clase para hacer introspección.

Sin embargo, ¿Cómo se determina cada elemento de un cuerpo opaco struct?

¿Fue útil?

Solución

@Lothars respuesta podría ser "cínico", pero es bastante cerca de la marca, por desgracia.Con el fin de implementar algo similar @encode(), se necesita un analizador a gran escala con el fin de extraer la información de tipo.Bueno, al menos para otra cosa que "trivial" @encode() instrucciones (es decir, @encode(char *)).Los compiladores modernos, por lo general tienen dos o tres componentes principales:

  • El front-end.
  • El intermedio final (para algunos compiladores).
  • La parte final.

La parte delantera debe analizar todo el código fuente y, básicamente, convierte el código fuente de texto a un interno, "la máquina utilizable" forma.

La parte final se traduce en la interna, "la máquina utilizable" la forma en que el código ejecutable.

Los compiladores que tienen un "intermedio final" normalmente lo hacen porque de alguna necesidad:dan soporte a múltiples "front-end", posiblemente hecho de idiomas completamente distintos.Otra razón es para simplificar la optimización:todos la optimización pasa a trabajar en la misma representación intermedia.El gcc suite del compilador es un ejemplo de un "tres etapas" del compilador. llvm podría ser considerado un "intermedio y al final de" la etapa del compilador:El "bajo nivel de máquina virtual" es la representación intermedia, y todos la optimización se lleva a cabo en este formulario. llvm también capaz de mantener en esta representación intermedia de la derecha hasta el último segundo, lo que permite un enlace de "optimización del tiempo".El clang compilador es realmente un "front end" que (efectivamente) salidas llvm representación intermedia.

Por lo tanto, si desea agregar @encode() la funcionalidad para una 'existente' compilador, probablemente tenga que hacerlo como una "fuente de información" 'compilador / preprocesador'.Este era el Objetivo original-C y C++ compiladores fueron escritos - que analiza la fuente de entrada de texto y convertida a "plain C", que luego fue alimentado en el compilador de C estándar.Hay un par de maneras de hacer esto:

Rollo de su propia

  • Uso yacc y lex para armar una ANSI-C analizador.Usted necesitará una gramática- ANSI C de la gramática (Yacc) es un buen comienzo.En realidad, para ser claros, cuando digo yacc, Lo digo de verdad bisonte y flex.Y también, indirectamente, los otros varios yacc y lex como C-herramientas basadas en: limón, dparser, etc...
  • Uso perl con Yapp o EYapp, que son pseudo-yacc clones en perl.Probablemente sea mejor para la rápida generación de prototipos de una idea en comparación con C-basado yacc y lex- es perl después de todo:Las expresiones regulares, las matrices asociativas, no la gestión de memoria, etc.
  • Construir su analizador con Antlr.No tengo ninguna experiencia con esta herramienta de la cadena, pero es otra "compilador de compilador" herramienta que (parece) a ser más orientado a los desarrolladores de java.No parece estar disponible gratuitamente C y Objective-C gramáticas disponible.

Otra herramienta Hack

Nota: No tengo experiencia personal en el uso de cualquiera de estas herramientas para hacer algo como la adición de @encode(), pero sospecho que sería una gran ayuda.

  • CIL - Ninguna experiencia personal con esta herramienta, sino que está diseñado para el análisis de código fuente de C y, a continuación, "haciendo cosas" con ella.Por lo que puedo deducir de la documentación, esta herramienta debe permitir extraer el tipo de información que usted necesita.
  • Escasa - Vale la pena mirar, pero no estoy seguro.
  • clang - No lo he utilizado para este propósito, pero supuestamente uno de los objetivos era hacer "fácilmente hackeable" para este tipo de cosas.En particular (y de nuevo, sin experiencia personal) en realizar el "trabajo pesado" de todos los análisis, lo que le permite concentrarse en el "muy interesante", que en este caso sería la extracción de contexto de sintaxis y sensible al tipo de información y, a continuación, convertir esto en una llanura de C de la cadena.
  • gcc - Los Plugins son una gcc 4.5 (que es el actual alfa/beta de la versión del compilador) y "podría" le permiten conectar fácilmente en el compilador para extraer el tipo de información que usted necesita.Ni idea de si la arquitectura de plugin permite para este tipo de cosas.

Otros

  • Coccinelle - Marcado esta recientemente a "mirar adelante".Esto "podría" ser capaz de hacer lo que quiere, y que "podría" ser capaz de hacerlo con mucho esfuerzo.
  • MetaC - Marcado esta uno recientemente.Ni idea de lo útil que esto sería.
  • mygcc - "Podría" hacer lo que quiera.Es una idea interesante, pero no es directamente aplicable a lo que usted desea.Desde la página web:"Mygcc permite a los programadores agregar sus propias verificaciones que tener en cuenta la sintaxis, control de flujo, flujo de datos y de la información."

Los enlaces.

Edición #1, los enlaces de bonificación.

@Lothar hace un buen punto en su comentario.Yo tenía la intención de incluir lcc, pero parece que se perdió en el camino.

  • lcc - La lcc El compilador de C de.Este es un compilador de C que es particularmente pequeño, al menos en términos de código fuente tamaño.También tiene un libro, que recomiendo encarecidamente.
  • tcc - La tcc El compilador de C de.No es tan pedagógico como lcc, pero sin duda todavía vale la pena mirar.
  • poc - La poc Objective-C del compilador.Esta es una "fuente de información" Objective-C del compilador.Se analiza el Objetivo de código fuente de C y emite un código fuente en C, que luego pasa a gcc (bueno, normalmente gcc).Tiene un número de Objective-C, extensiones / funciones que no están disponibles en gcc.Definitivamente vale la pena mirar.

Otros consejos

Se podría implementar esta implementando el compilador ANSI C y luego añadir algunos pragmas y funciones específicas de aplicación a la misma.

Sí sé que esto es la respuesta cínica y acepto las downvotes.

Una forma de hacerlo sería escribir un preprocesador, que lee el código fuente de las definiciones de tipos y también reemplaza @encode ... con la correspondiente cadena literal.

Otro enfoque, si el programa se compila con -g, sería escribir una función que lee la definición del tipo de información de depuración del programa en tiempo de ejecución, o utilizar gdb u otro programa para leerlo para usted y luego volver a darle formato como se desee. El comando gdb ptype se puede utilizar para imprimir la definición de un tipo particular (o, si esto no es suficiente también hay maint print type, lo que es seguro para imprimir mucha más información de lo que posiblemente podría desear).

Si está utilizando un compilador que apoya plugins (por ejemplo, GCC 4.5), puede también es posible escribir un plugin para este compilador. Tu lector a continuación, podría aprovechar la información de tipo que el compilador ya ha analizado. Obviamente, este enfoque sería compilador específico muy.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top