Escolar Documentos
Profissional Documentos
Cultura Documentos
1. Herramientas Tradicionales
Se incluyen en este apartado las herramientas clásicas: Lex/Yacc, Pclex, Pcyacc, Bison, Flex ,...
Ventajas:
• Los analizadores generados son muy eficientes, incluso más que los que pudiéramos hacer
de manera manual.
• Los analizadores ascendentes pueden reconocer la mayor parte de los lenguajes libres de
contexto.
Inconvenientes:
• Yacc necesita usar herramientas externas para que le provean los tokens necesarios.
• Las acciones semánticas asociadas a las producciones de los no terminales de las gramáticas
son difíciles de depurar. Puesto que este código pasa directamente al código del analizador
generado por Yacc, es necesario comprender el funcionamiento de un analizador
ascendentes, para saber donde falla algo.
• Yacc no genera ASTs (Abstract Syntax Trees) con lo cual no es fácil conseguir compiladores
que realicen sus tareas en varias pasadas. Los analizadores generados por Yacc, en general,
realizan sus tareas leyendo el fichero fuente una sola vez.
• Se incrementa la dificultad del trabajo de depuración puesto que los errores que se cometen
en el fichero de especificación son sólo visibles en el analizador generado.
ANTLR
Ventajas:
• Debido a la naturaleza de los analizadores descendentes, el código generado por Antlr es más
fácil de depurar y comprender que el de Yacc.
• Los analizadores generados por Antlr son menos eficientes que los generados por Yacc.
• Los ficheros de especificaciones de Antlr (como los de YACC) pueden volverse realmente
complejos ya que contienen muchas más cosas que la especificación gramatical propiamente
dicha.
• El proceso de depurado consta de los siguientes pasos: escribir el código de las acciones,
compilar el fichero de especificaciones, compilar y ejecutar el programa generado, localizar
los errores en el programa y corregir los errores en el fichero de especificaciones.
Ejemplo:
// Fichero calc.g
expr
: mexpr (PLUS^ mexpr)* SEMI! //! Operador para indicar que el
; // token será ignorado para el AST
mexpr
: atom (STAR^ atom)*
;
atom: INT
;
WS : (' '
| '\t'
| '\n'
| '\r')
{ _ttype = Token.SKIP; }
;
LPAREN:'('
;
RPAREN:')'
;
STAR: '*'
;
PLUS: '+'
;
SEMI: ';'
;
protected
DIGIT :'0'..'9'
;
INT : (DIGIT)+
;
class CalcTreeWalker extends TreeParser;
// Fichero calc.java
#include <iostream>
#include <antlr/AST.hpp>
#include "CalcLexer.hpp"
#include "CalcParser.hpp"
#include "CalcTreeWalker.hpp"
int main()
{
using namespace std;
try {
CalcLexer lexer(cin);
CalcParser parser(lexer);
// Analiza la expresión de la entrada
parser.expr();
RefAST t = parser.getAST();
// Imprime el AST usando la notación LISP
cout << t->toStringTree() << endl;
CalcTreeWalker walker;
// Recorre el árbol creado por el analizador
float r = walker.expr(t);
cout << "value is " << r << endl;
} catch(exception& e) {
cerr << "exception: " << e.what() << endl;
}
}
Las especificaciones de Antlr incluyen la descripción de la gramática (al lado las producciones
aparecen las acciones en lenguaje Java) y la especificación del analizador léxico.
Las especificaciones del analizador léxico y del sintáctico serán creados en forma de dos clases, la
clase CalcLexer y la clase CalcParser.
No se necesita especificar la prioridad de los operadores puesto que los analizadores generados son
descendentes.
Se debe incluir al menos otro fichero con el método main para que se encargue de inicializar una
instancia del analizador léxico y del analizador sintáctico.
ANTLR genera:
• Una clase que contiene al lexer. Su función es obtener los tokens que va proporcionando al
analizador sintáctico.
• Una clase que contiene al parser. Como es descendente, comienza su análisis desde un
símbolo inicial y va derivando hasta encontrar los tokens que le proporciona el analizador
léxico. La clase generada contiene un método para cada una de las reglas de la gramática y es
subclase de LlkParser, que es la clase padre de todos los analizadores sintácticos que genera
Antlr.
• Una clase que contiene el AST. Los ASTs permiten construir un árbol de derivación genérico
que podrá ser aplicado a un programa concreto expresado en un lenguaje de programación
determinado. Sobre este AST se podrá aplicar uno o varios tree-walkers o clases que se
encarguen de recorrer el árbol.
Tratamiento de errores:
El mecanismo de tratamiento y recuperación de errores de Antlr se basa en el sistema de
tratamiento de excepciones presente en Java (y en otros lenguajes de programación como C++).
Incluye una jerarquía de excepciones con las siguientes clases:
• RecognitionException. Un error genérico que se produce cada vez que hay un problema
asimilando la entrada con las estructuras gramaticales.
• SemanticException. Excepción para cuando hay problemas con los predicados semánticos.
JAVACC
Inicialmente apareció con el nombre Jack y es una herramienta para construir compiladores
similar a ANTLR, es un analizador descendente. No existen muchas diferencias entre los dos
productos pero Javacc es un producto comercial de acceso libre (sin ficheros fuentes) mientras
que ANTLR es de dominio público (incluido los fuentes).
Ventajas:
Ejemplo:
En primer lugar, se especifica el código que ha de proveer el usuario para inicializar y terminar el
análisis.
La sección SKIP, contiene las expresiones regulares que se corresponden con las partes de la
entrada que se pueden ignorar en el proceso de análisis, como por ejemplo, comentarios.
La sección TOKEN, recoge las expresiones regulares asociadas a los tokens de la gramática. A
partir de esta información se generará el analizador léxico.
Aunque en el ejemplo se ve como todos los tokens han sido definidos en la sección correspondiente,
lo cierto es que se puede realizar definiciones de este tipo dentro del ámbito de una regla, aunque en
ese caso dicha definición solo tendrá validez dentro de esa regla.
• TokenMgrError. Esta clase se encarga de que los mensajes de error presenten suficiente
información al usuario.
• Token. La clase que encapsula los elementos terminales que se encarga de obtener el
analizador léxico para el sintáctico.
Tratamiento de errores:
• Está basado en el mecanismo de excepciones del lenguaje Java. No existe una jerarquía de
excepciones determinada sino que cuando se encuentra un error durante el proceso de
análisis se lanza una excepción de tipo ParserException.
• Una excepción podrá ser tratada en el lugar donde se produjo o en cualquier otra producción
que la pueda anteceder en el proceso de derivación.
3. Otras Herramientas
BYACC/JAVA
Es una extensión del YACC estándar para generar código Java en vez de código C/C++. El
fichero de especificaciones es el mismo que para YACC pero el código de las acciones, y la
secciones de código y declaraciones del lenguajes estarán escritas en Java.
java parser
COCO/JAVA
CUP
Una herramienta educativa que se puede utilizar para visualizar las técnicas de compilación.
Proporciona un entorno integrado con editores especiales para las definiciones del scaner y
parser, herramientas para ver información derivada como el conjunto de iniciales -first /
siguientes -follow y para el depurado del scaner y parser.
COCKTAIL
ELI
Originalmente PCCTS 1.33 fue escrito en C++ para generar compiladores escritos en C++.
Más tarde fue portado a Java y llamado ANTLR 2.xx. PCCTS consta de tres herramientas:
5. Direcciones
ANTLR: http://www.antlr.org/
JavaCC: http://www.metamata.com/javacc/
Construcción de compiladores en JAVA: http://www.first.gmd.de/cogent/catalog/java.html
Kits para la construcción de compiladores: http://www.first.gmd.de/cogent/catalog/kits.html
Generadores de analizadores léxicos: http://www.first.gmd.de/cogent/catalog/lexparse.html