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

Documentos relacionados
PROCESADORES DE LENGUAJE EXAMEN FINAL 8-JUNIO-07

ANÁLISIS SEMÁNTICO. Especificación formal: Semántica Operacional, semántica denotacional, semántica Axiomática, Gramáticas con Atributos.

PROGRAMA DE LABORATORIO SECCIÓN: ÁREA A LA QUE PERTENECE: POS-REQUISITO: AUXILIAR:

Algoritmos y programas. Algoritmos y Estructuras de Datos I

Unidad II: Análisis semántico

Capítulo 5: Traducción Dirigida por Sintaxis

Las Etapas de la Compilación

Unidad I: Análisis semántico

Métodos para escribir algoritmos: Diagramas de Flujo y pseudocódigo

Construcción de tablas de análisis sintáctico LL(1)

LEX. Las definiciones y subrutinas son opcionales. El segundo %% es opcional pero el primer %% indica el comienzo de las reglas.

Tema 1.3. Un lenguaje mínimo y su procesador: Restricciones contextuales

Métodos que devuelven valor Dado el siguiente triángulo rectángulo:

Tipos algebraicos y abstractos. Algoritmos y Estructuras de Datos I. Tipos algebraicos

Guía práctica de estudio 05: Diagramas de flujo

SISTEMAS INFORMÁTICOS PROGRAMACION I - Contenidos Analíticos Ing. Alejandro Guzmán M. TEMA 2. Diseño de Algoritmos

Tema 3. Análisis sintáctico descendente

Compiladores: Parsing ascendente

Procesadores de lenguaje Tema 6 La tabla de símbolos

JavaCC Parte I. 1 Compiladores / Guía VII / Ciclo Facultad: Ingeniería Escuela: Computación Asignatura: Compiladores.

Algoritmos. Medios de expresión de un algoritmo. Diagrama de flujo

GUIA 2: Repaso sobre uso de C#. Funciones, métodos y arreglos.

TEORÍA DE AUTÓMATAS Y LENGUAJES FORMALES TRABAJO DE PRÁCTICAS. Convocatoria de junio de 2013

INGENIERÍA DEL SOFTWARE I Práctica 5 Modelado de Diseño

Universidad de Costa Rica. Escuela de Ciencias de la Computación e Informática CI-2700 TÓPICOS ESPECIALES - COMPILADORES.

LABORATORIO DE PROCESADORES DE LENGUAJE Curso: Práctica 2: Analizador léxico/sintáctico/semántico con Flex y Bison

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

Tema: Autómata de Pila

Unidad V Análisis Semántico. M.C. Juan Carlos Olivares Rojas

GRAMATICAS LIBRES DEL CONTEXTO

Diseño Estructurado de Algoritmos

Diagramas de secuencia

Toda copia en PAPEL es un "Documento No Controlado" a excepción del original.

Unidad I Introducción a la programación de Sistemas. M.C. Juan Carlos Olivares Rojas

Elementos de un programa en C

Procesadores de Lenguaje

Tema II: Metodología para la construcción de programas

PHP: Lenguaje de programación

Unidad Didáctica 2. Elementos básicos del lenguaje Java Tipos, declaraciones, expresiones y asignaciones

Sistema electrónico digital (binario) que procesa datos siguiendo unas instrucciones almacenadas en su memoria

Desde los programas más simples escritos en un lenguaje de programación suelen realizar tres tareas en forma secuencial.

Conversión entre Tipos

CRITERIOS DE SELECCIÓN DE MODELOS

Programación. Test Autoevaluación Tema 3

Universidad de Managua

Lenguaje de programación. COMPILADORES Unidad I: Introducción al proceso de compilación

Tema 2 Introducción a la Programación en C.

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

Generador de analizadores léxicos FLEX

Objetivos de la sesión. Aplicación de consola 7/30/11. Código con que se inicia un programa en Visual C# (aplicación de consola)

OPTIMIZACIÓN DE CÓDIGO

Estructuras de control

1. Cuántas sentencias hay en la secuencia principal del siguiente programa?

Tabla de Símbolos. Programación II Margarita Álvarez

Funciones como Subprogramas en C++

Unidad 4. Autómatas de Pila

Lenguajes de Programación. Juan Zamora O. Semestre II Nombres, Ambitos y Ligados

ESCUELA POLITÉCNICA SUPERIOR PRÁCTICA 2: EXPRESIONES, PRINTF Y SCANF

Enteros. Son los números que no contienen componentes fraccionarios y, por tanto, no contienen punto decimal.

FUNCIONES PHP: DECLARACIÓN Y LLAMADAS. PARÁMETROS, RETURN. EJERCICIOS EJEMPLOS RESUELTOS. (CU00827B)

$0 Representa al parámetro cero o nombre del programa $1 Representa al parámetro uno $2 Representa al parámetro dos

Herramientas de Programación. M.C. Juan Carlos Olivares Rojas

MODELOS DE COMPUTACION I Preguntas Tipo Test. 1. El lema de bombeo puede usarse para demostrar que un lenguaje determinado es regular.

Tema 13: Apuntadores en C

Las plantillas permiten definir funciones genéricas.

Programación en C. Algoritmo y Estructura de Datos. Ing. M. Laura López. Programación en C

Diagramas de secuencia

Programación MODULAR: Subalgoritmos - funciones y procedimientos

Ejercicios de Lógica Proposicional *

Tema: Clases y Objetos en C#. Parte II.

Control de Flujo. Estructuras de Control! Experiencia Educativa de Algorítmica CONTROL DE FLUJO

Tema II: Metodología para la construcción de programas. Profesora: Nelly García Mora

Introducción a C++ y Code::Blocks

Estatutos de Control C# Estatutos de Decisión (Selección)

Java Avanzado Facultad de Ingeniería. Escuela de computación.

Instituto Tecnológico de Celaya

5. Sentencias selectivas o condicionales

Requerimientos de Software

GENERACIÓN DE CÓDIGO

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

Conceptos a tratar. Fundamentos de la Programación Orientada a Objetos Ampliación sobre clases y objetos

Expresiones y sentencias

APUNTADORES. Un apuntador es un objeto que apunta a otro objeto. Es decir, una variable cuyo valor es la dirección de memoria de otra variable.

INTERFACE COMPARATOR. DIFERENCIAS ENTRE COMPARATOR Y COMPARABLE. CLASE COLLECTIONS. EJERCICIOS RESUELTOS. (CU00918C)

Procesamiento de documentos XML.

XQuery. Un lenguaje de consulta para XML.

EJERCICIOS del TEMA 3: Lenguajes independientes del contexto

Programación Estructurada

Serialización de datos en C# en Binario, Soap y Xml

PROGRAMACION ORIENTADA A OBJETOS EN C++

GLOSARIO DE MICROSOFT VISUAL BASIC (HAZ CLIC EN LA OPCION DEL MENU Y ACCEDERAS RAPIDAMENTE)

LA ESTRUCTURA DE DATOS PILA EN JAVA. CLASE STACK DEL API JAVA. EJEMPLO Y EJERCICIOS RESUELTOS. (CU00923C)

CURSO: PRESENTE Y DESAFIOS DE LA GESTION PARLAMENTARIA

Java Avanzado. Guía 1. Java Avanzado Facultad de Ingeniería. Escuela de computación.

Todo programa en 'C' consta de una o más funciones, una de las cuales se llama main.

Tema: Entorno a C# y Estructuras Secuenciales.

Universidad de Cantabria. Facultad de Ciencias Ingeniería en Informática. Ingeniería del Software II

Transcripción:

1 Compiladores e Intérpretes Análisis Semántico I Sebastian Gottifredi 2017

Organización Repaso Intuición General del Análisis Semántico Gramáticas de Atributos Funcionamiento Atributos: Sintetizados-Heredados-Intrinsecos Esquema de Traducción Evaluación en un Analizador Sintáctico 2

Repaso 3

Repaso Para entender y controlar la estructura de un programa fuente hay que analizar si sigue las reglas de sintaxis del lenguaje Estas reglas están expresadas en términos de tokens, mientras que el fuente es una cadena de caracteres El Analizador Léxico es el encargado armar los tokens Para expresar las reglas de sintaxis del lenguaje utilizamos gramáticas libres de contexto 4

Repaso El analizador sintáctico es el encargado de reconocer si un programa sigue esas expresadas por la gramática, para eso: La gramática tiene que ser no ambigua Simula el proceso de derivación usando una estrategia: Descendentes: arrancando del no terminal Inicial reconstruir la derivación a izquierda hasta llegar a la cadena Ascendentes: aplican las producciones en orden inverso hasta llegar al símbolo inicial de la gramática 5

Repaso Estrategias Descendentes: simular la derivación a izquierda mediante Mediante Tabla LL(1) Recursiva Estrategia Ascendentes: simular la derivación a derecha en orden inverso mediante: Tabla de estados representando posibles prefijos 6

Intuición General del Análisis Semántico 7

Intuiciones Análisis Semántico La tarea final del compilador es traducir el programa fuente en un código que se pueda ejecutar directamente en la maquina destino Para esto necesita conocimiento del programa que va mas allá de la estructura sintáctica. Informalmente cuando la sintaxis indica la forma valida de un programa la semántica concierne su significado, que es clave para: Controlar que se cumplan las reglas (consistencia de tipos) Obtener información para generar un programa de salida equivalente 8

Intuiciones Análisis Semántico Por ejemplo, para un id con lexema x Qué tipo de valor se puede almacenar en x? Si x es una suprograma Cuántos parámetros tiene? Que tipo de valor retorna? En donde es visible x? Si x esta ligado a un objeto Qué mensajes se le pueden enviar? Fue previamente declarado x? Cual es el tipo resultante de evaluar una expresión cuyo valor será almacenado en x? 10

Intuiciones Análisis Semántico Las tareas del analizador semántico, en general para un lenguaje de programación con tipado estático, se pueden dividir en dos: Recolectar, entender y controlar todas las entidades declaradas Chequeo de Declaraciones Recolectar, entender y controlar todas las sentencias asociadas a las entidades recolectadas Chequeo de Sentencias 11

Intuiciones Análisis Semántico Hay dos alternativas para implementar el analizador semántico: Intercalado con el analizador sintáctico Los controles semánticos se implementan dentro del analizador sintáctico Separado del analizador sintáctico Como parte del analizador sintáctico se implementa la construcción de una representación intermedia utilizada por otro modulo encargado del análisis semánticos 12

Intuiciones Análisis Semántico En cualquier caso, es necesario realizar acciones especiales dentro del analizador sintáctico O bien para realizar los controles semánticos O para construir la representación intermedia (arboles sintácticos) Las Gramáticas de Atributos son las herramientas formales utilizadas para diseñar estas acciones en el analizador sintáctico 13

Gramáticas de Atributos 14

Gramáticas de Atributos Son gramáticas libres de contexto aumentadas con conjunto de reglas (acciones) que especifican computaciones Cada regla asocia valores a atributos usando otros atributos Los atributos están asociados a los símbolos de la gramática S E$ E E + T E - T T T (E) string num El + concatena strings, concatena un entero a un string, o suma enteros El solo resta enteros Queremos: Calcular el tipo una expresión en un atributo! S.tipo E.tipo T.tipo 15

Gramáticas de Atributos Una regla se utiliza para dar valor a un atributo {T.tipo = tstr} Las reglas se vinculan a producciones de la gramática T string {T.tipo = tstr} Las reglas solo pueden utilizar atributos vinculados a símbolos la producción a la cual están vinculados 16

Gramáticas de Atributos En su concepción formal Una regla asociada a una producción asocia el valor de un atributo de los símbolos de la producción, donde el atributo puede Tomar directamente el valor de otro atributo o una constante, T string {T.tipo = tstr} E T {E.tipo = T.tipo} Tomar el valor de una función semántica, la cual puede tener un numero arbitrario de argumentos que solo pueden ser atributos asociados a símbolos de la producción Cuando se repite un símbolo en una producción es posible subindicarlos para distinguirlos entre ellos 17

Gramáticas de Atributos En la practica, permitimos que las reglas sean porciones de código en un lenguaje bien definido (el de implementamos del compilador) La intuición es especificar las funciones semánticas in-line E 1 E 2 - T {if(t.tipo == tint && E 2.tipo == tint) E 1.tipo = tint else ERROR} Aun así solo podemos referirnos a atributos asociados a la producción a la cual la regla esta vinculada. Pero, en caso de ser necesario podemos usar variables globales. 18

Gramáticas de Atributos S E$ E E + T E - T T T (E) string num El + concatena strings, concatena un entero a un string, o suma enteros El solo resta enteros Queremos: Calcular el tipo una expresión en un atributo! S.tipo E.tipo T.tipo Producción Reglas Semanánticas S E$ {S.tipo = E.tipo} E 1 E 2 + T {if(t.tipo == tstr E 2.tipo == tstr) E 1.tipo = tstr else E 1.tipo = tint} E 1 E 2 - T E T T (E) T string T num {if(t.tipo == tint && E 2.tipo == tint) E 1.tipo = tint else ERROR} {E.tipo = T.tipo} {T.tipo = E.tipo} {T.tipo = tstr} {T.tipo = tint} Pizarrón! 19

Funcionamiento de las Gramáticas de Atributos 21

Evaluando Atributos y Acciones El proceso de evaluar los atributos aplicando las reglas es denominado anotación o decoración del árbol de derivación En este árbol cada nodo va a estar etiquetado con los atributos asociados al símbolo que tiene asociado Aplica una regla en un nodo solo cuando se hayan calculado todos los valores necesarios para el calculo En general, implica calcular valores de atributos en nodos descendientes y/o hermanos! (8-5)+ hola $ Pizarrón! 22

Evaluando Atributos y Acciones E T ( E E T num tipo=tint tipo=tint E tipo=tint tipo=tint tipo=tint - T num S ) tipo=tint tipo=tstr tipo=tstr + T string $ tipo=tstr (8-5)+ hola $ 23

Evaluando Atributos y Acciones El orden en el que fuimos calculando los valores de los atributos da el patrón en el que fluye la información a través del árbol Este patrón es denominado flujo de atributos E T ( E E T num tipo=tint tipo=tint E tipo=tint tipo=tint tipo=tint - T num S tipo=tstr ) tipo=tint tipo=tstr + T string $ tipo=tstr (8-5)+ hola $ 24

Atributos Sintetizados Un atributo es sintetizado si toma valor solo cuando aparece asociado al símbolo NT de la parte izquierda de la producción Es sintetizado el atributo tipo del ejemplo anterior? En el árbol decorado este comportamiento se ve cuando un atributo hace fluir información de abajo hacia arriba. Mediante el flujo se puede ver que la información sube (se sintetiza) a través de los nodos del árbol SI! 25

Atributos Intrínsecos Un atributo es intrínseco cuando su valor se asume dado de antemano Son los atributos asociados a los tokens Pueden verse también como atributos sintetizados, los cuales se sintetizan de manera externa Por ejemplo, el lexema de un token es un atributo intrínseco 26

Atributos Heredados Un atributo es heredado si toma valor solo cuando aparece asociado al símbolo de la parte derecha de la producción. En el árbol estos atributos permiten la información fluya de arriba hacia abajo o desde los costados S D$ D T L T id pstring pint L id R R id R e Gramática para declarar variables Queremos guardar el nombde de cada id con su respectivo tipo, usando la función Guardar(nombre, tipo) T.tipo (sintetizado) E.tipo (heredado) R.tipo (heredado) token.lex(intrínseco) Pizarrón! 27

Atributos Heredados Producción S D$ D T L T id T pstring T pint L id R R 1 id R 2 R e Reglas Semanánticas {L.tipo = T.tipo} {T.tipo = id.nombre} {T.tipo = tstr} {T.tipo = tint} {Guardar(id.lex,L.tipo)} {R.tipo = L.tipo} {Guardar(id.lex, R 1.tipo)} {R 2.tipo = R 1.tipo} int a1 v1 x Pizarrón! 28

Atributos Heredados Mediante el flujo se puede ver que la información pasa con atributos heredados va hacia abajo y hacia los laterales T pint tipo=tint D L Id Lex=a1 Id Lex=v1 int a1 v1 x tipo=tint R Id tipo=tint guardar(a1,tint) Lex=x R tipo=tint guardar(v1,tint) R tipo=tint guardar(x,tint) 29

Evaluando Atributos y Acciones Producción Producción S D$ D$ D T L T id T id pstring T pint pstring L T id pint R L id R R 1 id R 2 R 1 id R 2 R e R e Reglas Semanánticas Reglas Semanánticas {for(x in L.lista) {L.tipo Guardar(x, = T.tipo} T.tipo) {T.tipo } = id.lex} {T.tipo = tstr} id.nombre} {T.tipo = tint} tstr} {Guardar(id.lex,L.tipo)} {T.tipo = tint} {R.tipo {R.lista.add(id.nombre)) = L.tipo} {Guardar(id.lex, {L.lista = R.lista} R 1.tipo)} {R.tipo = R 1.tipo} 2.lista.add(id.nombre))} {R 1.lista = R 2.lista} {R.lista = new List()} Hubiese sido posible resolver esto usando solo atributos sintetizados? Si! Con una lista 30

Evaluando Atributos y Acciones Veamos otro ejemplo Pizarrón! S E$ E E + T E - T T T (E) string num El + concatena strings, concatena un entero a un string, o suma enteros El solo resta enteros Queremos: Calcular el tipo una expresión en un atributo! S E$ E T R R +TR -TR e T (E) string num S.tipo (sintetizado) E.tipo (sintetizado) T.tipo (sintetizado) R.tipoS (sintetizado) R.tipoH (heredado) token.nombre(intrínseco) 31

Evaluando Atributos y Acciones Producción S E$ E T R R 1 +TR 2 R 1 -TR 2 R e T (E) T string T num Reglas Semanánticas {R.tipoH = T.tipo} {E.tipo = R.tipoS} {if(t.tipo == tstr R 1.tipoH == tstr) R 2.tipoH = tstr else R 2.tipoH = tint} {R 1.tipoS = R 2.tipoS} {if(t.tipo == tint && R 1.tipoH == tint) R 2.tipoH = tint else ERROR} {R 1.tipoS = R 2.tipoS} {R.tipoS = R.tipoH} {T.tipo = E.tipo} {T.tipo = tstr} {T.tipo = tint} 32

Evaluando Atributos y Acciones S tipos=tstr Pizarrón! E $ T tipo=tint R tipos=tstr tipoh=tint ( E tipo=tint ) + T tipo=tstr R tipos=tstr tipoh=tstr T tipo=tint R tipos=tint tipoh=tint string tipo=tstr num - T tipo=tint R tipos=tint tipoh=tint num tipo=tit (8-5)+ hola $ 33

Esquemas de Traducción Como vimos en para decorar los arboles seguimos un orden al aplicar las acciones vinculadas a las producciones Los esquemas de traducción (EDT) nos permiten embeber las reglas en la gramática para indicar el orden en que las vamos a aplicar, si seguimos una estrategia de primero en profundidad de izquierda a derecha para recorrer el arbol. En un EDT vamos a tener producciones, por ejemplo, de la forma: A B {C.y = B.x} C {A.z = C.w} 34

Esquemas de Traducción Producción Reglas Semanánticas S D$ D T L T id T pstring T pint L id R R 1 id R 2 R e {L.tipo = T.tipo} {T.tipo = id.nombre} {T.tipo = tstr} {T.tipo = tint} {Guardar(id.lex,L.tipo)} {R.tipo = L.tipo} {Guardar(id.lex, R 1.tipo)} {R 2.tipo = R 1.tipo} Esquema de Traducción (EDT) S D$ D T {L.tipo = T.tipo} L T id {T.tipo = id.nombre} T pstring {T.tipo = tstr} T pint {T.tipo = tint} L id {R.tipo = L.tipo} R {Guardar(id.lex,L.tipo)} R 1 id {Guardar(id.lex, R 1.tipo)} R 2 {R 2.tipo = R 1.tipo} R e 35

Esquemas de Traducción Esquema de Traducción S E$ E T {R.tipoH = T.tipo} R {E.tipo = R.tipoS} R 1 +T {if(t.tipo == tstr R 1.tipoH == tstr) R 2.tipoH = tstr else R 2.tipoH = tint} R 2 {R 1.tipoS = R 2.tipoS} R 1 -T {if(t.tipo == tint && R 1.tipoH == tint) R 2.tipoH = tint else ERROR} R 2 {R 1.tipoS = R 2.tipoS} R e {R.tipoS = R.tipoH} T (E) {T.tipo = E.tipo} T string {T.tipo = tstr} T num {T.tipo = tint} Pizarrón! 36

Esquemas de Traducción No cualquier gramática de atributos tiene un esquema de traducción asociado Por qué? En una EDT un atributo heredado asociado a un símbolo en la parte derecha de una producción solo puede depender de atributos heredados del simbolo de la parte izquierda o de atributos (sintetizados o heredados) de símbolos mas a la izquierda en la parte derecha Por qué? En la EDT la evaluación se hace de izquierda a derecha y en profunidad A B C {B.x = C.y} 37

Evaluando EDTs en Analizadores Sintáctico 38

EDTs en Analizadores Sintácticos Para reconocer sintácticamente un programa el analizador sintáctico simula el mecanismo de derivación usando las reglas de la gramática Una derivación tiene un árbol de derivación asociado Entonces, el analizador sintáctico simula la construcción del árbol de derivación! 39

EDTs en Analizadores Sintácticos El analizador construye implícitamente el árbol Tenemos que combinar orden de aplicación de las acciones de la gramática con tal construcción En particular, en los analizadores descendentes predictivos el árbol se construye siguiendo una política de primero en profundidad de izquierda a derecha. Es el orden de evaluación que asume la EDT! 40

EDTs en Analizadores Sintácticos En los analizadores descendentes predictivos recursivos, la implementación de una EDT es directa Cómo codificamos las acciones? Cuando codificamos la parte derecha, también codificamos las acciones siguiendo el orden en el que aparecen en la producción Cómo modelamos los atributos sintetizados? Son retornados por el subprograma correspondiente al NT asociado al atributo Cómo modelamos los atributos heredados? Son los parámetros de entrada correspondiente al NT asociado al atributo 41

EDTs en Analizadores Sintácticos Por ejemplo: A r B {C.y = B.x} C {A.z = C.w} void A(){ match( r ) B() C() } A(){ match( r ) x = B() w = C(x) return w} 42

EDTs en Analizadores Sintácticos Esquema de Traducción (EDT) S D$ D T {L.tipo = T.tipo} L T id {T.tipo = id.nombre} T pstring {T.tipo = tstr} T pint {T.tipo = tint} L id {R.tipo = L.tipo} R {Guardar(id.lex,L.tipo)} R 1 id {Guardar(id.lex, R 1.tipo)} R 2 {R 2.tipo = R 1.tipo} R e void D() Tipo t = T() L(t) Tipo T() if(tkact es id) String nom = tkact.lex match( id ) return new TipoClase(nom) else if(tkact es pint) match( pint ) return new TipoInt() else if(tkact es pstring) match( pstring ) return new TipoInt() else ERROR SINTACTICO! void L(Tipo t) String nom = tkact.lex match( id ) R(t) Guardar(nom, t) void R(Tipo t) if(tkact es id) String nom = tkact.lex match( id ) R(t) Guardar(nom, t) else if(tkactual es $) else ERROR SINTACTICO 43

EDTs en Analizadores Sintácticos En los analizadores sintácticos descendentes basados en tabla lo que hacemos es tratar a las acciones como: Un símbolo mas a la hora de apilarlos cuando aplicamos una producción Una porción de código a ejecutar cuando esta en el tope de la pila 44

EDTs en Analizadores Sintácticos Los métodos ascendentes LR solo pueden trabajar con EDTs donde las acciones estén en lugares de la producción donde no hay ambigüedad de que se reducirá por esa producción Por lo tanto, estos métodos trabajan adecuadamente con gramáticas que no tienen atributos heredados La intuición es que las acciones semánticas asociadas a una regla se ejecutan cuando se realiza una reducción 45