En informática , un compilador-compilador o generador de compiladores es una herramienta de programación que crea un analizador , intérprete o compilador a partir de alguna forma de descripción formal de un lenguaje de programación y una máquina.
El tipo más común de compilador-generador se llama analizador sintáctico . [1] Se encarga únicamente del análisis sintáctico .
Una descripción formal de un lenguaje suele ser una gramática que se utiliza como entrada para un generador de analizadores sintácticos. Suele parecerse a la forma Backus–Naur (BNF), la forma Backus–Naur extendida (EBNF) o tiene su propia sintaxis. Los archivos de gramática describen la sintaxis del lenguaje de programación de destino de un compilador generado y las acciones que se deben realizar en relación con sus construcciones específicas.
El código fuente de un analizador del lenguaje de programación se devuelve como salida del generador de analizadores. Este código fuente se puede compilar en un analizador, que puede ser independiente o integrado. El analizador compilado acepta el código fuente del lenguaje de programación de destino como entrada y realiza una acción o genera un árbol de sintaxis abstracta (AST).
Los generadores de analizadores no manejan la semántica del AST ni la generación de código de máquina para la máquina de destino. [2]
Un metacompilador es una herramienta de desarrollo de software que se utiliza principalmente en la construcción de compiladores , traductores e intérpretes para otros lenguajes de programación. [3] La entrada de un metacompilador es un programa informático escrito en un metalenguaje de programación especializado diseñado principalmente con el propósito de construir compiladores. [3] [4] El lenguaje del compilador producido se denomina lenguaje objeto. La entrada mínima que produce un compilador es un metaprograma que especifica la gramática del lenguaje objeto y las transformaciones semánticas en un programa objeto . [4] [5]
Un generador de analizador típico asocia el código ejecutable con cada una de las reglas de la gramática que se deben ejecutar cuando el analizador aplica dichas reglas. A estos fragmentos de código a veces se los denomina rutinas de acción semántica, ya que definen la semántica de la estructura sintáctica que analiza el analizador. Según el tipo de analizador que se deba generar, estas rutinas pueden construir un árbol de análisis (o árbol de sintaxis abstracta ) o generar código ejecutable directamente.
Una de las primeras (1964), y sorprendentemente potentes, versiones de compiladores-compiladores es META II , que aceptaba una gramática analítica con facilidades de salida que producían código de máquina de pila, y era capaz de compilar su propio código fuente y otros lenguajes.
Entre los primeros programas de las versiones originales de Unix que se crearon en Bell Labs se encontraba el sistema de dos partes lex y yacc , que normalmente se utilizaba para generar código en lenguaje de programación C , pero que tenía un sistema de salida flexible que podía utilizarse para todo, desde lenguajes de programación hasta conversión de archivos de texto. Sus versiones modernas de GNU son flex y bison .
Algunos compiladores experimentales toman como entrada una descripción formal de la semántica del lenguaje de programación, generalmente utilizando semántica denotacional . Este enfoque a menudo se denomina "compilación basada en semántica" y fue iniciado por el Sistema de Implementación Semántica (SIS) de Peter Mosses en 1978. [6] Sin embargo, tanto el compilador generado como el código que producía eran ineficientes en tiempo y espacio. Actualmente no se construyen compiladores de producción de esta manera, pero la investigación continúa.
El proyecto Production Quality Compiler-Compiler ( PQCC ) de la Universidad Carnegie Mellon no formaliza la semántica, pero sí tiene un marco semiformal para la descripción de máquinas.
Los compiladores existen en muchos tipos, incluidos los generadores de máquinas de reescritura de abajo hacia arriba (ver JBurg) utilizados para ordenar árboles de sintaxis de acuerdo con una gramática de reescritura para la generación de código, y los generadores de analizadores de gramática de atributos (por ejemplo, ANTLR se puede utilizar para verificación de tipos simultánea, propagación constante y más durante la etapa de análisis).
Los metacompiladores reducen la tarea de escribir compiladores al automatizar los aspectos que son los mismos independientemente del lenguaje objeto. Esto hace posible el diseño de lenguajes específicos de dominio que sean apropiados para la especificación de un problema particular. Un metacompilador reduce el costo de producir traductores para dichos lenguajes objeto específicos de dominio hasta un punto en el que se vuelve económicamente factible incluir en la solución de un problema un diseño de lenguaje específico de dominio . [4]
Como el metalenguaje de un metacompilador normalmente será un potente lenguaje de procesamiento de cadenas y símbolos, a menudo tienen aplicaciones sólidas para aplicaciones de propósito general, incluida la generación de una amplia gama de otras herramientas de análisis e ingeniería de software. [4] [7]
Además de ser útil para el desarrollo de lenguajes de dominio específico , un metacompilador es un excelente ejemplo de un lenguaje de dominio específico, diseñado para el dominio de la escritura de compiladores.
Un metacompilador es un metaprograma escrito generalmente en su propio metalenguaje o en un lenguaje de programación de computadoras existente. El proceso de compilación de un metacompilador, escrito en su propio metalenguaje, es equivalente al compilador autoalojado . La mayoría de los compiladores escritos hoy en día son compiladores autoalojados. El autoalojado es una herramienta poderosa, de muchos metacompiladores, que permite la extensión fácil de su propio metalenguaje de metaprogramación. La característica que separa a un metacompilador de otros compiladores es que toma como entrada un lenguaje de metaprogramación especializado que describe todos los aspectos del funcionamiento del compilador. Un metaprograma producido por un metacompilador es un programa tan completo como un programa escrito en C++ , BASIC o cualquier otro lenguaje de programación general . El metalenguaje de metaprogramación es un atributo poderoso que permite un desarrollo más fácil de lenguajes de programación de computadoras y otras herramientas informáticas. Los procesadores de línea de comandos, la transformación y el análisis de cadenas de texto se codifican fácilmente utilizando metalenguajes de metaprogramación de metacompiladores.
Un paquete de desarrollo con todas las funciones incluye un enlazador y una biblioteca de soporte en tiempo de ejecución . Por lo general, se necesita un lenguaje de programación de sistemas orientado a máquinas , como C o C++, para escribir la biblioteca de soporte. Una biblioteca que consta de funciones de soporte necesarias para el proceso de compilación generalmente completa el paquete de metacompilador completo.
En informática, el prefijo meta se usa comúnmente para significar sobre (su propia categoría) . Por ejemplo, los metadatos son datos que describen otros datos. Un lenguaje que se usa para describir otros lenguajes es un metalenguaje . Meta también puede significar en un nivel superior de abstracción . Un metalenguaje opera en un nivel superior de abstracción para describir las propiedades de un lenguaje. La forma Backus–Naur (BNF) es un metalenguaje formal utilizado originalmente para definir ALGOL 60. BNF es un metalenguaje débil , ya que describe solo la sintaxis y no dice nada sobre la semántica o el significado. La metaprogramación es la escritura de programas de computadora con la capacidad de tratar los programas como sus datos. Un metacompilador toma como entrada un metaprograma escrito en un metalenguaje especializado (una abstracción de nivel superior) diseñado específicamente para el propósito de la metaprogramación. [4] [5] La salida es un programa de objeto ejecutable.
Se puede establecer una analogía: así como un compilador de C++ toma como entrada un programa en lenguaje de programación C++ , un metacompilador toma como entrada un programa en un metalenguaje de metaprogramación .
Muchos defensores del lenguaje Forth denominan metacompilación al proceso de creación de una nueva implementación de Forth y lo consideran un metacompilador. La definición de metacompilador de Forth es:
Este uso del término metacompilador por parte de Forth es objeto de controversia en la informática convencional. Véase Forth (lenguaje de programación) e Historia de la construcción de compiladores . El proceso real de compilación de Forth es una combinación de Forth, que es un lenguaje de programación extensible autoalojado , y, a veces, compilación cruzada , una terminología establecida desde hace mucho tiempo en informática. Los metacompiladores son un sistema general de escritura de compiladores. Además, el concepto de metacompilador de Forth es indistinguible del lenguaje autoalojado y extensible. El proceso real actúa en un nivel inferior y define un subconjunto mínimo de palabras de Forth , que se pueden usar para definir palabras de Forth adicionales. A partir del conjunto base, se puede definir una implementación completa de Forth. Esto suena como un proceso de arranque. El problema es que casi todos los compiladores de lenguajes de propósito general también se ajustan a la descripción del metacompilador de Forth.
Simplemente reemplace X con cualquier lenguaje común, C, C++, Pascal , COBOL , Fortran , Ada , Modula-2 , etc. Y X sería un metacompilador de acuerdo con el uso de metacompilador de Forth. Un metacompilador opera en un nivel de abstracción por encima del compilador que compila. Solo opera en el mismo nivel (compilador autoalojado) cuando se compila a sí mismo. Hay que ver el problema con esta definición de metacompilador. Se puede aplicar a casi cualquier lenguaje.
Sin embargo, si analizamos el concepto de programación en Forth, añadir nuevas palabras al diccionario y extender el lenguaje de esta manera es metaprogramación. Es esta metaprogramación en Forth lo que lo convierte en un metacompilador.
Programar en Forth es agregar nuevas palabras al lenguaje. Cambiar el lenguaje de esta manera es metaprogramación . Forth es un metacompilador, porque Forth es un lenguaje diseñado específicamente para la metaprogramación. Programar en Forth es extender Forth, agregar palabras al vocabulario Forth crea un nuevo dialecto Forth . Forth es un metacompilador especializado para dialectos del lenguaje Forth.
El diseño del compilador-compilador original fue iniciado por Tony Brooker y Derrick Morris en 1959, con pruebas iniciales que comenzaron en marzo de 1962. [8] El compilador Brooker Morris Compiler (BMCC) se utilizó para crear compiladores para la nueva computadora Atlas en la Universidad de Manchester , para varios lenguajes: Mercury Autocode , Extended Mercury Autocode, Atlas Autocode , ALGOL 60 y ASA Fortran . Aproximadamente al mismo tiempo, ET (Ned) Irons estaba realizando un trabajo relacionado en Princeton y Alick Glennie en el Atomic Weapons Research Establishment en Aldermaston, cuyo artículo "Syntax Machine" (desclasificado en 1977) inspiró la serie META de sistemas de escritura de traductores que se mencionan a continuación.
La historia de los metacompiladores está estrechamente ligada a la historia del grupo de trabajo 1 de SIG/PLAN sobre compiladores controlados por sintaxis. El grupo se inició principalmente gracias al esfuerzo de Howard Metcalfe en el área de Los Ángeles. [9] En el otoño de 1962, Howard Metcalfe diseñó dos intérpretes para la escritura de compiladores. Uno utilizaba una técnica de análisis de abajo a arriba basada en un método descrito por Ledley y Wilson. [10] El otro utilizaba un enfoque de arriba a abajo basado en el trabajo de Glennie para generar oraciones aleatorias en inglés a partir de una gramática libre de contexto. [11]
Al mismo tiempo, Val Schorre describió dos "metamáquinas", una generativa y otra analítica. La máquina generativa se implementó y produjo expresiones algebraicas aleatorias. Meta I, el primer metacompilador, fue implementado por Schorre en un IBM 1401 en UCLA en enero de 1963. Sus intérpretes y metamáquinas originales fueron escritos directamente en un lenguaje pseudo-máquina. META II , sin embargo, fue escrito en un metalenguaje de nivel superior capaz de describir su propia compilación en el lenguaje pseudo-máquina. [12] [13] [14]
Lee Schmidt de Bolt, Beranek y Newman escribió un metacompilador en marzo de 1963 que utilizaba una pantalla CRT en el PDP-1 de tiempo compartido. [15] Este compilador produjo código de máquina real en lugar de código interpretativo y fue parcialmente arrancado de Meta I. [ cita requerida ]
Schorre creó Meta II a partir de Meta I durante la primavera de 1963. El artículo sobre el sistema de metacompilador perfeccionado presentado en la conferencia ACM de Filadelfia de 1964 es el primer artículo sobre un metacompilador disponible como referencia general. La sintaxis y la técnica de implementación del sistema de Schorre sentaron las bases para la mayoría de los sistemas que le siguieron. El sistema se implementó en un pequeño 1401 y se utilizó para implementar un pequeño lenguaje similar a ALGOL . [ cita requerida ]
Inmediatamente le siguieron muchos sistemas similares. [ cita requerida ]
Roger Rutman de AC Delco desarrolló e implementó LOGIK, un lenguaje para simulación de diseño lógico, en el IBM 7090 en enero de 1964. [16] Este compilador utilizó un algoritmo que produjo un código eficiente para expresiones booleanas. [ cita requerida ]
Otro artículo en las actas de la ACM de 1964 describe Meta III, desarrollado por Schneider y Johnson en la UCLA para el IBM 7090. [17] Meta III representa un intento de producir código de máquina eficiente para una amplia clase de lenguajes. Meta III se implementó completamente en lenguaje ensamblador. Se escribieron dos compiladores en Meta III: CODOL, un compilador de demostración para la escritura de compiladores, y PUREGOL, un dialecto de ALGOL 60 (fue un descaro llamarlo ALGOL).
A finales de 1964, Lee Schmidt desarrolló el metacompilador EQGEN, desde el PDP-l hasta el Beckman 420. EQGEN era un lenguaje generador de ecuaciones lógicas.
En 1964, System Development Corporation inició un importante esfuerzo en el desarrollo de metacompiladores. Este esfuerzo incluye los potentes metacompiladores Bookl y Book2 escritos en Lisp, que tienen una amplia capacidad de búsqueda en árboles y de copia de seguridad. Una consecuencia de uno de los sistemas Q-32 de SDC es Meta 5. [18] El sistema Meta 5 incorpora una copia de seguridad del flujo de entrada y otras funciones suficientes para analizar cualquier lenguaje sensible al contexto. Este sistema se lanzó con éxito a un amplio número de usuarios y tenía muchas aplicaciones de manipulación de cadenas además de la compilación. Tiene muchas pilas de inserción elaboradas, funciones de configuración y prueba de atributos y mecanismos de salida. El hecho de que Meta 5 traduzca con éxito los programas JOVIAL a programas PL/I demuestra su potencia y flexibilidad.
Robert McClure de Texas Instruments inventó un compilador-compilador llamado TMG (presentado en 1965). TMG se utilizó para crear los primeros compiladores para lenguajes de programación como B , PL/I y ALTRAN . Junto con el metacompilador de Val Schorre, fue una inspiración temprana para el último capítulo de El arte de la programación informática de Donald Knuth . [19]
El sistema LOT se desarrolló en 1966 en el Stanford Research Institute y se basó en el modelo Meta II. [20] Tenía nuevas construcciones especiales que le permitían generar un compilador que, a su vez, podía compilar un subconjunto de PL/I. Este sistema tenía amplias funciones de recopilación de estadísticas y se utilizó para estudiar las características del análisis descendente.
SIMPLE es un sistema traductor especializado diseñado para ayudar en la escritura de preprocesadores para PL/I. SIMPLE, escrito en PL/I, se compone de tres componentes: un ejecutivo, un analizador de sintaxis y un constructor semántico. [21]
El compilador TREE-META fue desarrollado en el Stanford Research Institute en Menlo Park, California, en abril de 1968. La historia de los primeros metacompiladores está bien documentada en el manual TREE META. TREE META fue paralelo a algunos de los desarrollos de SDC. A diferencia de los metacompiladores anteriores, separó el procesamiento semántico del procesamiento sintáctico. Las reglas de sintaxis contenían operaciones de construcción de árboles que combinaban elementos del lenguaje reconocidos con nodos del árbol. La representación de la estructura de árbol de la entrada se procesaba entonces mediante una forma simple de reglas de desanálisis. Las reglas de desanálisis utilizaban el reconocimiento de nodos y la prueba de atributos que, cuando coincidían, daban como resultado la ejecución de la acción asociada. Además, también se podía probar un elemento del árbol similar en una regla de desanálisis. Las reglas de desanálisis también eran un lenguaje recursivo que podía llamar a reglas de desanálisis pasando elementos del árbol antes de que se realizara la acción de la regla de desanálisis.
El concepto de metamáquina propuesto originalmente por Glennie es tan simple que se han diseñado tres versiones de hardware y una de ellas se ha implementado. Esta última en la Universidad de Washington en St. Louis. Esta máquina se construyó a partir de componentes macromodulares y tiene como instrucciones los códigos descritos por Schorre.
CWIC (Compiler for Writing and Implementing Compilers) es el último metacompilador de Schorre conocido. Fue desarrollado en Systems Development Corporation por Erwin Book, Dewey Val Schorre y Steven J. Sherman. Con todo el poder de (lisp 2), un lenguaje de procesamiento de listas, los algoritmos de optimización podían operar en listas y árboles generados por sintaxis antes de la generación de código. CWIC también tenía una tabla de símbolos incorporada al lenguaje.
Con el resurgimiento de los lenguajes específicos de dominio y la necesidad de generadores de analizadores que sean fáciles de usar, fáciles de entender y fáciles de mantener, los metacompiladores se están convirtiendo en una herramienta valiosa para proyectos avanzados de ingeniería de software.
Otros ejemplos de generadores de analizadores sintácticos en la línea yacc son ANTLR , Coco/R , [22] CUP, [ cita requerida ] GNU Bison , Eli, [23] FSL, [ cita requerida ] SableCC , SID (Syntax Improving Device), [24] y JavaCC . Si bien son útiles, los generadores de analizadores sintácticos puros solo abordan la parte de análisis del problema de construir un compilador. Las herramientas con un alcance más amplio, como PQCC , Coco/R y DMS Software Reengineering Toolkit, brindan un soporte considerable para actividades posteriores al análisis sintáctico más difíciles, como el análisis semántico, la optimización y generación de código.
Los primeros metacompiladores de Schorre, META I y META II, fueron desarrollados por D. Val Schorre en la UCLA. Luego vinieron otros metacompiladores basados en Schorre, cada uno de los cuales agregó mejoras al análisis del lenguaje y/o la generación de código.
En programación, es habitual utilizar el nombre del lenguaje de programación para referirse tanto al compilador como al lenguaje de programación, siendo el contexto el que distingue el significado. Un programa C++ se compila utilizando un compilador C++. Esto también se aplica en los siguientes casos. Por ejemplo, META II es tanto el compilador como el lenguaje.
Los metalenguajes de la línea Schorre de metacompiladores son lenguajes de programación funcional que utilizan ecuaciones sintácticas de análisis gramatical de arriba hacia abajo que tienen construcciones de transformación de salida incorporadas.
Una ecuación de sintaxis:
<nombre> = <cuerpo>;
es una función de prueba compilada que devuelve éxito o fracaso . <name> es el nombre de la función. <body> es una forma de expresión lógica que consta de pruebas que pueden agruparse, tener alternativas y generar producciones. Una prueba es como un bool en otros lenguajes, siendo el éxito verdadero y el fracaso falso .
Definir un lenguaje de programación analíticamente de arriba hacia abajo es algo natural. Por ejemplo, un programa podría definirse como:
programa = $declaracion;
Definir un programa como una secuencia de cero o más declaraciones.
En los lenguajes Schorre META X hay una regla impulsora. La regla de programa anterior es un ejemplo de una regla impulsora. La regla de programa es una función de prueba que llama a una declaración, una regla de prueba , que devuelve éxito o fracaso . El operador de bucle $ llama repetidamente a la declaración hasta que se devuelve el fracaso . El operador $ siempre es exitoso, incluso cuando no hay declaraciones. El programa anterior siempre devolvería éxito. (En CWIC, un error largo puede omitir la declaración. Un error largo es parte del sistema de retroceso de CWIC)
Los conjuntos de caracteres de estos primeros compiladores eran limitados. El carácter / se utilizaba para el operador alternante (o). "A o B" se escribe como A / B. Los paréntesis ( ) se utilizan para agrupar.
A (B/C)
Describe una construcción de A seguida de B o C. Como expresión booleana sería
A y (B o C)
Una secuencia XY tiene un significado X e Y implícito. ( ) son operadores de agrupación y / o . El orden de evaluación siempre es de izquierda a derecha, ya que la secuencia de caracteres de entrada se especifica mediante el orden de las pruebas.
Se utilizan palabras de operador especial cuyo primer carácter es un "." para mayor claridad. .EMPTY se utiliza como última alternativa cuando no es necesario que haya una alternativa previa.
X (A/B/.VACÍO)
Indica que X puede ir seguido opcionalmente de A o B. Esta es una característica específica de estos metalenguajes, que son lenguajes de programación. Lo anterior evita el retroceso. Es posible que otros sistemas de construcción de compiladores hayan declarado las tres secuencias posibles y hayan dejado que el analizador las averigüe.
Las características de los metalenguajes de metaprogramación anteriores son comunes a todos los metacompiladores de Schorre y los derivados de ellos.
META I era un metacompilador compilado a mano que se utilizó para compilar META II. Se sabe poco más de META I, excepto que la compilación inicial de META II produjo un código casi idéntico al del compilador META I, codificado a mano.
Cada regla consta opcionalmente de pruebas, operadores y producciones de salida. Una regla intenta hacer coincidir alguna parte del flujo de caracteres de origen del programa de entrada y devuelve éxito o fracaso. En caso de éxito, la entrada avanza sobre los caracteres coincidentes. En caso de fracaso, la entrada no avanza.
Las producciones de salida produjeron una forma de código ensamblador directamente a partir de una regla de sintaxis.
TREE-META introdujo los operadores de construcción de árboles : <node_name> y [ <number> ] , que convierten las transformaciones de producción de salida en reglas sin analizar. Los operadores de construcción de árboles se utilizaron en las reglas gramaticales que transformaban directamente la entrada en un árbol de sintaxis abstracta . Las reglas sin analizar también son funciones de prueba que coinciden con los patrones de árboles. Las reglas sin analizar se invocan desde una regla gramatical cuando se debe transformar un árbol de sintaxis abstracta en código de salida. La construcción de un árbol de sintaxis abstracta y las reglas sin analizar permitieron realizar optimizaciones locales mediante el análisis del árbol sintáctico.
El traslado de las producciones de salida a las reglas de desanálisis permitió una clara separación del análisis gramatical y la producción de código, lo que facilitó la lectura y la comprensión de la programación.
Entre 1968 y 1970, Erwin Book, Dewey Val Schorre y Steven J. Sherman desarrollaron CWIC. [4] (Compilador para escribir e implementar compiladores) en el Centro de Historia de la Tecnología de la Información del Instituto Charles Babbage de la Corporación de Desarrollo de Sistemas (Caja 12, carpeta 21),
CWIC es un sistema de desarrollo de compiladores compuesto por tres lenguajes específicos de dominio y de propósito especial, cada uno de los cuales tiene como objetivo permitir la descripción de ciertos aspectos de la traducción de una manera sencilla. El lenguaje de sintaxis se utiliza para describir el reconocimiento del texto fuente y la construcción a partir de él de una estructura de árbol intermedia . El lenguaje generador se utiliza para describir la transformación del árbol en un lenguaje objeto apropiado.
El lenguaje de sintaxis sigue la línea anterior de metacompiladores de Dewey Val Schorre. Se parece más a TREE-META, ya que tiene operadores de construcción de árboles en el lenguaje de sintaxis. Las reglas de desanálisis de TREE-META se extienden para funcionar con el lenguaje generador basado en objetos basado en LISP 2 .
CWIC incluye tres idiomas:
El lenguaje de generadores tenía una semántica similar a la de Lisp . El árbol de análisis se consideraba una lista recursiva. La forma general de una función del lenguaje de generadores es:
nombre-de-función(primera-regla-de-analización) => primer-generador-de-código-de-producción (segunda regla de anulación de análisis) => segundo generador de código de producción (tercera regla de desanálisis) => tercer generador de código de producción ...
El código para procesar un árbol determinado incluía las características de un lenguaje de programación de propósito general, más un formato: <stuff>, que emitiría (stuff) en el archivo de salida. Se puede utilizar una llamada de generador en unparse_rule. Se pasa al generador el elemento del patrón unparse_rule en el que se encuentra y sus valores de retorno se enumeran en (). Por ejemplo:
expr_gen(ADD[expr_gen(x),expr_gen(y)]) => <AR+(x*16)+y;> liberaciónreg(y); devuelve x; (SUB[expr_gen(x),expr_gen(y)])=> <SR + (x*16)+y;> liberaciónreg(y); devuelve x; (MUL[expr_gen(x),expr_gen(y)])=> . . . (x)=> r1 = obtenerreg(); cargar(r1, x); devuelve r1;...
Es decir, si el árbol de análisis se parece a (ADD[<something1>,<something2>]), se llamaría a expr_gen(x) con <something1> y devolvería x. Una variable en la regla de desanálisis es una variable local que se puede usar en production_code_generator. Se llama a expr_gen(y) con <something2> y devuelve y. Aquí hay una llamada de generador en una regla de desanálisis a la que se le pasa el elemento en la posición que ocupa. Con suerte, en lo anterior, x e y serán registros en el retorno. La última transformación tiene como objetivo cargar un átomo en un registro y devolver el registro. La primera producción se usaría para generar la instrucción "AR" (Add Register) 360 con los valores apropiados en los registros generales. El ejemplo anterior es solo una parte de un generador. Cada expresión de generador evalúa un valor que luego puede procesarse más. La última transformación también podría haberse escrito como:
(x)=> devolver carga(getreg(), x);
En este caso, load devuelve su primer parámetro, el registro devuelto por getreg(). Las funciones load y getreg son otros generadores CWIC.
De los autores de CWIC:
"Un metacompilador facilita la tarea de construcción de compiladores al automatizar sus aspectos no creativos, aquellos aspectos que son los mismos independientemente del lenguaje que el compilador producido debe traducir. Esto hace posible el diseño de lenguajes que sean apropiados para la especificación de un problema particular. Reduce el costo de producción de procesadores para tales lenguajes hasta un punto en el que se vuelve económicamente factible comenzar la solución de un problema con el diseño del lenguaje". [4]
{{cite book}}
: CS1 maint: location missing publisher (link) CS1 maint: others (link)