Beruflich Dokumente
Kultur Dokumente
Antlr (ANother Tool for Language Recognition) genera analizadores sintcticos LL(k) con
predicados sintcticos y semnticos.
Estructura de un analizador sintctico
Los analizadores sintcticos o parsers reconocen estructuras sintcticas desde secuencias de
tokens. La estructura general de un analizador sintctico antlr es:
header { ... } //Cdigo que se situar en la cabecera del parser (opcional)
// Suele usarse para decidir la ubicacin del analizador tras ser
// compilado (pe. header {package X; })
class Anasint extends Parser;
options { ... } // opciones destinadas a particularizar el parser (opcional)
tokens {...} //definicin de tokens (opcional)
{ //clases internas necesarias para la implementacin del parser } (opcional)
// definicin de reglas lxicas
Ejemplo:
class Anasint extends Parser;
instrucciones: (expresion ";")* ;
expresion : exp_base (("+"|"-") exp_base)* ;
exp_base : NUMERO
| "(" expresion ")"
;
Uso del analizador sintctico
El procesamiento de un parser como el anterior produce una clase Anasint con mtodos que
representan las reglas gramaticales. El analisis sintctico se apoya sobre un anlisis lxico, es
decir, las categoras sintcticas son generadas desde un flujo de tokens producidos desde un
analizador lxico.
Ejemplo de uso del parser suponiendo un analizador lxico denominado Analex:
import java.io.*;
import antlr.collections.AST;
import antlr.ANTLRException;
public class expre {
public static void main(String args[]){
try{
FileInputStream fis=
new FileInputStream("entrada.txt");
Analex analex = new Analex(fis);
Anasint anasint = new Anasint(analex);
anasint.instrucciones();
}catch(ANTLRException ae){
System.err.println(ae.getMessage());
}
catch (FileNotFoundException fnfe){
System.err.println("No se encontr el fichero");
}
}
}
Construccin de Reconocedores por Separado
Antlr ofrece la posibilidad de desarrollar lexers y parsers por separado.
Por defecto, todo parser exporta su vocabulario (conjunto de tokens usados en la definicin del
parser). Antlr implementa esta idea mediante dos ficheros, uno de texto y otro Java
implementando una interfaz.
Supongamos un fichero Anasint.g conteniendo el siguiente texto:
class Anasint extends Parser;
instrucciones : (expresion ";")* ;
expresion : exp_mult (("+"|"-") exp_mult)* ;
exp_mult : exp_base (("*"|"/") exp_base)* ;
exp_base : NUMERO
| "(" expresion ")"
;
Al compilarlo se producen tres ficheros:
AnasintTokenTypes.java contiene:
public interface AnasintTokenTypes {
int EOF = 1;
int NULL_TREE_LOOKAHEAD = 3;
// ";" = 4
// "+" = 5
// "-" = 6
// "*" = 7
// "/" = 8
int NUMERO = 9;
// "(" = 10
// ")" = 11
}
AnasintTokenTypes.txt contiene:
";"=4
"+"=5
"-"=6
"*"=7
"/"=8
NUMERO=9
"("=10
")"=11
Estos ficheros son necesarios para conectar el parser con el lexer. La forma de hacerlo es incluir
en el lexer una importacin del vocabulario correspondiente:
class Analex extends Lexer;
options{
importVocab = Anasint; // Importacin del conjunto de tokens
}
BLANCO : (' '|'\t'|"\r\n") {$setType(Token.SKIP);};
NUMERO : ('0'..'9')+('.'('0'..'9')+)?;
OPERADOR : '+'|'-'|'*'|'/';
PARENTESIS : '('|')';
SEPARADOR : ';';
Predicados sintcticos: Antlr permite construir parsers LL(k) (con k arbitrario) haciendo uso de
predicados sintcticos. Se trata de construcciones de la forma ( lookahead ) => regla gramatical
;
Opciones
Muchos aspectos en el comportamiento de Antlr puede programarse mediante opciones. Las
opciones principales en relacin con el anlisis sintctico son:
k: nmero de tokens lookahead.
Ejemplo:
class Anasint extends Parser;
options { k=2; }
...
importVocab: permite importar un vocabulario de tokens.
Ejemplo:
class Anasint extends Parser;
options{
importVocab = Analex; // Importacin del conjunto de tokens
}
buildAST: indica si el analizador es genera o no representaciones intermedias en forma de
boles de sintaxis abstracta (ASA)
Ejemplo:
class Anasint extends Parser;
options{
buildAST = true; //construccin automtica de AST
}
instrucciones : (expresion ";")*;
expresion : exp_mult (("+"|"-") exp_mult)*;
exp_mult : exp_base (("*"|"/") exp_base)*;
exp_base : NUMERO
| "(" expresion ")"
;
instrucciones reconocidas
}catch(ANTLRException ae){
System.err.println(ae.getMessage());
}
catch (FileNotFoundException fnfe){
System.err.println("No se encontr el fichero");
}
}
}
Flujo de entrada (entrada.txt):
1+2;
(3-1)+7+5;
33;
instrucciones reconocidas
NUMERO : (DIGITO)+('.'(DIGITO)+)?;
IDENT : LETRA (LETRA | DIGITO)* ;
PARENTESIS : '('|')';
SEPARADOR : ';';
ASIG : ":=";
NUMERO : (DIGITO)+('.'(DIGITO)+)?;
IDENT : LETRA (LETRA | DIGITO)* ;
OPERADOR : '+'|'-'|'*'|'/';
PARENTESIS : '('|')';
SEPARADOR : ';';
ASIG : ":=";
NUMERO : (DIGITO)+('.'(DIGITO)+)?;
IDENT : LETRA (LETRA | DIGITO)* ;