Porque desea utilizar algún tipo de pseudo código interno o tablas/estructuras de datos. Por ejemplo, si tiene alguna línea de código:
a = b + c;
que se quiere tomar eso y romperla en un
load b
load c
add b + c
store a
como ejemplo, muchas soluciones. El lenguaje interno es probablemente mejor que ir directamente a la asamblea para un objetivo en particular por algunas razones. Se espera que el lenguaje interno sea algo que se pueda optimizar si tiene un optimizador, y es lo suficientemente genérico como para usarlo en múltiples objetivos si desea enfocarse en diferentes procesadores.
No sé lo suficiente al respecto, pero creo que también tiene los analizadores sintácticos bison/flex comunes, lo reducen a algún tipo de conjunto de instrucciones/códigos intermedios y luego escribe un backend para eso.
También se beneficia de que puede tener, por ejemplo, un front end C y C++ y otro idioma, sin afectar el back-end.
También se beneficia al dividir el compilador en bloques de módulos lógicos, puede desarrollar y probar la interfaz de forma independiente desde la parte posterior. llvm, por ejemplo, permite la exportación e importación del idioma intermedio, podrías hacerlo si realmente quisieras escribir código usando el lenguaje intermedio y tener el beneficio de objetivos múltiples en el back-end.
¿Puede decirme por favor cómo son los compiladores de M + N? Creo que tenemos M frontales para convertir a ICG y N generadores de código para convertir a código de máquina de destino. ¿Estás considerando cada interfaz como un compilador? – Zephyr
@Zephyr, sin una combinación FE/BE necesitaríamos tantas permutaciones que es innecesario/difícil de manejar. –
@Zephyr Sí, una combinación de front end/back end es un compilador. Sin duda, esto es obvio? – EJP