El objetivo de esta sección es sugerir, de la manera más genérica posible, cómo se pueden solucionar los problemas relacionados con las construcciones más frecuentes que se utilizan en los lenguajes de programación de alto nivel.
2. GRAMATICA DE ATRIBUTOS PARA EL
ANALISIS SEMANTICA DE LOS LENGUAJES
DE PROGRAMACIÓN
1.-Declaración de identificadores:
El analizador morfológico debe proporcionar (como valor de su atributo),
el tipo de dato que se esa declarando.
El identificador debe comprobarse en la tabla de símbolos que no se
haya declarado previamente la misma variable.
3. 2.-Expresiones aritméticas:
El analizador semántico tiene que asegurar que se
satisfacen las restricciones de tipo de los
operandos que aparecen en las expresiones.
Una de las dificultades para la generación de
código para calcular expresiones es la
determinación del lugar donde se almacenarán los
resultados intermedios. El sistema ofrece un
conjunto limitado de registros
4. 3-Asignación de valor a los identificadores:
El analizador semántico tendrá que encargase de las siguientes tareas:
• El analizador morfológico propaga la información semántica del nombre del
identificador.
• Tras procesar el símbolo <identificador>, hay que consultar la tabla de
símbolos para comprobar que ya ha sido declarado y recuperar su información
semántica asociada, que incluye su tipo.
• Tras procesar el símbolo no terminal <expresión>, habrá que comprobar la
compatibilidad entre los tipos de la expresión y el identificador, para que la
asignación sea correcta.
5. 4.-Procedimientos:
Las comprobaciones que debe realizar el analizador semántico son:
• El tipo y el identificador se tratan de manera análoga a la de la
declaración de variables, excepto que se tiene que indicar en la tabla de
símbolos que el identificador representa una función
• La declaración de la lista de argumentos implica actualizar la información
que se conserva al respecto, que tiene que ser accesible en el momento
de la invocación del procedimiento.
6. El analizador semántico debe realizar las siguientes tareas:
• Tras procesar el símbolo <identificador>, cuyo nombre debe
propagarse, hay que comprobar en la tabla de símbolos que se ha
declarado un procedimiento con ese nombre, y recuperar la
información que describe la lista de sus argumentos.
• Tras procesar el paréntesis de cierre, se podrá completar la
verificación de la correspondencia del número, tipo y orden de los
argumentos de la invocación y los de la declaración.
7. Algunas herramientas para la generación de analizadores
semánticos
Un metacompilador es un compilador de compiladores. se trata de un
programa que acepta como entrada la descripción de un lenguaje
(gramática) y produce el compilador o intérprete de dicho lenguaje, no
existen metacompiladores completos, pero sí parciales que permiten
añadir código para completar el resto del compilador.
Ejemplos de metacompiladores son: LEX, YACC, FLEX, BISON, JAVACC,
JLEX, CUP, ETC.
8. Estructura del fichero fuente de yacc
• La sección de definiciones.
• La sección de reglas.
• La sección de código de usuario.
9. Sección de definiciones
Declaraciones propias de yacc
Se especifican aspectos generales, mediante el uso de directivas.
• Directiva %union
• Directiva %type
• Directiva %token
• Directiva %start
10. Sección de reglas
Existen tres formas para escribir los símbolos terminales en una gramática
definida por Bison, estas son:
Token designado, se define en esta sección como si se tratara de un
identificador
Token carácter, se escriben en la gramática directamente utilizando la sintaxis
de C para los caracteres
Token cadena, se define cono una cadena en C es decir entre comillas dobles,
ademas este tipo de tokens no funcionan en Yacc
11. Sección de reglas
Dentro de la acción semántica se escriben instrucciones en el lenguaje C.
En ellas, pueden aparecer los símbolos de la tabla 5., que tienen
significado especial para yacc, y que permiten acceder a la información
semántica de la gramática. Se supone, en la tabla, que se está
describiendo la regla X:Y1 Y2...Yn).
12. Sección de funciones de usuario
yyparse: Esta función realiza el análisis sintáctico de los programas escritos
en el lenguaje que se especificó en la gramática.
Yylex: Esta función se encarga de partir el programa ingresado en
unidades léxicas elementales (tokens) y se los entrega al yyparse para
que él determine la regla que le corresponde.