Compilador-compilador - Compiler-compiler

En informática , un compilador-compilador o generador de compilador es una herramienta de programación que crea un analizador , un intérprete o un 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-compilador se llama más precisamente generador de analizador sintáctico y solo maneja el análisis sintáctico: su entrada es una gramática , generalmente escrita en forma Backus-Naur (BNF) o forma Backus-Naur extendida (EBNF) que define la sintaxis de un lenguaje de programación; y su salida es el código fuente de un analizador para el lenguaje de programación. Los generadores de analizadores no manejan la semántica del lenguaje de programación o la generación de código de máquina para la máquina de destino.

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. La entrada a un metacompilador es un programa de computadora escrito en un metalenguaje de programación especializado diseñado principalmente con el propósito de construir compiladores. El lenguaje del compilador producido se llama lenguaje de objetos . 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 .

Variantes

Un generador de analizador típico asocia código ejecutable con cada una de las reglas de la gramática que deben ejecutarse cuando el analizador aplica estas reglas. Estos fragmentos de código a veces se denominan rutinas de acción semántica, ya que definen la semántica de la estructura sintáctica que analiza el analizador sintáctico. Dependiendo del tipo de analizador que deba generarse, estas rutinas pueden construir un árbol de análisis sintáctico (o árbol de sintaxis abstracta ) o generar código ejecutable directamente.

Una de las primeras versiones (1964), sorprendentemente poderosas, de compiladores-compiladores es META II , que aceptó una gramática analítica con facilidades de salida que producen código de máquina de pila , y es capaz de compilar su propio código fuente y otros lenguajes.

Entre los primeros programas de las versiones originales de Unix que se estaban construyendo en Bell Labs estaba el sistema lex y yacc de dos partes , que normalmente se usaba para generar código en lenguaje de programación C , pero tenía un sistema de salida flexible que podía usarse para todo, desde lenguajes de programación. a la conversión de archivos de texto. Sus versiones modernas de GNU son flex y bison .

Algunos compiladores-compiladores experimentales toman como entrada una descripción formal de la semántica del lenguaje de programación, típicamente usando semántica denotacional . Este enfoque a menudo se denomina "compilación basada en semántica", y fue pionero en el Sistema de Implementación Semántica (SIS) de Peter Mosses en 1978. Sin embargo, tanto el compilador generado como el código que produjo fueron 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 tiene un marco semiformal para la descripción de la máquina.

Los compiladores-compiladores existen en muchos sabores, incluidos los generadores de máquina de reescritura de abajo hacia arriba (ver JBurg ) que se utilizan para agrupar árboles de sintaxis de acuerdo con una gramática de reescritura para la generación de código y generadores de analizadores de gramática de atributos (por ejemplo, ANTLR se puede usar para la verificación simultánea de tipos, constante propagación, y más durante la etapa de análisis).

Metacompiladores

Los metacompiladores reducen la tarea de escribir compiladores al automatizar los aspectos que son iguales independientemente del lenguaje del objeto . Esto hace posible el diseño de lenguajes específicos de dominio que son apropiados para la especificación de un problema particular. Un metacompilador reduce el costo de producir traductores para dichos lenguajes de objetos específicos de dominio hasta un punto en el que resulta económicamente factible incluir en la solución de un problema un diseño de lenguaje específico de dominio .

Como el metalenguaje de un metacompilador suele ser un poderoso 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.

Además de ser útil para el desarrollo de un lenguaje específico de un dominio, un metacompilador es un excelente ejemplo de un lenguaje específico de un dominio, diseñado para el dominio de la escritura del compilador.

Un metacompilador es un metaprograma generalmente escrito en su propio metalenguaje o en un lenguaje de programación de computadora existente. El proceso de un metacompilador, escrito en su propio metalenguaje, compilándose a sí mismo es equivalente al compilador autohospedado . Los compiladores más comunes que se escriben hoy en día son compiladores autohospedados. El autohospedaje es una herramienta poderosa, de muchos metacompiladores, que permite la fácil extensión de su propio metalenguaje de metaprogramación. La característica que separa a un metacompilador de otros compiladores de compiladores es que toma como entrada un lenguaje de metaprogramación especializado que describe todos los aspectos de la operación 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 la metaprogramación es un atributo poderoso que permite un desarrollo más fácil de lenguajes de programación 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 sistema orientado a la máquina , 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 completo del metacompilador.

El significado de metacompilador

En ciencias de la computación, el prefijo meta se usa comúnmente para referirse a (su propia categoría) . Por ejemplo, los metadatos son datos que describen otros datos. Un idioma que se usa para describir otros idiomas es un metalenguaje . Meta también puede significar un mayor nivel 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 originalmente utilizado 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 . La salida es un programa objeto ejecutable.

Se puede establecer una analogía: que como un compilador de C ++ toma como entrada un programa de lenguaje de programación C ++ , un metacompilador toma como entrada un programa de metalenguaje de programación meta .

Cuarto metacompilador

Muchos defensores del lenguaje Forth llaman al proceso de crear una nueva implementación de Forth una metacompilación y que constituye un metacompilador. La cuarta definición de metacompilador es:

"Un metacompilador es un compilador que procesa su propio código fuente, lo que resulta en una versión ejecutable de sí mismo".

Este cuarto uso del término metacompilador se disputa en la ciencia de la computación convencional. Consulte Forth (lenguaje de programación) e Historia de la construcción del compilador . El proceso de Forth real de la compilación en sí es una combinación de un Forth ser un autoalojamiento extensible programación de lenguaje y, a veces la compilación cruzada , la terminología de larga data en la informática. Los metacompiladores son un sistema de escritura de compiladores general. Además, el concepto de metacompilador Forth es indistinguible del lenguaje autohospedado y extensible. El proceso real actúa en un nivel inferior definiendo un subconjunto mínimo de cuartos de palabras , que se pueden usar para definir cuartos de palabras adicionales. Entonces se puede definir una implementación de Forth completa a partir del conjunto base. Esto suena como un proceso de arranque. El problema es que casi todos los compiladores de lenguaje de propósito general también se ajustan a la descripción del metacompilador Forth.

Cuando (compilador autohospedado) X procesa su propio código fuente, lo que da como resultado una versión ejecutable de sí mismo, X es un metacompilador.

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 Forth del metacompilador. Un metacompilador opera a un nivel de abstracción por encima del compilador que compila. Solo funciona al mismo nivel (compilador autohospedado) cuando se compila a sí mismo. Uno tiene que ver el problema con esta definición de metacompilador. Se puede aplicar a casi cualquier idioma.

Sin embargo, al examinar el concepto de programación en Forth, agregar nuevas palabras al diccionario, extender el lenguaje de esta manera es metaprogramación. Es esta metaprogramación en Forth la que lo convierte en un metacompilador.

Programar en Forth es agregar nuevas palabras al lenguaje. Cambiar el idioma de esta manera es metaprogramación . Forth es un metacompilador porque Forth es un lenguaje diseñado específicamente para la metaprogramación. La programación en Forth se está extendiendo Forth añadiendo palabras al vocabulario Forth crea un nuevo dialecto Forth . Forth es un metacompilador especializado para los dialectos del idioma Forth.

Historia

El primer compilador-compilador que usó ese nombre fue escrito por Tony Brooker en 1960 y se usó para crear compiladores para la computadora Atlas en la Universidad de Manchester , incluido el compilador Atlas Autocode .

La historia temprana de los metacompiladores está estrechamente relacionada con 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. En el otoño de 1962, Howard Metcalfe diseñó dos intérpretes de escritura de compiladores. Uno utilizó una técnica de análisis de abajo hacia arriba basada en un método descrito por Ledley y Wilson. El otro utilizó un enfoque de arriba a abajo basado en un trabajo de Glennie para generar oraciones en inglés aleatorias a partir de una gramática libre de contexto.

Al mismo tiempo, Val Schorre describió dos "metamáquinas". Uno generativo y uno analítico. Se implementó la máquina generativa y se produjeron 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 alto nivel capaz de describir su propia compilación en el lenguaje pseudo-máquina.

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. Este compilador produjo código de máquina real en lugar de código interpretativo y fue parcialmente arrancado de Meta I.

Schorre arrancó Meta II de Meta I durante la primavera de 1963. El artículo sobre el sistema de metacompilador refinado 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 sentó las bases para la mayoría de los sistemas que siguieron. El sistema se implementó en un pequeño 1401 y se utilizó para implementar un pequeño lenguaje similar a ALGOL .

Inmediatamente siguieron muchos sistemas similares.

Roger Rutman de AC Delco desarrolló e implementó LOGIK, un lenguaje para la simulación de diseño lógico, en el IBM 7090 en enero de 1964. Este compilador usó un algoritmo que produjo un código eficiente para expresiones booleanas.

Otro artículo en los procedimientos de ACM de 1964 describe Meta III , desarrollado por Schneider y Johnson en UCLA para IBM 7090. Meta III representa un intento de producir código de máquina eficiente, para una gran clase de lenguajes. Meta III se implementó completamente en lenguaje ensamblador. Se escribieron dos compiladores en Meta III, CODOL, un compilador de demostración de escritura de compilador, y PUREGOL, un dialecto de ALGOL 60. (Fue puramente descarado llamarlo ALGOL).

A fines de 1964, Lee Schmidt arrancó el metacompilador EQGEN, del PDP-1 al Beckman 420. EQGEN era un lenguaje generador de ecuaciones lógicas.

En 1964, System Development Corporation inició un gran esfuerzo en el desarrollo de metacompiladores. Este esfuerzo incluye poderosos metacompiladores, Bookl y Book2 escritos en Lisp que tienen una amplia capacidad de búsqueda de árboles y copias de seguridad. Una consecuencia de uno de los sistemas Q-32 en SDC es Meta 5. El sistema Meta 5 incorpora respaldo del flujo de entrada y suficientes otras facilidades para analizar cualquier lenguaje sensible al contexto. Este sistema se lanzó con éxito a un gran número de usuarios y tenía muchas aplicaciones de manipulación de cadenas además de la compilación. Tiene muchas pilas de pushdown elaboradas, funciones de configuración y prueba de atributos y mecanismos de salida. Que Meta 5 traduzca con éxito los programas JOVIAL a programas PL / I demuestra su poder y flexibilidad.

Robert McClure de Texas Instruments inventó un compilador-compilador llamado TMG (presentado en 1965). TMG se utilizó para crear los primeros compiladores de lenguajes de programación como B , PL / I y ALTRAN . Junto con metacompiler de Val Schorre, era una inspiración temprana para el último capítulo de Donald Knuth 's The Art of Computer Programming .

El sistema LOT se desarrolló durante 1966 en el Stanford Research Institute y se modeló muy de cerca a Meta II. Tenía nuevas construcciones de propósito especial que le permitían generar un compilador que, a su vez, podía compilar un subconjunto de PL / I. Este sistema tenía amplias instalaciones de recopilación de estadísticas y se utilizó para estudiar las características del análisis de arriba hacia abajo.

SIMPLE es un sistema traductor especializado diseñado para ayudar a la escritura de preprocesadores para PL / I, SIMPLE, escrito en PL / I, está compuesto por tres componentes: un ejecutivo, un analizador de sintaxis y un constructor semántico.

El compilador TREE-META se desarrolló en el Instituto de Investigación de Stanford en Menlo Park, California. 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 la COSUDE. A diferencia de los metacompiladores anteriores, separaba el procesamiento semántico del procesamiento de sintaxis. Las reglas de sintaxis contenían operaciones de construcción de árboles que combinaban elementos de lenguaje reconocidos con nodos de árbol. La representación de la estructura de árbol de la entrada se procesó luego mediante una forma simple de reglas no analizadas. Las reglas no analizadas utilizaban el reconocimiento de nodos y las pruebas de atributos que, cuando se combinaban, daban como resultado la realización de la acción asociada. Además, el elemento de árbol similar también podría probarse en una regla no analizada. Las reglas unparse también eran un lenguaje recursivo que podía llamar a reglas unparse que pasaban elementos del árbol antes de que se realizara la acción de la regla unparse.

El concepto de metamáquina propuesto originalmente por Glennie es tan simple que se han diseñado tres versiones de hardware y una realmente implementada. Este último en la Universidad de Washington en St. Louis. Esta máquina fue construida a partir de componentes macro-modulares y tiene como instrucciones los códigos descritos por Schorre.

CWIC (compilador para escribir e implementar compiladores) es el último metacompilador conocido de Schorre. Fue desarrollado en Systems Development Corporation por Erwin Book, Dewey Val Schorre y Steven J. Sherman. Con todo el poder de (lisp 2), los algoritmos de optimización del lenguaje de procesamiento de listas 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 en el idioma.

Con el resurgimiento de lenguajes de dominios específicos y la necesidad de generadores de analizadores sintácticos 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 de ingeniería de software avanzados.

Otros ejemplos de generadores de analizadores sintácticos en la línea yacc son ANTLR , Coco / R , CUP, GNU Bison , Eli, FSL, SableCC , SID (Syntax Improving Device) y JavaCC . Si bien son útiles, los generadores de analizadores sintácticos puros solo abordan la parte del análisis sintáctico 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 más difíciles, como el análisis semántico, la optimización y la generación de código.

Metalenguajes Schorre

Los primeros metacompiladores de Schorre, META I y META II, fueron desarrollados por D. Val Schorre en UCLA. Le siguieron otros metacompiladores basados ​​en Schorre. Cada uno agrega mejoras al análisis del lenguaje y / o generación de código.

En programación, es común usar el nombre del lenguaje de programación para referirse tanto al compilador como al lenguaje de programación, el contexto distingue el significado. Un programa de C ++ se compila utilizando un compilador de C ++. Eso también se aplica a lo siguiente. 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 de sintaxis de análisis de gramática de arriba hacia abajo que tienen construcciones de transformación de salida integradas.

Una ecuación de sintaxis:

<name> = <body>;

es una función de prueba compilada que devuelve éxito o fracaso . <nombre> es el nombre de la función. <cuerpo> es una forma de expresión lógica que consta de pruebas que pueden agruparse, tener alternativas y producciones de salida. Una prueba es como un bool en otros idiomas, el éxito es verdadero y el fracaso es falso .

Definir un lenguaje de programación analíticamente de arriba hacia abajo es natural. Por ejemplo, un programa podría definirse como:

 program = $declaration;

Definir un programa como una secuencia de cero o más declaraciones.

En los idiomas Schorre META X hay una regla de conducción. La regla del programa anterior es un ejemplo de regla de conducción. La regla del programa es una función de prueba que llama a la declaración, una regla de prueba , que devuelve éxito o fracaso . El operador $ loop llama repetidamente a la declaración hasta que se devuelve el error . El operador $ siempre tiene éxito, incluso cuando hay declaración cero. El programa anterior siempre devolvería el éxito. (En CWIC, una falla prolongada puede omitir la declaración. Una falla prolongada es parte del sistema de retroceso de CWIC)

Los conjuntos de caracteres de estos primeros compiladores eran limitados. El carácter / se usó para el operador alterno (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 and (B or C)

Una secuencia XY tiene un significado implícito de X e Y. () están agrupando y / el operador or . El orden de evaluación es siempre de izquierda a derecha, ya que el orden de las pruebas especifica una secuencia de caracteres de entrada.

Palabras de operador especiales cuyo primer carácter es un "." se utilizan para mayor claridad. .EMPTY se utiliza como última alternativa cuando no es necesario que exista una alternativa anterior.

X (A / B / .EMPTY)

Indica que X es seguido opcionalmente por A o B. Esta es una característica específica de que estos metalenguajes son lenguajes de programación. Lo anterior evita el retroceso. Otros sistemas constructores de compiladores pueden haber declarado las tres secuencias posibles y dejar 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 a los que se derivan de ellos.

META I

META I era un metacompilador compilado a mano utilizado para compilar META II. Poco más se sabe 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.

META II

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 que devuelve éxito o fracaso. En caso de éxito, la entrada avanza sobre los caracteres coincidentes. En caso de falla, la entrada no avanza.

Las producciones de salida produjeron una forma de código ensamblador directamente a partir de una regla de sintaxis.

ÁRBOL-META

TREE-META introdujo operadores de construcción de árboles : < nombre_nodo > y [ < número > ] moviendo las transformaciones de producción de salida a reglas no analizadas. Los operadores de construcción de árboles se utilizaron en las reglas gramaticales transformando directamente la entrada en un árbol de sintaxis abstracta . Las reglas no analizadas también son funciones de prueba que coinciden con los patrones de árbol. Las reglas no analizadas se llaman desde una regla gramatical cuando un árbol de sintaxis abstracta se va a transformar en código de salida. La construcción de un árbol de sintaxis abstracto y reglas de análisis permitió realizar optimizaciones locales mediante el análisis del árbol de análisis.

El traslado de las producciones de salida a las reglas no analizadas hizo una clara separación del análisis gramatical y la producción de código. Esto hizo que la programación fuera más fácil de leer y comprender.

CWIC

En 1968-1970, Erwin Book, Dewey Val Schorre y Steven J. Sherman desarrollaron CWIC. (Compilador para escribir e implementar compiladores) en System Development Corporation Centro del Instituto Charles Babbage para la Historia de la Tecnología de la Información (Cuadro 12, carpeta 21) ,

CWIC es un sistema de desarrollo de compiladores compuesto por tres lenguajes de dominio específico y de propósito especial, cada uno de los cuales tiene la intención de permitir la descripción de ciertos aspectos de la traducción de una manera directa. El lenguaje de sintaxis se utiliza para describir el reconocimiento del texto fuente y la construcción a partir de él en una estructura de árbol intermedia . El lenguaje generador se utiliza para describir la transformación del árbol en el lenguaje de objetos apropiado.

El lenguaje de sintaxis sigue la línea anterior de metacompiladores de Dewey Val Schorre. Se parece más a TREE-META que tiene operadores de construcción de árboles en el lenguaje de sintaxis. Las reglas unparse de TREE-META se extienden para trabajar con el lenguaje generador basado en objetos basado en LISP 2 .

CWIC incluye tres idiomas:

  • Sintaxis : transforma la entrada del programa fuente en estructuras de lista mediante la fórmula de transformación gramatical. Una estructura de expresión analizada se pasa a un generador colocando una llamada de generador en una regla. Un árbol está representado por una lista cuyo primer elemento es un objeto de nodo. El lenguaje tiene operadores, < y > , específicamente para hacer listas. El operador dos puntos : se utiliza para crear objetos de nodo. : ADD crea un nodo ADD. ¡La exclamación ! El operador combina varias entradas analizadas con un nodo para hacer un árbol . Los árboles creados por las reglas de sintaxis se pasan a las funciones del generador, devolviendo el éxito o el fracaso. El lenguaje de sintaxis está muy cerca de TREE-META. Ambos usan dos puntos para crear un nodo. ¡La exclamación de construcción del árbol de CWIC ! <Número> funciona igual que el [<número>] de TREE-META.
  • Generador : una serie con nombre de reglas de transformación, cada una de las cuales consta de una regla no analizada de coincidencia de patrones. y una producción de salida escrita en un lenguaje similar a LISP 2. la traducción fue al código de máquina binario de IBM 360. Otras facilidades del lenguaje generador de salida generalizada.
  • MOL-360 : un lenguaje de implementación de nivel medio independientepara la familia de computadoras IBM System / 360 desarrollado en 1968 y utilizado para escribir la biblioteca de soporte subyacente.

Lenguaje de generadores

Generators Language tenía una semántica similar a Lisp . El árbol de análisis se pensó como una lista recursiva. La forma general de una función de lenguaje generador es:

  function-name(first-unparse_rule) => first-production_code_generator
           (second-unparse_rule) => second-production_code_generator
           (third-unparse_rule) => third-production_code_generator
               ...

El código para procesar un árbol dado incluía las características de un lenguaje de programación de propósito general, más una forma: <stuff>, que emitiría (cosas) en el archivo de salida. Se puede usar una llamada de generador en unparse_rule. Al generador se le pasa el elemento del patrón unparse_rule en el que se coloca y sus valores de retorno se enumeran en (). Por ejemplo:

  expr_gen(ADD[expr_gen(x),expr_gen(y)]) =>
                                <AR + (x*16)+y;>
                                releasereg(y);
                                return x;
               (SUB[expr_gen(x),expr_gen(y)])=>
                                <SR + (x*16)+y;>
                                releasereg(y);
                                return x;
               (MUL[expr_gen(x),expr_gen(y)])=>
                              .
                              .
                              .
               (x)=>     r1 = getreg();
                            load(r1, x);
                            return r1;
...

Es decir, si el árbol de análisis se parece a (ADD [<something1>, <something2>]), expr_gen (x) se llamaría con <something1> y devolvería x. Una variable en la regla unparse es una variable local que se puede usar en el generador de código de producción. expr_gen (y) se llama con <algo2> y devuelve y. Aquí hay una llamada al generador en una regla no analizada que se pasa al elemento en la posición que ocupa. Es de esperar que en el xey anterior se registren al regresar. La última transformación está destinada a cargar un atómico en un registro y devolver el registro. La primera producción se usaría para generar la instrucción 360 "AR" (Agregar registro) con los valores apropiados en los registros generales. El ejemplo anterior es solo una parte de un generador. Cada expresión generadora se evalúa a un valor que luego se procesa más. La última transformación también podría haberse escrito como:

               (x)=>     return load(getreg(), x);

En este caso, load devuelve su primer parámetro, el registro devuelto por getreg (). las funciones load y getreg son otros generadores de CWIC.

El CWIC abordó los idiomas específicos del dominio antes de que existiera el término idioma específico del dominio

De los autores de CWIC:

"Un metacompilador asiste en la tarea de construcción del compilador automatizando sus aspectos no creativos, aquellos aspectos que son los mismos independientemente del lenguaje que el compilador producido va a traducir. Esto hace posible el diseño de lenguajes que son apropiados a la especificación de un problema particular. Reduce el costo de producir procesadores para tales lenguajes hasta un punto en el que resulta económicamente factible comenzar la solución de un problema con el diseño del lenguaje ".

Ejemplos de

Ver también

Referencias y notas

Otras lecturas

enlaces externos