2. El análisis léxico es la primera fase de un compilador
consistente en un programa que recibe como entrada el
código fuente de otro programa (secuencia de
caracteres) y produce una salida compuesta de tokens
(componentes léxicos) o símbolos. Estos tokens sirven
para una posterior etapa del proceso de traducción,
siendo la entrada para el analizador sintáctico .
3. El analisis sintactico es nuestra segunda etapa para
generar nuestro compilador.
El analizador sintáctico obtiene una cadena de
componentes léxicos del analizador léxico, y comprueba
si la cadena puede ser generada por la gramática del
programa fuente.
4. La fase de análisis semántico revisa el programa
fuente para tratar de encontrar errores semánticos y
reúne la información sobre los tipos para la fase
posterior de generación de código. En ella se utiliza la
estructura jerárquica determinada por la fase de análisis
sintáctico para identificar los operadores y operandos de
expresiones y proposiciones.
5. a) manejo de localidades temporales de memoria
(buffers)
El uso de localidades temporales de memoria es para
agilizar el tiempo de compilación, el manejo de este es
por medio de estructuras de datos utilizando memoria
dinámica, como se vio en materias anteriores como
estructura de datos, usando esta implementación de
diferentes formas que pueden clasificarse de acuerdo a
su argumento de búsqueda.
6. b) creación de tablas de símbolos
Las tablas de símbolos (también llamadas tablas de
identificadores y tablas de nombres), realizan dos
importantes funciones en el proceso de traducción:
verificar que la semántica sea correcta y ayudar en la
generación apropiada de código. Ambas funciones se
realizan insertando o recuperando desde la tabla de
símbolos los atributos de las variables usadas en el
programa fuente. Estos atributos, tales como: el
nombre, tipo, dirección de almacenamiento y dimensión de
una variable, usualmente se encuentran explícitamente en
las declaraciones o más implícitamente a través del
contexto en que aparecen los nombres de variables en el
programa.
7. Una de las estructuras de datos que se encuentran
relacionadas con las fases del proceso de compilación
es la tabla de símbolos, la cual tiene como propósito
registrar información que se comparte entre varias
etapas y que permite administrar los recursos asociados
a las entidades que manipulará el programa. La tabla de
símbolos tiene típicamente la siguiente estructura:
8. en donde podemos apreciar la designación de la
entidad y su token -derivados del análisis de léxico-
asi como una serie de atributos (tipo de
dato, dirección en memoria) que emanan de otras
fases (análisis gramatical y semántico). Las
consultas a la tabla de símbolos se realizan por
medio del lexema con que se designa a la entidad.
9. c) Manejo de errores léxicos
El compilador tiene que::
Reportar clara y exactamente la presencia de errores
Recuperarse de cada error lo suficientemente rápido para poder
detectar errores subsiguientes:
Tratar de evitar mensajes falsos de error
Un error que produce un token erroneo
Errores léxicos posibles
Un token o componente léxico es una cadena de caracteres que
tiene un significado coherente en cierto lenguaje de
programación. Ejemplos de tokens, podrían ser palabras clave
(if, while, int), identificadores, números, signos, o un operador de
varios caracteres. Son los elementos más básicos sobre los
cuales se desarrolla toda traducción de un programa, surgen en
la primera fase, llamada análisis léxico.
10. a) Diagramas de sintaxis
Es otra forma (al igual que los árboles de derivación) de
especificar gramáticas del tipo 2.
• La característica de este esquema es que permite ver las
derivaciones al instante de que ocurren.
11.
12. b) Precedencia de operadores
La precedencia de operadores es de vital importancia en el
proceso de análisis sintáctico ya que nos representará la
forma en que debe construirse el árbol de derivación.
En aritmética existen prioridades, por ejemplo: * y / tienen
preferencia sobre + y -.
() indican la máxima prioridad.
La forma de evaluación depende de cómo se construyan
los operadores, ya sea en infijo, postfijo o prefijo.
Las operaciones se realizan de abajo hacia arriba.
13. c) Analizador sintáctico: analizador descendente
(LL), analizador ascendente (LR, LALR).
Analizador descendente (LL). Existen diferentes métodos
de análisis sintáctico. La mayoría caen en una de dos
categorías: ascendentes y descendentes.
Los ascendentes construyen el árbol desde las hojas hacia
la raíz. Los descendentes lo hacen en modo inverso.
14. Derivación izquierda:
S->aA->aaBbC->aabbC->aabbc (1234)
S->aA->aaBbC->aaBbc->aabbc (3421)
LL(k) traductores “top-down”
Un análisis anticipado de k caracteres
S->aS|cA
• A->bA|cB|ε
• B->cB|a| ε
• Construir cadena acbb
• S->aS o S->cA; al anticipar el primer
símbolo
15.
16. Analizador ascendente (LR, LALR)
Algunos problemas no se pueden resolver de forma
descendente ya que no están fácil quitar la ambigüedad.
En algunos casos es más fácil demostrar algo ya existente.
Generalmente los analizadores sintácticos LR(k) son del
tipo “bottom-up”
17. El analizador trata de reducir la cadena de entrada w al
símbolo inicial S. En un proceso que recorre el árbol de
derivación en sentido inverso que se llama reducción.
No sólo es necesario una gramática que no presente
ambigüedades sino que también tenga el valor de k más
pequeño.
18.
19. d) Administración de tablas de símbolos.
La tabla de símbolos se crea durante la fase de análisis
léxico a través de los componentes léxicos, pero en el
proceso de análisis sintáctico sufren algunas
modificaciones.
Generalmente se agregan valores de tipo y significado
para el análisis sintáctico.
20. e) Manejo de errores sintácticos y su recuperación.
Si los traductores tuvieran que procesar programas
correctas el proceso de implantación se simplificaría
mucho.
¿Cómo debe de responder un compilador de pascal a un
código Fortran?
Ningún método de recuperación de errores resuelve todos
los problemas
21. a) Verificación de tipos en expresiones.
La verificación de los tipos de datos se hace asignando el valor
de tipo de cada una de los componentes léxicos.
Estos valores se comparan para verificar que los tipos de datos
coincidad y sean congruentes, de lo contrario no se pueden
realizar los cálculos.
Sistema Semantico.
Reglas de un lenguaje que permiten saignar tipos de las
disteintas partes de un programa y verificar su correccion.
Formado por las definiciones y reglas que permiten comprobar
el dominio de un identificador, y en que contextos puede ser
usado.
Cada lenguaje tiene un sistema de tipos propio, aunque puede
variar de una a otra implementación.
La comprobación de tipos es parte del análisis semantico.
22. b) Conversión de tipos
Las conversiones nos permiten que una expresión de un
tipo sea tratada como una expresión de otro tipo, dichas
conversiones pueden ser implícitas o explícitas, por
ejemplo la conversión de un tipo int a long es implícita, sin
embargo la conversión de un tipo long a un tipo int es
explícita, esto debido a que un int puede ser expresado en
formato long sin que haya perdida de precisión en la
operación, sin embargo si intentamos convertir un numero
long a int puede haber perdida de precisión y se necesita
una conversión explícita
23. c) Acciones agregadas en un analizador sintáctico
descendente (top-down).
En un parser recursivo-descendente, el código de las acciones
semánticas es mezclado dentro del flujo de control de las acciones del
parser. En un parser especificado en javaCC, las acciones semánticas
son fragmentos de código de programa en java unido a las
producciones gramaticales.
Cada símbolo terminal y noterminal puede asociarse con su propio tipo
de valor semántico.
Los otros tokens no necesitarían tener un valor. Por otra parte el tipo
asociado a un token debe por supuesto coincidir con el tipo de token
que el scanner retorne.
Para una regla ABCD, la acción semántica debe retornar un valor
cuyo tipo es el asociado al noterminal A. Pero puede construir este
valor de los valores asociados a los terminales y noterminales B, C, D.
24. d) Pila semántica en un analizador sintáctico
ascendente (bottom-up).
El diseño ascendente se refiere a la identificación de
aquellos procesos que necesitan computarizarse con
forme vayan apareciendo, su análisis como sistema y su
codificación, o bien, la adquisición de paquetes de software
para satisfacer el problema inmediato.
Los problemas de integración entre los subsistemas son
sumamente costosos y muchos de ellos no se solucionan
hasta que la programación alcanza la fecha limite para la
integración total del sistema.
25. e) Administración de la tabla de símbolos.
Una tabla de símbolos es una estructura de datos que usa el
proceso de traducción de un lenguaje de programación, por un
compilador o un intérprete, donde cada símbolo en el código
fuente de un programa está asociado con información tal como
la ubicación, el tipo de datos y el ámbito de cada
variable, constante o procedimiento.
Los símbolos en la tabla de símbolos pueden referirse a
constantes, a funciones o a tipos de datos en el código fuente
de un programa.
El administrador de la tabla de símbolos se encarga de manejar
los accesos a la tabla de símbolos, en cada una de las etapas
de compilación de un programa.
26. f) Manejo de errores semánticos.
Los errores semánticos son más sutiles. Un error
semántico se produce cuando la sintáxis del código es
correcta, pero la semántica o significado no es el que se
pretendía. La construcción obedece las reglas del
lenguaje, y por ello el compilador o intérprete no detectan
los errores semánticos. Los compiladores e intérpretes
sólo se ocupan de la estructura del código que se
escribe, y no de su significado. Un error semántico puede
hacer que el programa termine de forma anormal, con o sin
un mensaje de error.