Upload
lucita287
View
2.166
Download
0
Embed Size (px)
DESCRIPTION
Historia, funcionamiento, Estructura de Cup, Código de Usuario, declaración de terminales, Declaración de precedencia, definición de gramáticas, Métodos de errores, recuperación de errores .
Citation preview
CUP – Constructor of Useful Parsers
Desarrollado por:Lucita287 (Aura Cifuentes)Universidad De San Carlos de Guatemala.
Un poco de Historia [CUP]
• Fue desarrollado en la Universidad de Pricenton por Scott Hudson, 1995.
• CUP Constructor of Useful Parsers es un analizador sintáctico LARL escrito en java.
• Basa su diseño en el analizador YACC, creado en lenguaje C, pero esta completamente implementado en java.
Funcionamiento de CUP:• Esquema de funcionamiento Cup:– El analizador sintáctico arranca.– Solicita un token.– El scanner lo devuelve de acuerdo a la
codificación Sym.
Scanner Basado en
especificaciones Jlex/JFlex
Parser Basado en
especificaciones CUP
SymConstantes utilizadas
Next_token()
TOKEN
CODIGO FUENTE
Ejemplo – Cup sym.java• /** CUP generated class containing symbol constants. */• public class sym {• /* terminals */• public static final int RPARENT = 10;• public static final int DIGITO = 6;• public static final int POTENCIA = 7;• public static final int SUMA = 2;• public static final int MULTIPLICACION = 5;• public static final int EOF = 0;• public static final int SIGNO = 11;• public static final int RESULTADO = 8;• public static final int error = 1;• public static final int DIVISION = 4;• public static final int RESTA = 3;• public static final int LPARENT = 9;• }
Clase analizador sintáctico parser.java
parser.java contiene 2 clases:– public class parserextends java_cup.runtime.lr_parser{ ...}Clase pública del analizador:• Subclase de java_cup.runtime.lr_parser que implementa la tabla de acciones de un analizador LALR. – class CUP$parser$actions: Clase no pública incluida en el fichero
que encapsula las acciones de usuario contenidas en la gramática.• Contiene el método que selecciona y ejecuta las diferentes acciones
definidas en cada regla sintáctica: – public final java_cup.runtime.Symbol• CUP$parser$do_action
Estructura de un Fichero CUP:1. Especificaciones de importación y empaquetamiento. La
primera parte del fichero se utiliza para incluir información que define cómo se generará el analizador y el código de importación de la librería CUP.
2. Código de usuario. Se puede ubicar una serie de declaraciones opcionales que permiten incluir código en el analizador generado.
3. Lista de símbolos. La segunda parte de la especificación declara los terminales y no terminales utilizados en la gramática y, opcionalmente, especifica el tipo (clase-objeto) de cada uno de ellos. Si se omite el tipo, al terminal o no-terminal correspondiente no se le pueden asignar valores.
4. Declaraciones de precedencia. La tercera parte del fichero define la precedencia y asociatividad de los terminales.
5. Gramática.
Código de Usuario:
Opcional. Permite definir variables y procedimientos de asistencia al parser dentro de una clase de ayuda
Action code {: :}
parser code {: :}
Opcional. Permite definir funciones y variables dentro de la clase Parser para adaptar el comportamiento del analizador sintáctico.
Código de Usuario:
Opcional. Permite definir lógica de inicialización que se llamará antes de comenzar el análisis.
Init With {: :}
scan with {: :}
Opcional. Permite indicar qué sentencia debe utilizarse para solicitar un nuevo token.
Declaración de símbolos gramaticales
• Terminales. Se especifican los símbolos terminales de la gramática indicando, opcionalmente, los tipos.
• No terminales. Se especifican los símbolos no terminales de la gramática indicando, opcionalmente, sus tipos.
terminal [clase] nombre1, nombre2, ...;non terminal [clase] nombre1, nombre2, ...;
• Un ejemplo de esta definición son las siguientes sentencias.
Sección:Declaración de Símbolos
terminal SEMI, PLUS, MINUS, TIMES, DIVIDE; terminal UMINUS, LPAREN, RPAREN; terminal Integer NUMBER;
non terminal expr_list, expr_part;
non terminal Integer expr, term, factor;
Sección: Declaración de PrecedenciaLa asociatividad de los terminales se utiliza
para resolver conflictos de desplazamiento-reducción, pero solo para terminales de igual precedencia.
Lista de precedencia-asociatividad, pude ser:• right: asociatividad por la derecha.• left: asociatividad por la izquierda.• nonassoc: sin asociatividad.
12/04/2023 11
• Indica la prioridad de evaluación de operadores.
• Los operadores en una misma fila tiene igual prioridad.
• La prioridad es creciente en orden de declaración.
Sección: Declaración de Precedencia
precedence left RESTA, SUMA;precedence left MULTIPLICACION, DIVISION;precedence left MENOSUNARIO;precedence right POTENCIA;
Definición de la gramática:Operación Expresión
RegularCUP
Concatenación AB C::= AB;
Opcion A | B C ::= A | B;
ε | A C ::= | A;
Clausura de Kleene
A * C ::= | AC ;
A + C ::= C A | A;
Sección: Definición de la Gramática• La gramática se define en notación BNF,
siguiendo la siguiente sintaxis;• Se inicia con una declaración opcional
de la forma: start with no-terminal.• La secuencia_de_terminales y
noterminales es una lista de terminales o no terminales separados por espacios en blanco.
no-terminal ::= ListaTerminalesOnoterminales [ {:acción:} ]
Sección: Definición de la Gramática
Las acciones se colocan dentro de {: … :}y pueden ser:
Para obtener el valor de un símbolo, se puede realizar por medio de la función intvalue(), indicando una asignación a una variable.
12/04/2023 15
{: System.out.println("Sintaxis correcta"); :}
expr ::= expr:e1 PLUS expr:e2 {: RESULT = new Integer(e1.intValue() + e2.intValue()); :}
Métodos de Errores:
• public void syntax_error(Symbol cur_token)• Este método es invocado por el analizador al detectar un error
sintáctico, y previamente al intento de recuperarlo. En la implementación por defecto proporcionada por CUP únicamente se llama al método report_error.
• public void syntax_error(Symbol cur_token) {• report_error("Syntax error", cur_token);• }
Métodos de Errores:• public void unrecovered_syntax_error
(Symbol cur_token)• Invocado por el analizador si es imposible
recuperarse de un error• sintáctico. La implementación proporcionada por
CUP es:public void unrecovered_syntax_error (Symbol
cur_token) throws java.lang.Exception {report_fatal_error("Couldn't repair and continue
parse", cur_token);}
Recuperación de Errores:• Cuando el analizador sintáctico generado por CUP
recibe una secuencia de testigos que no corresponde a la gramática que ha de analizar, se genera un error y el analizador finaliza su ejecución.
• CUP proporciona un mecanismo de recuperación ante los errores, consistente en definir un no terminal especial (error) que encaja toda entrada errónea.
– El símbolo de error sólo está activo en caso de detectarse un error. En este caso, el analizador intenta reemplazar una secuencia de testigos para este no terminal y continuar el análisis.
Recuperación Errores – Símbolo error
ecuacion ::= expresion{: System.out.println("Sintaxis correcta"); :}RESULTADO| error {: System.out.println("Sintaxis
incorrecta");:}RESULTADO ;Si se detecta un error en el análisis de una
expresión, la recuperación se intentará descartando testigos de la entrada hasta encontrar el testigo RESULTADO (‘=’).