UNIVERSIDAD NACIONAL DE JUJUY Facultad de Ingeniería ANÁLISIS SEMÁNTICO Grupo 4: CARI, Jonatan Maximiliano LAMAS, Daniel Alberto GUERRERO, Matías GUZMAN, Ariel Palomino FASES DEL COMPILADOR Estas 2 primeras fases son las encargadas de definir la estructura sintáctica del lenguaje y sus componentes léxicos. LD A, t1 INC A STA t1, A Código Final Código Intermedio Analizador Semántico <a, ID> Analizador Sintáctico ; 1 + a := a Analizador Léxico a:=a+1; Las 3 fases siguientes son las encargadas de dar un significado único, preciso y computable a cada construcción del lenguaje. 0000 0110 0110 1100 1110 0110 0001 0111 1111 1101 ¿POR QUÉ NECESITAMOS EL ANÁLISIS SEMÁNTICO? El analizador sintáctico solo puede detectar errores sobre la estructura del lenguaje, no así los errores de la interpretación de esta estructura. Por esta razón necesitamos un analizador semántico. ¿QUÉ ES UN ANALIZADOR SEMÁNTICO? El analizador semántico es un parte más del proceso de los compiladores en lo cual incluye la verificación de que una gramática tenga sentido o interpretación de un significado de un determinados elementos, símbolos, o expresión. El analizador semántico trata de determinar el tipo de resultado intermedio, comprobar que los argumentos que tienen un operador pertenece a un conjunto de los operadores posibles y si son compatible entre si. ¿QUÉ ES UN ANALIZADOR SEMÁNTICO? Por ejemplo Supongamos que tenemos una línea de código en C# 𝑅𝑒𝑠 = 𝑣𝑎𝑙𝑜𝑟1 + 𝑣𝑎𝑙𝑜𝑟2; 𝑐ℎ𝑎𝑟 ≠ 𝑑𝑜𝑢𝑏𝑙𝑒 𝑁𝑜 𝑐𝑜𝑚𝑝𝑎𝑡𝑖𝑏𝑙𝑒 ⇒ 𝐸𝑟𝑟𝑜𝑟 COMO FUNCIONA EL ANALIZADOR SEMÁNTICO El analizador semántico características que son requiere las siguientes atributos reglas semánticas Existen dos maneras de asociarlos definición dirigida por regla de sintaxis esquema de traducción En ambos casos es útil definir un conjunto de atributos a los símbolos gramaticales a los lenguajes. TRADUCCIÓN DIRIGIDA POR SINTAXIS Es una generalización de una gramática libre de contexto en la cual cada símbolo tiene asociado un conjunto de atributos. Asocia información a construcciones de un lenguaje de programación, asignándole atributos al símbolo de la gramática que representa dicha construcción. Dependiendo del tiempo en que se realice la traducción dentro del ciclo de compilación tenemos dos clases de traducción: 1. Traducción en tiempo de compilación. 2. Traducción en tiempo de ejecución. DEFINICIÓN DIRIGIDA POR SINTAXIS Una definición dirigida por sintaxis es un formalismo para especificar las traducciones para las construcciones en función de atributos asociados con sus componentes sintácticos. La idea es asociar con cada símbolo de la gramática un conjunto de atributos y además a cada producción un conjunto de reglas semánticas para calcular los valores de los atributos asociados con los símbolos que aparecen en esa producción. La definición dirigida por sintaxis consiste en sí entonces de la gramática y el conjunto de reglas semánticas. TABLA DE SÍMBOLOS Estructura más importante para el análisis semántico. Contiene información esencial para el análisis. Su información va a servir para fases posteriores de síntesis: Optimización Generación de código final Permanece sólo en tiempo de compilación, salvo excepciones TABLA DE SÍMBOLOS ¿Qué almacena? Almacena información sobre: - Identificadores - Palabras reservadas (opcional) - Constantes (opcional) Para cada entrada en la TS se debe guardar: - Lexema - Tipo (depende de la implementación) - Ámbito (depende de la implementación) - Dirección de memoria TABLA DE SÍMBOLOS Ejemplo 𝑀𝑎𝑡𝑟𝑖𝑧 𝑇𝑖𝑝𝑜 𝑑𝑒 𝑒𝑙𝑒𝑚𝑒𝑛𝑡𝑜𝑠 𝑁ú𝑚𝑒𝑟𝑜 𝑑𝑒 𝑒𝑙𝑒𝑚𝑒𝑛𝑡𝑜𝑠 𝐿í𝑚𝑖𝑡𝑒 𝑖𝑛𝑓. 𝑦 𝑠𝑢𝑝. 𝑁ú𝑚𝑒𝑟𝑜 𝑑𝑒 𝑝𝑎𝑟𝑎𝑚𝑒𝑡𝑟𝑜𝑠 𝑃𝑟𝑜𝑐𝑒𝑑𝑖𝑚𝑖𝑒𝑛𝑡𝑜 𝑇𝑖𝑝𝑜 𝑑𝑒 𝑝𝑎𝑟𝑎𝑚𝑒𝑡𝑟𝑜𝑠 𝐹𝑜𝑟𝑚𝑎 𝑑𝑒 𝑝𝑎𝑠𝑜 𝑅𝑒𝑓𝑒𝑟𝑒𝑛𝑐𝑖𝑎 𝑉𝑎𝑙𝑜𝑟 PRINCIPALES OPERACIONES DE LA TS Inserción Búsqueda Eliminación GESTIÓN DE TABLA DE SÍMBOLOS La gestión de la TS es un punto crítico para el rendimiento del compilado. El acceso a la TS debe hacerse de forma eficiente y en cualquier momento. ¿Quién debe acceder a la TS? Analizador Léxico. Analizador Semántico. IMPLEMENTACIÓN DE LA TABLA DE SÍMBOLOS La Implementación de la TS debe ser eficiente: Lista: - Permite insertar fácilmente La búsqueda depende del nº de elementos Puede ser muy costoso Lista ordenada: - La búsqueda es sencilla La inserción es muy costosa Tabla Hash: Coste de inserción bajo Coste de búsqueda bajo - Ideal para la TS - TABLA DE SÍMBOLOS Ejemplo Número Nombre de Variable Dirección Tipo Valor Línea Declaración Líneas Referenciada 1 Empresa 0 4 1 2 9,14,25 2 X3 4 1 0 3 12,14 3 Formal 8 3 2 4 36,37,38 4 B 48 1 0 5 10,11,13,23 5 Resp 52 1 0 5 11,23,25 6 M 56 6 0 6 17,21 7 Primero 64 2 0 7 28,29,30,38 ATRIBUTOS Un atributo es un espacio de información que sirve para albergar una característica propia del proceso de traducción y que puede ser transferida a otras producciones gramaticales para que pueda ser usada desde allí por sus reglas semánticas. También se puede definir atributo como a las propiedades de los símbolos del lenguaje que almacenan contenidos relacionados con el significado de los símbolos a los que pertenecen. Se utiliza la notación 𝑠í𝑚𝑏𝑜𝑙𝑜. 𝑎𝑡𝑟𝑖𝑏𝑢𝑡𝑜 Ejemplos 𝐼𝑑. 𝑙𝑒𝑥𝑒𝑚𝑎 𝑣𝑎𝑟. 𝑣𝑎𝑙𝑜𝑟 𝑣𝑎𝑟. 𝑑𝑖𝑟𝑒𝑐𝑐𝑖𝑜𝑛 ATRIBUTOS: TIPOS DE ATRIBUTOS Atributos Sintetizados Atributos Heredados Se calculan a partir de atributos de nodos hijos. Calculados con atributos en nodos padre y hermanos. Se refieren a los atributos del antecedente de la regla. Se refieren a atributos del consecuente de la regla. La información asciende por el árbol. Información descendente o de transito horizontal. Los atributos sintetizados lo son durante toda la gramática. Los atributos heredados lo son durante toda la gramática. Los atributos de terminales son sintetizados. ATRIBUTOS: EJEMPLOS Atributos Heredados Atributos Sintetizados REGLAS SEMÁNTICAS Una regla semántica es una expresión formal asociada a una regla de producción que permite definir la semántica de la construcción gramatical asociada a la misma en términos de los símbolos de la regla de producción. REGLAS SEMÁNTICAS Contamos con 2 tipos de Reglas Semánticas: Reglas de ecuaciones de atributos. Reglas de acción semántica. ECUACIONES DE ATRIBUTOS Los valores de los atributos, de cada símbolo gramatical, están relacionados con los valores de los atributos de los otros símbolos en la regla. 𝑋𝑖 . 𝑎𝑗 = 𝑓𝑖𝑗 𝑋0 . 𝑎1 , … , 𝑋0 . 𝑎𝑘 , 𝑋1 . 𝑎1 , … , 𝑋𝑛 . 𝑎1 , … , 𝑋𝑛 . 𝑎𝑘 donde: 𝑓𝑖𝑗 : es una función matemática de sus argumentos. 𝑎𝑗 , … , 𝑎𝑘 : es la colección de todos los atributos para todas las reglas gramaticales. 𝑋𝑖 : símbolos gramaticales. ECUACIONES DE ATRIBUTOS Ahora veremos un ejemplo para la cadena 𝒇𝒍𝒐𝒂𝒕 𝒙, 𝒚; Consideremos la siguiente gramática simple para declaraciones de variables de tipo int y float en una sintaxis tipo C: 𝑑𝑒𝑐𝑙 → 𝑡𝑦𝑝𝑒 𝑣𝑎𝑟L𝑖𝑠𝑡; 𝑡𝑦𝑝𝑒 → 𝒊𝒏𝒕 | 𝒇𝒍𝒐𝒂𝒕 𝑣𝑎𝑟𝐿𝑖𝑠𝑡 → 𝒊𝒅, (𝑣𝑎𝑟𝐿𝑖𝑠𝑡 | 𝒊𝒅) ECUACIONES DE ATRIBUTOS Asociada a la gramática tendremos la siguiente gramática con atributos dtype. Regla Gramatical Reglas Semánticas 𝑑𝑒𝑐𝑙 → 𝑡𝑦𝑝𝑒 𝑣𝑎𝑟𝐿𝑖𝑠𝑡; 𝑣𝑎𝑟𝐿𝑖𝑠𝑡. 𝑑𝑡𝑦𝑝𝑒 = 𝑡𝑦𝑝𝑒. 𝑑𝑡𝑦𝑝𝑒 𝑡𝑦𝑝𝑒 → 𝒊𝒏𝒕 𝑡𝑦𝑝𝑒. 𝑑𝑡𝑦𝑝𝑒 = 𝑖𝑛𝑡𝑒𝑔𝑒𝑟 𝑡𝑦𝑝𝑒 → 𝒇𝒍𝒐𝒂𝒕 𝑡𝑦𝑝𝑒. 𝑑𝑡𝑦𝑝𝑒 = 𝑟𝑒𝑎𝑙 𝑣𝑎𝑟𝐿𝑖𝑠𝑡1 → 𝒊𝒅, 𝑣𝑎𝑟𝐿𝑖𝑠𝑡2 𝑖𝑑. 𝑑𝑡𝑦𝑝𝑒 = 𝑣𝑎𝑟𝐿𝑖𝑠𝑡1 . 𝑑𝑡𝑦𝑝𝑒 𝑣𝑎𝑟𝐿𝑖𝑠𝑡2 . 𝑑𝑡𝑦𝑝𝑒 = 𝑣𝑎𝑟𝐿𝑖𝑠𝑡1 . 𝑑𝑡𝑦𝑝𝑒 𝑣𝑎𝑟𝐿𝑖𝑠𝑡 → 𝒊𝒅 𝑖𝑑. 𝑑𝑡𝑦𝑝𝑒 = 𝑣𝑎𝑟𝐿𝑖𝑠𝑡. 𝑑𝑡𝑦𝑝𝑒 ECUACIONES DE ATRIBUTOS Las ecuaciones de atributo se pueden exhibir en un árbol de análisis gramatical. Regla Gramatical Reglas Semánticas 𝑑𝑒𝑐𝑙 → 𝑡𝑦𝑝𝑒 𝑣𝑎𝑟𝐿𝑖𝑠𝑡; 𝑣𝑎𝑟𝐿𝑖𝑠𝑡. 𝑑𝑡𝑦𝑝𝑒 = 𝑡𝑦𝑝𝑒. 𝑑𝑡𝑦𝑝𝑒 𝑡𝑦𝑝𝑒 → 𝒊𝒏𝒕 𝑡𝑦𝑝𝑒. 𝑑𝑡𝑦𝑝𝑒 = 𝑖𝑛𝑡𝑒𝑔𝑒𝑟 𝑡𝑦𝑝𝑒 → 𝒇𝒍𝒐𝒂𝒕 𝑡𝑦𝑝𝑒. 𝑑𝑡𝑦𝑝𝑒 = 𝑟𝑒𝑎𝑙 𝑣𝑎𝑟𝐿𝑖𝑠𝑡1 → 𝒊𝒅, 𝑣𝑎𝑟𝐿𝑖𝑠𝑡2 𝑖𝑑. 𝑑𝑡𝑦𝑝𝑒 = 𝑣𝑎𝑟𝐿𝑖𝑠𝑡1 . 𝑑𝑡𝑦𝑝𝑒 𝑣𝑎𝑟𝐿𝑖𝑠𝑡2. 𝑑𝑡𝑦𝑝𝑒 = 𝑣𝑎𝑟𝐿𝑖𝑠𝑡1 . 𝑑𝑡𝑦𝑝𝑒 𝑣𝑎𝑟𝐿𝑖𝑠𝑡 → 𝒊𝒅 𝑖𝑑. 𝑑𝑡𝑦𝑝𝑒 = 𝑣𝑎𝑟𝐿𝑖𝑠𝑡. 𝑑𝑡𝑦𝑝𝑒 GRAFOS DE DEPENDENCIAS Un grafo de dependencias describe el flujo de información entre las instancias de atributos en un árbol de análisis sintáctico específico; una flecha de una instancia de atributo a otra significa que el valor de la primera se necesita para calcular la segunda. GRAFOS DE DEPENDENCIAS Algoritmo para su construcción: Para cada nodo 𝒏 en el árbol de análisis sintáctico hacer Para cada atributo 𝑎 del símbolo gramatical en el nodo 𝑛 hacer Construir un nodo en el grafo de dependencias para 𝑎; Para cada nodo 𝒏 en el árbol de análisis sintáctico hacer Para cada regla semántica 𝑏 ≔ 𝑓 𝑐1 , 𝑐2 , … , 𝑐𝑘 asociada con la producción utilizada en 𝑛 hacer Para cada 𝑖 ≔ 1 hasta k hacer Construir una arista desde el nodo 𝑐𝑖 hasta el nodo para 𝑏; GRAFOS DE DEPENDENCIAS Ahora veremos un ejemplo para ello utilizaremos la gramática anterior y la misma cadena de entrada: 𝑓𝑙𝑜𝑎𝑡 𝑥, 𝑦 ACCIONES SEMÁNTICAS • Define solo el valor de los atributos de los símbolos que aparecen en la producción. • Una acción semántica se ejecuta justo cuando se han reconocido los símbolos que se encuentran a su izquierda en el cuerpo de la producción. • La acción semántica se puede ver como una regla semántica asociada a un nuevo símbolo no terminal cuya única producción asociada 𝑀 → 𝑒 es ejecutada ESQUEMAS DE TRADUCCIÓN Esquema de traducción postfijo Esquema de traducción con acciones en medio de la producción ESQUEMAS DE TRADUCCIÓN Esquema de traducción postfijo Definición: un esquema de traducción postfijo es aquel en el cual las acciones semánticas se encuentran al final del cuerpo de producción Ejemplo Si en la regla 𝐴 → 𝛼𝛽 insertamos un fragmento de código: 𝐴 → 𝛼𝛽{𝑎𝑐𝑡𝑖𝑜𝑛} La acción semántica {𝑎𝑐𝑡𝑖𝑜𝑛} se ejecutará después de todas las acciones asociadas con el recorrido de los subárboles 𝛼 y 𝛽. ESQUEMAS DE TRADUCCIÓN Esquema de traducción con acciones en medio de la producción (infijo) Para aplicar estas acciones se deben realizar los siguientes pasos: • Recorrer en pre orden el árbol de análisis sintáctico ejecutando las acciones semánticas. • Adicionar nuevos hijos a cada símbolo de la parte izquierda como nuevos hijos que contienen a las acciones semánticas en el punto donde ellas se deben realizar. • Construir el árbol de análisis sintáctico ignorando las acciones semánticas. ESQUEMAS DE TRADUCCIÓN Ejemplo de INFIJO Si en la regla 𝐴 → 𝛼𝛽 insertamos un fragmento de código: 𝐴 → 𝛼 𝑎𝑐𝑡𝑖𝑜𝑛 𝛽 La acción {𝑎𝑐𝑡𝑖𝑜𝑛} se ejecutará después de todas las acciones asociadas con el recorrido del subárbol de 𝛼 y antes que todas las acciones asociadas con el recorrido del subárbol 𝛽. Otro ejemplo con el árbol de análisis sintáctico {action} OBJETIVOS DEL ANALIZADOR SEMÁNTICO La Fase de análisis semántico tiene por objetivo analizar los componentes del árbol de análisis sintáctico que representan en el programa con el fin de comprobar que se respetan ciertas reglas semánticas que dan un significado coherente a las construcciones del lenguaje, es decir, el analizador semántico va comprobando la coherencia semántica del árbol de análisis sintáctico según se va construyendo. Las responsabilidades del analizador semántico son: Registrar declaraciones Inferir tipos Comprobar tipos Comprobar corrección semántica CONCLUSIÓN Concluimos que el analizador semántico es tan importante como vital para un compilador, debido a que este analiza cada estructura sintáctica verificando la coherencia de la misma. Para esto emplea las estructuras: Árbol sintáctico Tabla de Símbolos Que son las más primordiales para este análisis.