Aclaraciones resueltas de analisis sintactico
Antlr (ANother Tool for Language Recognition) genera analizadores sintácticos LL(k) con predicados sintácticos y semánticos. Estructura de un analizador sintáctico Los analizadores sintácticos o parsers reconocen estructuras sintácticas desde secuencias de tokens. La estructura general de un analizador sintáctico antlr es: header { ... } //Código que se situará enla cabecera del parser (opcional) // Suele usarse para decidir la ubicación del analizador tras ser // compilado (pe. header {package X; }) class Anasint extends Parser; options { ... } // opciones destinadas a particularizar el parser (opcional) tokens {...} //definición de tokens (opcional) { //clases internas necesarias para la implementación del parser } (opcional) // definición de reglasléxicas Ejemplo: class Anasint extends Parser; instrucciones: (expresion ";")* ; expresion : exp_base (("+"|"-") exp_base)* ; exp_base : NUMERO | "(" expresion ")" ; Uso del analizador sintáctico El procesamiento de un parser como el anterior produce una clase Anasint con métodos que representan las reglas gramaticales. El analisis sintáctico se apoya sobre un análisis léxico, es decir, las categoríassintácticas son generadas desde un flujo de tokens producidos desde un analizador léxico. Ejemplo de uso del parser suponiendo un analizador léxico 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 = newAnalex(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"); } } } Construcción de Reconocedores por Separado Antlr ofrece la posibilidad de desarrollar lexers y parsers por separado. Por defecto, todo parser exporta su vocabulario (conjuntode tokens usados en la definición 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: • • Anasint.java (el parser java), AnasintTokenTypes.java (la interfaz con la definición del conjunto de tokens utilizados en el parser) y
•
AnasintTokenTypes.txt (el fichero de texto con la definición del conjunto de tokens utilizados en el parser).
AnasintTokenTypes.java contiene: public interface AnasintTokenTypes { int EOF = 1; intNULL_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 importación del vocabulario correspondiente: class Analex extends Lexer; options{importVocab = Anasint; // Importación del conjunto de tokens } BLANCO : (' '|'\t'|"\r\n") {$setType(Token.SKIP);}; NUMERO : ('0'..'9')+('.'('0'..'9')+)?; OPERADOR : '+'|'-'|'*'|'/'; PARENTESIS : '('|')'; SEPARADOR : ';'; Predicados sintácticos: Antlr permite construir parsers LL(k) (con k arbitrario) haciendo uso de predicados sintácticos. Se trata de construcciones de la forma ( lookahead ) =>regla gramatical
El siguiente ejemplo es un típico de gramática no-LL(1): instruccion : asignacion | llamada ... ; asignacion : IDENT ":=" expr ";" ; llamada : IDENT "(" expr ")" ";" ; La forma de resolverlo con predicados sintácticos es: instruccion : (IDENT ":=") => asignacion | (IDENT "(") => llamada ... ; Gramáticas Atribuidas en Antlr El reconocimiento descendente permite asociar a cada...
Regístrate para leer el documento completo.