Agenda. Introducción Analizador léxico Analysis El problema de analizar sintácticamente Analizador sintáctico descendeterecursivo

Documentos relacionados
Analizadores sintácticos LR(0) y SLR

Controla el flujo de tokens reconocidos por parte del analizador léxico. 4.2 Introduccion a las gramaticas libres de contexto y arboles de derivacion

Análisis sintáctico 1

Lenguajes y Compiladores Análisis Sintáctico Parte I. Teoría Lenguajes 1

Compiladores: Análisis Sintáctico. Pontificia Universidad Javeriana Cali Ingenieria de Sistemas y Computación Prof. Gloria Inés Alvarez V.

16 Análisis sintáctico I

Lenguajes y Compiladores Análisis Sintáctico Parte II

Compiladores: Análisis Sintáctico. Pontificia Universidad Javeriana Cali Ingenieria de Sistemas y Computación Prof. Gloria Inés Alvarez V.

Análisis sintáctico Analizadores descendentes

Compiladores e Intérpretes Análisis Léxico

ANÁLISIS SINTÁCTICO PREDICTIVO NO RECURSIVO

UNIVERSIDAD NACIONAL DE EDUCACIÓN A DISTANCIA Escuela Técnica Superior de Ingeniería Informática Procesadores de Lenguajes. Tema 2.

Compiladores e Intérpretes Análisis Sintáctico

Analizador Sintáctico Ascendente

18 Análisis sintáctico III Compiladores - Profr. Edgardo Adrián Franco Martínez. Clasificación de métodos de análisis sintáctico Análisis descendente

Procesadores de Lenguaje

Gramáticas y parsers LR(K)

Tema 5. Análisis sintáctico ascendente

Tema 3. Análisis sintáctico descendente

Compiladores: Parsing ascendente

Proyecto Intermedio Algoritmo de Earley

Más sobre gramáticas independientes de contexto o incontextuales

22, 23 y 24 Análisis sintáctico V Compiladores - Profr. Edgardo Adrián Franco Martínez

Temas. Objetivo. Analizador Sintáctico: funciones y tipos. Analizador Sintáctico Descendente. Analizador Sintáctico Ascendente

Compiladores. Análisis Sintáctico Ascendente. Adrian Ulises Mercado Martínez. Facultad de Ingeniería, UNAM. 5 de septiembre de 2013

Procesadores de Lenguajes. Análisis sintáctico. Gramáticas libres de contexto

8- LEX-Expresiones regulares

Lenguajes y Compiladores Análisis Léxico

Compiladores: Análisis Léxico. Pontificia Universidad Javeriana Cali Ingeniería de Sistemas y Computación Prof. Gloria Inés Alvarez V.

Tipos de análisis deterministas. Análisis descendente. Tipos de análisis deterministas. Análisis ascendente. Análisis descendente

Ciencias de la Computación I

Lenguajes y Compiladores Aspectos Formales (Parte 2) Compiladores

Compiladores e intérpretes Análisis Léxico I. Análisis Léxico I

Analizador De léxico. V A R i : I N T E G E R ; \n...

ANÁLISIS SINTÁCTICO I ANALIZADORES SINTÁCTICOS

Tema 4: Gramáticas independientes del contexto. Teoría de autómatas y lenguajes formales I

Parsing Top Down (Descendente)

YACC (Yet Another Compiler Compiler) LALR(1) Parser Generator

Conceptos básicos sobre gramáticas

TRADUCTORES E INTERPRETADORES

Tema 1. Introducción

Tema: Análisis Sintáctico LR


Compiladores: Análisis sintáctico descendente recursivo

Análisis léxico. Formalización y desarrollo. Procesadores de Lenguajes. Ingeniería Técnica superior de Ingeniería Informática

Analizador Léxico. Programación II Margarita Álvarez. Analizador Léxico - Funciones

Apuntes de compiladores

Yacc/Bison. Introducción

Sintaxis y Semántica. Un repaso

Tema 2: Análisis léxico

UNIVERSIDAD NACIONAL DE EDUCACIÓN A DISTANCIA Escuela Técnica Superior de Ingeniería Informática Procesadores de Lenguajes. Tema 3.

Procesadores de Lenguajes. Análisis sintáctico. Analizadores descendentes

Procesadores de Lenguaje

Objetivos Que el estudiante logre conocer, comprender y manejar conceptos y técnicas vinculados con el Analizador Léxico, para lo cual debe:

El proceso del Análisis Léxico

ANÁLISIS LÉXICO Ing. Ronald Rentería Ayquipa

Las Etapas de la Compilación

NOTAS PARA LA MATERIA LENGUAJES DE PROGRAMACIÓN

Procesadores de lenguaje Tema Análisis sintáctico (Parte II)

Compiladores e Intérpretes Análisis Semántico I

Teoría de lenguajes Oscar BRUNO

17 Análisis sintáctico II Compiladores - Profr. Edgardo Adrián Franco Martínez. Gramáticas limpias y bien formadas

Tema: Generación de analizadores con YACC

Tema 6: Compiladores e intérpretes. Teoría de autómatas y lenguajes formales I

Tema 5. Análisis semántico

SSL Guia de Ejercicios

Procesadores de lenguaje

Lenguajes y Compiladores Introducción. Compiladores 1

B b A. Notar que las gramáticas utilizadas son sin recursión por la izquierda:

Diseño de Compiladores I. Estructura General de un Compilador

Introducción. Análisis Semántico. José M. Castaño. Teoría de Lenguajes 2011 Departamento de Computación FCEyN, UBA

Tema 2: Análisis léxico

Análisis semántico Tabla de símbolos, chequeo de tipos y representaciones internas

1. Acciones en Yacc. %{ #include <stdio.h> yyerror (char *s) { fprintf (stderr, %s\n, s) ; } %} %% : S \n {printf ( Correcto\n );} ; : ( S ) S

Analista Universitario en Sistemas. Taller de Programación II. Instituto Politécnico Superior. Trabajo Final

Tema: Análisis Sintáctico

Elementos para el estudio de los compiladores

Análisis semántico Tabla de símbolos, chequeo de tipos y representaciones internas

Universidad Tecnológica Nacional Facultad Regional Buenos Aires Grupo de Inteligencia Artificial y Robótica. Seminario IA y R

Unidad IV Análisis Sintáctico. M.C. Juan Carlos Olivares Rojas

INTRODUCCIÓN AL PROCESO DE COMPILACIÓN

Definición de la sintaxis (1) Definición de la sintaxis (2) Definición de la sintaxis (3)

Nombre de la asignatura: Lenguajes y Autómatas I. Créditos: Aportación al perfil

Práctica 4 Análisis LALR para milenguaje y construcción de un traductor de milenguaje

Tema: Análisis Sintáctico

Agenda. BNF y EBNF Brevemente, lo necesario para especificar el lenguaje sobre el que vamos a trabajar.

Sintaxis y Semántica del Lenguaje

Desarrollo de lenguajes y Compiladores [MII-771] Capítulo 1: Lenguajes y Gramáticas Formales

Teoría de Lenguajes. Parsers descendentes para gramáticas extendidas ELL(1) Miércoles 24 de Mayo de Facultad de Ciencias Exactas y Naturales

Tema 1: Introducción

Uso de la herramienta YACC

ANÁLISIS SINTÁCTICO I ANÁLISIS SINTÁCTICO DESCENDENTE LL(1)

TEORÍA. definition TAG. PROPERTIES ID expr EXTENDS ID FIN_TAG. DELAYED : expr

Contenido. Capítulo 1. Teoría de conjuntos. 1. Capítulo 2. Lenguaje. 39. Capítulo 3. Lenguajes formales. 55

token siguiente! Tabla de símbolos

Transcripción:

Agenda Introducción Analizador léxico Analysis El problema de analizar sintácticamente Analizador sintáctico descendeterecursivo Analizador sintáctico Bottom-Up 1-1

1-2

Introducción Los sistemas de implementación de lenguajes deben analizar código fuente, independientemente del enfoque de implementación específica Casi todos los analizadores sintácticos se basan en una descripción formal del lenguaje (BNF) 1-3

Análisis sintáctico Casi siempre el análisis sintáctico está compuesto de dos partes: Un componente de bajo nivel llamado analizador léxico (matemáticamente, un autómata finito basado en una gramática regular) Un componente de alto nivel llamado analizador sintáctico, o parser (matemáticamente, un autómata de pila basado en una gramática independiente del contexto, o BNF) 1-4

Usar BNF para describir la sintaxis Provee una descripción sintáctica clara y precisa El analizador sintáctico puede estar basado directamente en el BNF Los analizadores sintácticos basados en BNF son fáciles de mantener 1-5

Razones para separar el análisis léxico del análisis sintáctico Simplicidad enfoques menos complejos pueden ser usados para analizar léxicamente; separarlos simplica el parser Eficiencia la separación permite la optimización del analizador léxico Portabilidad partes de un analizador léxico pueden no ser portables pero el parser siempre es portable 1-6

Análisis léxico Un analizador léxico busca coincidencias de patrones en cadenas de caracteres Un analizador léxico es un front-end para el parser Identifica subcadenas del programa fuente - lexemes Los lexemas son cadenas que coinciden con un patrón, el cual está asociado a una categoría conocida como token sum es un lexema; su token podría ser IDENT 1-7

Análisis léxico (continuación) El analizador léxico es usualmente una función que es llamada por el parser cuando éste necesita el siguiente token Existen tres enfoques para construir un analizador léxico: Escribir una descripción formal de los tokens y usar una herramienta computacional que construya una tabla dada su descripción Diseñar un diagrama de estado que describa los tokens y escribir un programa que implemente dicho diagrama Diseñar un diagrama de estados que describa los tokens y construir una tabla manualmente de su descripción 1-8

Diseño del diagrama de estados Un diagrama de estados simple tendría una transición de cada estado de cada caracter en el código fuente - dicho diagrama sería muy largo 1-9

Análisis léxico (cont.) En muchos casos las transiciones pueden ser combinadas para simplificar el diagrama de estados Cuando se reconozca una literal entera, todos los dígitos son equivalentes usar una clase de dígito 1-10

Análisis léxico (cont.) Palabras reservadas e identificadores pueden ser reconocidos juntos (en lugar de tener una parte del diagrama para cada palabra reservada) Usar una tabla de búsqueda para determinar si un identificador es en realidad una palabra reservada. 1-11

Análisis léxico (cont.) Subprogramas utilizados convenientemente: getchar obtiene el siguiente caracter, y lo coloca en nextchar, determina su clase y la coloca en charclass addchar copia el caracter de nextchar en el lugar donde el lexema está siendo acumulado, lexema lookup determina si la cadena en lexeme es una palabra reservada (regresa un código) 1-12

Diagrama de estados 1-13

Análisis léxico (cont.) Implementación: int lex() { getchar(); switch (charclass) { case LETTER: addchar(); getchar(); while (charclass == LETTER charclass == DIGIT) { addchar(); getchar(); } return lookup(lexeme); break; 1-14

Análisis léxico (cont.) case DIGIT: addchar(); getchar(); while (charclass == DIGIT) { addchar(); getchar(); } return INT_LIT; break; } /* End of switch */ } /* End of function lex */ 1-15

El problema de analizar sintácticamente Objetivos del parser dado un programa de entrada: Encontrar todos los errores de sintáxis; de cada cada uno, producir un mensaje de diagnóstico apropiado Producir un árbol de sintáxis 1-16

El problema de analizar sintácticamente (cont.) Hay dos categorías de analizadores Top down produce el árbol de sintáxis comenzando por la raíz Su orden de derivación por la derecha Construye un árbol en preorden Bottom up produce el árbol de sintaxis comenzando por las hojas Sigue un orden de derivación invertida: por la izquierda Los analizadores buscan sólamente un token hacia adelante 1-17

El problema de analizar sintácticamente (cont.) Analizador sintáctico Top-down Dada una forma sentencial, xaα, el analizador debe escoger la A-regla correcta para obtener la siguiente forma sentencial en la derivación por la izquierda, usando sólamente el primer token producido por A Los analizadores síntacticos top-down más comunes: Descendente recursivo Analizadores sintácticos LL (Left to right Leftmost derivation) implementación basada en tablas 1-18

El problema de analizar sintácticamente (cont.) Analizadores Bottom-up Dada una forma sentencial, α, determinar que subcadena de es la parte derecha de la regla en la gramática que debe ser reducida para producir la forma sentencial previa en la derivación derecha El analizador sintáctico bottom-up más común se encuentran en la familia LR (Left to right Right most derivation). 1-19

El problema de analizar sintácticamente (cont.) La complejidad del análisis Los analizadores que trabajan para cualquier gramática no-ambigua son complejos e ineficientes ( O(n 3 ), donde n es la longitud de la entrada ) Los compiladores usan analizadores que sólamente trabajan para un subconjnto de todas las gramáticas no-ambiguas, pero lo hacen en tiempo lineal ( O(n), donde n es la longitud de la entrada ) 1-20

Analizador descendente recursivo Hay un subprograma para cada noterminal que puede analizar las sentencias que pueden ser generadas por dicho no-terminal EBNF es ideal para ser usado por una analizador descendente recursivo porque éste minimiza el número de no-terminales 1-21

Analizador descendente recursivo (cont.) Una gramática para expresiones simples: <expr> <term> {(+ -) <term>} <term> <factor> {(* /) <factor>} <factor> id ( <expr> ) 1-22

Analizador descendente recursivo(cont.) Asumamos que tenemos un analizador léxico llamado lex, el cual copia el siguiente token en nexttoken El proceso de codificación cuando hay sólamente un RHS: Para cada símbolo terminal en el RHS, se compara con el siguiente token; si coinciden, se continua, en caso contrario hay un error Para cada símbolo no-terminal en el RHS, llama a su programa analizador asociado. 1-23

Analizador descendente recursivo (cont.) /* Function expr Parses strings in the language generated by the rule: <expr> <term> {(+ -) <term>} */ void expr() { /* Parse the first term */ term(); 1-24

Analizador descendente recursivo(cont.) /* As long as the next token is + or -, call lex to get the next token, and parse the next term */ while (nexttoken == PLUS_CODE nexttoken == MINUS_CODE){ lex(); term(); } } Esta rutina particular no detecta errores Convención: Cada rutina del analizador deja el próximo token en nexttoken 1-25

Analizador descendente recursivo (cont.) Un no terminal que tiene más de una RHS requiere un proceso inicial para determinar cual RHS está analizando El correcto RHS es escogido con base al siguiente token (el lookahead) El próximo token es comparado con el primer token que puede ser generado por cada RHS hasta que se encuentre una coincidencia Si no se encuentran coincidencias, entonces existe un error 1-26

Analizador descendentes recursivos(cont.) /* Function factor Parses strings in the language generated by the rule: <factor> -> id (<expr>) */ void factor() { /* Determine which RHS */ if (nexttoken) == ID_CODE) /* For the RHS id, just call lex */ lex(); 1-27

Analizador descendente recursivo (cont.) /* If the RHS is (<expr>) call lex to pass over the left parenthesis, call expr, and check for the right parenthesis */ else if (nexttoken == LEFT_PAREN_CODE) { lex(); expr(); if (nexttoken == RIGHT_PAREN_CODE) lex(); else error(); } /* End of else if (nexttoken ==... */ } else error(); /* Neither RHS matches */ 1-28

Analizador descendente recursivo (cont.) La clase gramatical LL El problema de la recursión por la izquierda Si una gramática tiene recursión por la izquierda, ya sea directa o indirectamente, no puede ser la base para un analizador top-down Se puede modificar una gramática para remover la recursión por la izquierda 1-29

Analizador descendente recursivo(cont.) La otra característica de las gramáticas que impide un análisis top-down es la falta de emparejamiento. La inhabilidad para determinar el RHS correcto de acuerdo a la base de un token de lookahead 1-30

Analizador descendente recursivo(cont.) La prueba del emparejamiento: Para cada no terminal, A, en la gramática tiene más de un RHS, para cada par de reglas, A α i y A α j, debe ser verdad que FIRST(α i ) diferente a FIRST(α j ) φ Examples: A a bb cab A a ab (Factorización por la izquierda) 1-31

Analizador Bottom-up El problema de analizar sintáticamente es encontrar la correcta RHS en una forma sentencial derecha para reducir y obtener la forma sentencial derecha previa en la derivación 1-32

Analizador Bottom-up (cont.) Shift-Reduce Algorithms Reduce es la acción de reemplazar el manejador que está en la cima de la pila con su correspondientelhs Desplaza es la accioń de mover el siguiente token a la cima de la pila 1-33

Analizador Bottom-up (cont.) Ventajas de los parsers LR Trabajan con casi cualquier gramática. Además son igual de eficientes que los bottom-up Pueden detectar errores rápidamente. Las clases de gramáticas LR son un superconjunto de las clases de analizables sintácticamente por los parsers LL. 1-34

Analizador Bottom-up (cont.) Los parsers LR deben ser construidos con una herramienta: YACC, BISON, ANTLR, etc 1-35

Analizador Bottom-up (cont.) Una configuración LR guarda el estado de un parser LR, mientras que para construir un LL, se necesita muchísima memoria. (S 0 X 1 S 1 X 2 S 2 X m S m, a i a i +1 a n $) 1-36

Analizador Bottom-up (cont.) Los parsers LR están basados en tablas, donde la tablas tiene dos componentes, una tabla ACCIÓN y una tabla GOTO La tabla ACCIÓN especifica la acción a realizar, a partir de un estado dado y el siguiente token Los renglones son los nombres de estado y las columnas las terminales La tabla GOTO especifica cuál estado será puesto en la cima de la pila después que una reducción sea hecha. Los renglones son los nombres del estado y las columnas los no terminales. 1-37

Estructura de un Analizador LR 1-38

Analizador Bottom-up (cont.) Configuración Inicial: (S 0, a 1 a n $) Acciones del parser: If ACTION[S m, a i ] = Desplaza S, la próxima configuración es: (S 0 X 1 S 1 X 2 S 2 X m S m a i S, a i+1 a n $) If ACTION[S m, a i ] = Reduce A β y S = GOTO[S m-r, A], realizado r = la longitud de β, la próxima configuración es (S 0 X 1 S 1 X 2 S 2 X m- rs m-r AS, a i a i+1 a n $) 1-39

Analizador Bottom-up (cont.) Acciones del parser (cont.): If ACTION[S m, a i ] = Acepta, el análisis está completo y se encontraron errores. If ACTION[S m, a i ] = Error, el parser llama a una rutina para manejar errores. 1-40

Analizador Bottom-up (cont.) Una tabla de un parser puede ser generada desde una herramienta para manejar gramáticas, e.g., yacc 1-41

Resumen La sintaxis es algo usual al momento de implementar lenguajes Un analizador léxico analizador de similitudes que aisla las pequeñas partes de un programa Detecta errores Produce un arbol de análisis. Un parser recursivo descendente es del tipo LL EBNF El problema de analizar sintáticamente parsers bottom-up: encontrar la subcadena de la forma sentenciales actual. La familia LR de parsers shift-reduce son más comunes que los enfoques basados en bottomup. 1-42