next up previous contents
Next: El formalismo SDF Up: 8.2 Los formalismos de Previous: 8.2 Los formalismos de

El formalismo METAL

METAL es un formalismo que permite definir separadamente la sintaxis abstracta y concreta de un lenguaje. El uso de operadores de construcción de árboles permite controlar libremente la relación entre la sintaxis abstracta y la concreta.

Este formalismo utiliza Lex y Yacc para generar los analizadores léxico y sintáctico, respectivamente, por lo que las gramáticas de contexto libre definidas deberán ser de tipo LALR(1).

La sintaxis abstracta

La definición de la sintaxis abstracta delimita el conjunto de árboles abstractos que pueden ser construidos a partir del análisis sintáctico de los tokens. En la definición de la sintaxis abstracta se utilizan nodos, llamados operadores, y tipos de nodos, llamados phyla. Los operadores representan a los símbolos terminales y no terminales del lenguaje. Un operador viene definido por el número de hijos en el árbol y el tipo de tales hijos, esto es, el phylum al que pertenecen.

A continuación se muestra una pequeña porción de la sintaxis abstracta del Pascal:

abstract syntax
   ident   -> imlemented as IDENTIFIER ;
   intcst  -> implemented as INTEGER ;
   alfacst -> implemented as STRING ;
   charsct -> implemeted as CHAR ;
   .
   .
   .
   uminus  -> EXP ;
   uplus   -> EXP ;
   plus    -> EXP EXP ;
   minus   -> EXP EXP ;
   mult    -> EXP EXP ;
   div     -> EXP EXP ;
   mod     -> EXP EXP ;
   lident  -> IDENT + ... ;
   .
   .
   .
   EXP    ::= ident intcst alfacst charcst nil hexcst realcst setof not
	      uplus uminus unref hexa eql lss gtr  neq leq geq in intdiv
	      mod div mult plus minus or and index dot call ;
   IDENT  ::= ident ;
   LIDENT ::= lident ;
   .
   .
   .

Los nombres de los operadores se escriben en minúsculas, mientras que para los phyla se utilizan nombres en mayúsculas.

Los operadores del primer bloque son atómicos. La frase implemented as type, donde type indica un tipo LE-LISP, significa que cuando uno de tales operadores es reconocido por el analizador léxico es convertido inmediatamente en el tipo LE-LISP type.

Los operadores del segundo bloque uminus y uplus son unarios y su único descendiente en el árbol tiene por tipo al phylum EXP. El resto de los operadores mostrados en ese bloque son binarios, con ambos hijos de tipo EXP, excepto lident, que tiene uno o más descendientes de tipo IDENTgif.

En el tercer bloque se indica que el phylum EXP es el tipo de los operadores ident, intcst, alfacst, charcst, uminos, uplus, plus, minus, etc. También se indica que el phylum IDENT es el tipo del operador ident, que ya estaba incluido en el phylum EXP. Un operador puede pertenecer a más de un phylum, lo cual significa que puede aparecer en diferentes contextos.

La sintaxis concreta

Para definir la sintaxis concreta se utilizan reglas compuestas de dos partes:

A continuación se muestra un pequeño fragmento de la sintaxis concreta utilizada para definir el lenguaje Pascal:

rules
   <ID> ::= %ID ;
      ident-atom(%ID)
   <ID> ::= "pascal" ;
      ident-atom('pascal')
   <ID> ::= "forward" ;
      ident-atom('forward')
   <ID> ::= "external" ;
      ident-atom('external')
   <ID-LIST> ::= <ID> ;
      lident-list((<ID>))
   <ID-LIST> ::= <ID-LIST> "," <ID> ;
      lident-post(<ID-LIST>, <ID>)

Los no terminales se encierran entre los símbolos < y >. El carácter ; se utiliza para separar la regla de producción de la función de construcción de árboles.

Las funciones list, pre y post se utilizan respectivamente para crear una lista, para añadir un elemento al principio de una lista y para añadir un elemento al final de una lista. La función list requiere dos conjuntos de paréntesis para construir la lista.

Para construir nodos atómicos se utiliza la función atom. Por ejemplo, en la primera regla, %ID representa el token devuelto por el analizador léxico, mientras que ident representa el operador de la sintaxis abstracta cuyo valor atómico es el token almacenado en %ID.

El fichero de recursos

A la hora de definir un lenguaje, se recomienda que todos los ficheros referentes al mismo residan en una jerarquía de directorios que tenga como raiz $HOME/centaur/tables/lang, donde lang es el nombre del lenguaje que se va a implementar. En este directorio se deberá crear un subdirectorio metal que contendrá toda la información relativa a este formalismo. En el fichero de recursos del lenguaje lang, que en este caso será $HOME/centaur/tables/syntax/pascal.rdb, se indicará que Pascal es un formalismo del usuario, así como la localización de las tablas del lenguaje:

Centaur.pascal.Root: user
Centaur.pascal.Location: centaur/tables/pascal/syntax/metal
Centaur.pascal.Mode: std

El fichero Buildfile

Este fichero, localizado en centaur/tables/pascal/syntax/metal, contiene las directivas para la construcción del analizador sintáctico, para lo cual se hará uso de Yacc y Lex. El contenido de este fichero será el siguiente:

LANGUAGE=pascal
all: allmetal
#include /usr/local/centaur/tables/metal/Buildmetal

Al ejecutar el comando ctmake se construirá el parser. El compilador METAL creará el fichero pascal.tokens.x, que indica el tipo de tokens que tendrá que reconocer el analizador léxico. Se debe editar a mano este fichero para incluir las expresiones regulares de los tokens.

El editor CENTAUR para METAL

Se pueden editar programas METAL utilizando el editor de CENTAUR, accesible mediante el botón Editor de la ventana principal. Al introducir un nombre de fichero con extensión .metal en la ventana de diálogo, el editor resultante será un ctview adaptado especialmente para la edición de programas METAL. En la figura 8.6 se muestra un editor de este tipo utilizado para editar el fichero pascal.metal.

  figure5772
Figure 8.6: La especificación pascal.metal en el editor.


next up previous contents
Next: El formalismo SDF Up: 8.2 Los formalismos de Previous: 8.2 Los formalismos de

Miguel A. Alonso Pardo
Thu Nov 20 16:47:01 CET 1997