Compiladores. Guía 7 1 Facultad: Ingeniería Escuela: Computación Asignatura: Compiladores Tema: Análisis Semántico Contenido En esta guía se desarrollará una tabla de símbolos y se asociará al analizador sintáctico de manera que se pueda manejar varios tipos de datos en un compilador, tomando como ejemplo base el compilador del lenguaje MUSIM/3. Objetivos Específicos Conocer las fases del análisis semántico y su relación con la tabla de símbolos y el analizador sintáctico. Enseñar la especificación semántica de un lenguaje de programación. Material y Equipo Guía de Laboratorio Nº 7. Computadora con programa “Dev C++”. Archivos de recurso o AnalizadorLexico.h o AnalizadorSintacticoEBNF.h Introducción Teórica Semántica Guía 3 La semántica en lingüística es el estudio del significado de una palabra tanto a nivel individual como en el contexto de una frase. Guía 4 Semántica en los lenguajes de programación es el conjunto de reglas que especifican el significado de cualquier sentencia, fía sintácticamente correcta y escrita en un determinado lenguaje. Por ejemplo en el lenguaje Pascal la sentencia: “suma := 27 / lado” es sintácticamente correcta, ya que a la izquierda del símbolo de asignación hay un identificador, y a 2 Compiladores. Guía 7 la derecha una expresión. Pero para que sea semánticamente correcta hay que comprobar: lado debe ser compatible con el operador "/" y con el operando 27. suma debe ser un tipo compatible con el resultado de la operación. Análisis Semántico El analizador semántico detecta la validez semántica de las sentencias aceptadas por el analizador sintáctico. El analizador semántico suele trabajar simultáneamente al analizador sintáctico y en estrecha cooperación. Se entiende por semántica como el conjunto de reglas que especifican el significado de cualquier sentencia sintácticamente correcta y escrita en un determinado lenguaje. Las rutinas semánticas deben realizar la evaluación de los atributos de las gramáticas siguiendo las reglas semánticas asociadas a cada producción de la gramática. Por ejemplo para una expresión como: ( A + B ) * ( C + D ) El analizador semántico debe determinar que acciones pueden realizar los operadores aritméticos (+,*) sobre las variables A,B,C y D. Así cuando el analizador sintáctico reconoce un operador, tal como " + " o " * ", llama a una rutina semántica que especifica la acción que puede llevar a cabo. Esta rutina puede comprobar que los dos operandos han sido declarados, y que tienen el mismo tipo. También puede comprobar si a los operandos se les ha asignado previamente algún valor. Procedimiento Semántica de MUSIM/3 Guía 3 La definición léxica y sintáctica de MUSIM/3 no es suficiente es necesario especificar su semántica. La semántica de este Guía 4 lenguaje está basada en las operaciones con sus tipos de datos. fía la especificación léxica y sintáctica de un lenguaje la Dada especificación semántica se puede orientar por diferentes Compiladores. Guía 7 3 caminos, aquí se ha elegido uno de ellos, una especificación semántica de comprobación estricta de tipos. Las promociones de tipo son muy restringidas en este caso se permite promocionar de entero a real. Los descensos de tipo están totalmente prohibidos, así por ejemplo está prohibido asignar directamente un real a un entero. La especificación semántica se puede resumir en: • Sistema de tipos: Se permiten tres tipos de datos: CHAR (carácter), INTEGER (entero) y FLOAT (real). Por defecto todos los operadores aritméticos siguen las leyes de composición interna, es decir las operaciones que tienen operandos del mismo tipo de datos, devuelven como resultado dicho tipos de datos, un caso especial es el operador potenciación: <expresión>1.tipo OPERADOR <expresión>2.tipo-> <expresión>3.tipo La sentencia de asignación sigue la misma ley de composición interna, es decir el tipo de la variable de la parte izquierda debe ser igual al tipo de la expresión de la parte derecha. <variable>.tipo = <expresión>.tipo • Conversiones de tipo por promoción: Tan solo se permite la promoción de tipo entero (INTEGER) a tipo real (FLOAT), es decir: <expresión>1.I OPERADOR <expresión>2.F <expresión>3.F <expresión>1.F OPERADOR <expresión>2.I <expresión>3.F También se permite sólo la promoción de entero (I) a real (F) en la sentencia de asignación: <variable>.F = <expresión>.I • Conversiones de tipo por descenso: MUSIM/3 las prohíbe totalmente. Por ejemplo no se permite pasar directamente de real a entero. A continuación se muestra un método de la clase Semántico que realiza comprobaciones de tipo de operadores aritméticos y del operador de asignación. Los tipos de datos que comprueba son entero (I), real (F) y carácter (C), devuelve el tipo del resultado, esto corresponde a la semántica de MUSIM/3 descrita anteriormente. 4 Compiladores. Guía 7 char Semantico::operar(char tipo1, char tipo2, char operador) { cout<<"\t\tSemantico: "<<tipo1<<" "<<operador<<" "<<tipo2<<endl; if (tipo1 == 'I' && tipo2 == 'I') if (operador == '/') return 'F'; else return 'I'; if (tipo1 == 'C' && tipo2 == 'C') return 'C'; if (tipo1 == 'F' && tipo2 == 'F') if (operador == '%') return 'I'; else return 'F'; if ( (tipo1 == 'C' && tipo2 != 'C') || (tipo2 == 'C' && tipo1 != 'C')) { cout<<"Error semántico: Tipos incompatibles: "<<tipo1<<" "<<tipo2<<" "<<operador; } if (tipo1 == 'I' && tipo2 == 'F') { switch (operador) { case '=': cout<<"Error semántico: Tipos incompatibles: "<<tipo1<<" "<<tipo2<<" "<<operador; case '^': return 'F'; default: return 'F'; } } if (tipo1 == 'F' && tipo2 == 'I') { return 'F'; } cout<<"Error semántico: Tipos incompatibles: "<<tipo1<<" "<<tipo2<<" "<<operador; } Un ejemplo de un programa con MUSIM/3 es: M{ I a; I b; F c; F d; Compiladores. Guía 7 5 R a; R b; c=a+b; d=a-b; W c; W d; }. Donde M=Main I=Integer F=Float C=Char R=Read W=Write Y los identificadores están formados de una sola letra. Tomando en cuenta, las consideraciones anteriores acerca del lenguaje MUSIM/3, implemente la clase Semántico asociada al lenguaje MUSIM/3, considerando el método presentado anteriormente para la comprobación estricta de tipos. Análisis de resultados Integre el analizador semántico con el analizador sintáctico del proyecto desarrollado en la guía 6 para el leguaje MUSIM/3. Utilice la definición sintáctica presentada en esa guía y tome en cuenta la definición semántica mostrada en el procedimiento. Investigación complementaria Investigue acerca de los bloques básicos de código, su relación con el código intermedio y el algoritmo de identificación de los bloques básicos de código dentro de una secuencia de instrucciones en lenguaje máquina. Bibliografía “Construcción de Compiladores. Principios y practica”, Kenneth C. Louden. “Compiladores. Principios técnicas y Herramientas”. Sethi Ullman. Pearson Education. 6 Compiladores. Guía 7 Hoja de cotejo: Guía 7: Análisis Semántico Docente: Tema: Presentación del programa 7 1 Máquina No: Máquina No: Alumno: Máquina No: GL: Alumno: Docente: GL: Docente: GL: Fecha: a EVALUACION % CONOCIMIENTO Del 20 al 30% APLICACIÓN DEL CONOCIMIENTO Del 40% al 60% 1-4 5-7 8-10 Conocimie nto deficient e de los fundament os teóricos Conocimiento y explicación incompleta de los fundamentos teóricos Conocimiento completo y explicación clara de los fundamentos teóricos No tiene actitud proactiva . Actitud propositiva y con propuestas no aplicables al contenido de la guía. Tiene actitud proactiva y sus propuestas son concretas. ACTITUD Del 15% al 30% TOTAL 100% Nota