19
CUP – Constructor of Useful Parsers Desarrollado por: Lucita287 (Aura Cifuentes) Universidad De San Carlos de Guatemala.

Cup

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

Page 1: Cup

CUP – Constructor of Useful Parsers

Desarrollado por:Lucita287 (Aura Cifuentes)Universidad De San Carlos de Guatemala.

Page 2: Cup

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.

Page 3: Cup

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

Page 4: Cup

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;• }

Page 5: Cup

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

Page 6: Cup

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.

Page 7: Cup

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.

Page 8: Cup

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.

Page 9: Cup

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, ...;

Page 10: Cup

• 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;

Page 11: Cup

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

Page 12: Cup

• 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;

Page 13: Cup

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;

Page 14: Cup

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:} ]

Page 15: Cup

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()); :}

Page 16: Cup

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);• }

Page 17: Cup

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);}

Page 18: Cup

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.

Page 19: Cup

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 (‘=’).