Está en la página 1de 16

DIRECCIÓN ACADÉMICA

Guía estructurada de evaluación


FO-205P11000-13
División: (1) Ingeniería en Sistemas Computacionales
Docente: (2) M.T.I Brian Antonio Mejía Díaz
Asignatura: (3) Lenguajes y autómatas II
Nombre y número de
Zamudio Franco Luis Jesús 193107070 Grupo: (6) 362M
control: (5)

Evidencia de aprendizaje: (7) Investigación Documental

Criterios de evaluación:

CRITERIOS
SI NO OBSERVACIONES
DE EVALUACIÓN

• Contiene portada con las especificaciones


(Nombre del Docente, Nombre del Estudiante, # de
control, grupo y tema a investigar).

• Contiene introducción a 1 cuartilla.


• Contiene las tablas correspondientes a:
➢ Índice de Contenido
➢ Índice de Imágenes
Estructura del ➢ Índice de Tablas
Respectivamente y en caso de existir.
Documento
• Contiene desarrollo parafraseado y en ½ cuartilla,
por tema.
• Contiene conclusión de acuerdo con las
características propias de hacerlo en inglés y con
sus propias palabras, de acuerdo con el nivel que
presente sin utilizar ninguna clase de traductor a ½
cuartilla.
• Referencias Bibliográficas (al menos 2 libros)

• Faltas de Ortografía.

• Márgenes Definidos 2.5 por lado.

• Interlineado a 1.5 y justificado.


Características • Los títulos y subtítulos se ven propiamente
del Documento resaltados y diferenciados el cuerpo del
documento.
• Las referencias se encuentran en formato
OXFORD.
• Entrega en tiempo y forma de acuerdo con las
indicaciones del docente.

Puntuación 1ª oportunidad 2ª oportunidad


Alcanzada (10)
División en Ingeniería en Sistemas Computacionales

Investigación documental

Asignatura:
Lenguajes y Autómatas I

Elaborado por:
Zamudio Franco Luis Jesús
193107070
Docente:
M.T.I Brian Antonio Mejía Díaz

Grupo:
362-M

Tema:
ANALISIS SEMANTICO.
Introducción.
El análisis semántico se compone de un conjunto de rutinas independientes, llamadas
por los analizadores morfológico y sintáctico.

El análisis semántico utiliza como entrada el árbol sintáctico detectado por el análisis
sintáctico para comprobar restricciones de tipo y otras limitaciones semánticas y
preparar la generación de código.

En compiladores de un solo paso, las llamadas a las rutinas semánticas se realizan


directamente desde el analizador sintáctico y son dichas rutinas las que llaman al
generador de código. El instrumento más utilizado para conseguirlo es la gramática de
atributos.

En compiladores de dos o más pasos, el análisis semántico se realiza


independientemente de la generación de código, pasándose información a través de
un archivo intermedio, que normalmente contiene información sobre el árbol sintáctico
en forma linealizada (para facilitar su manejo y hacer posible su almacenamiento en
memoria auxiliar).

En cualquier caso, las rutinas semánticas suelen hacer uso de una pila (la pila
semántica) que contiene la información semántica asociada a los operandos (y a veces
a los operadores) en forma de registros semánticos.
1.1 Arboles de expresiones.

Árbol de expresiones o árbol semántico. Es una estructura jerárquica en la cual se


registran las operaciones que realiza el programa fuente.

En cada una de las ramas del árbol se registra el valor o significado que este debe
tener y el análisis se encarga de terminar cuál de los valores registrado en las ramas
es aplicable.

Los árboles de expresiones representan el código de nivel del lenguaje en forma de


datos. Los datos se almacenan en una estructura con forma de árbol.

Cada nodo del árbol de expresión representa una expresión.

Ilustración 1. Ejemplo de árbol de expresión.

• Cualquier hoja esta etiquetada solo con un operando.


• Cualquier nodo interior n esta etiquetado por un operador.
• Nodo raíz es un operador.
1.1.1 Construcción de un árbol de expresión

Algoritmo.

Mientras carácter diferente de nulo. Leer carácter de la lista Si es paréntesis pasar al


siguiente carácter. Crear un nodo nuevo que contenga ese carácter.

Operando

Si el árbol está vacío hacer raíz a nuevo, si no recorrer el árbol por la derecha hasta
llegar a un nodo con hojas, si la hoja izquierda, no está etiquetada colocar operando,
si no colocarlo en la hoja derecha.

Operador.

Si la raíz es un operando, insertar nuevo en ese nodo, y convertir el operando en el hijo


izquierdo, si no si hay un paréntesis abierto insertar nuevo en la última hoja derecha y
colocar operando como hijo izquierdo. Si el carácter anterior es paréntesis izquierdo si
el siguiente carácter es paréntesis derecho si solo hay un operador en el árbol nuevo
se convierte en raíz, si no se inserta en el último nodo derecho, y el nodo se convierte
en hijo izquierdo. Si no se cumple ninguna de las condiciones anteriores si la raíz es de
igual prioridad o menor prioridad convertir la raíz en el hijo izq. de nuevo si no la
prioridad del nodo raíz es mayor al de nuevo insertar nuevo como hijo derecho y
colocar el nodo reemplazado como hijo izquierdo.
1.1.2 Recorridos en árboles

Recorrido en Preorden: En este tipo de recorrido se realiza cierta acción (quizás


simplemente imprimir por pantalla el valor de la clave de ese nodo) sobre el nodo actual
y posteriormente se trata el hijo izquierdo y cuando se haya concluido, el hijo derecho.

Recorrido en Postorden: En este caso se trata primero el hijo izquierdo, después el


derecho y por último el nodo actual.

Recorrido en Inorden: En este caso se trata primero el hijo izquierdo, después el nodo
actual y por último el hijo derecho.

Recorridos en amplitud (o por niveles): En este caso el recorrido se realiza en orden


por los distintos niveles del árbol. Así, se comenzaría tratando el nivel 1, que sólo
contiene el nodo raíz, seguidamente el nivel 2, el 3 y así sucesivamente. En los árboles
de expresión, la sucesión del preorden de etiquetas nos da lo que se conoce como la
forma prefijo de una expresión.

Análogamente, la sucesión postorden de las etiquetas de un árbol expresión nos da lo


que se conoce como la representación postfija de una expresión. Finalmente, el
inorden de una expresión en un árbol de expresión nos da la expresión infijo en sí
misma, pero sin paréntesis.
1.2 Acciones semánticas de un analizador sintáctico.
Es la fase del analizador que se encarga de chequear el texto de entrada en base a
una gramática dada. Y en caso de que el programa de entrada sea válido, suministra
el árbol sintáctico que lo reconoce.

En teoría, se supone que la salida del analizador sintáctico es alguna representación


del árbol sintáctico que reconoce la secuencia de Token suministrada por el analizador
léxico.

En la práctica, el analizador sintáctico también hace:

• Acceder a la tabla de símbolos (para hacer parte del trabajo del analizador
semántico).
• Chequeo de tipos (del analizador semántico).
• Generar código intermedio.
• Generar errores cuando se producen.
• En definitiva, realiza casi todas las operaciones de la compilación. Este método
de trabajo da lugar a los métodos de compilación dirigidos por sintaxis.

Manejo de errores sintácticos

Los errores sintácticos son dados por una expresión aritmética o paréntesis no
equilibrados.

El manejo de errores de sintaxis es el más complicado desde el punto de vista de la


creación de compiladores. Nos interesa que cuando el compilador encuentre un error,
se recupere y siga buscando errores. Por lo tanto, el manejador de errores de un
analizador sintáctico tiene como objetivos:

• Indicar los errores de forma clara y precisa. Aclarar el tipo de error y su


localización.
• Recuperarse del error, para poder seguir examinando la entrada.
• No ralentizar significativamente la compilación
Tipo de gramática que acepta un analizador sintáctico

Nosotros nos centraremos en el análisis sintáctico para lenguajes basados en


gramáticas formales, ya que de otra forma se hace muy difícil la comprensión del
compilador, y se pueden corregir, quizás más fácilmente, errores de muy difícil
localización, como es la ambigüedad en el reconocimiento de ciertas sentencias.

La gramática que acepta el analizador sintáctico es una gramática de contexto libre:

Gramática: G (N, T, P, S)

N = No terminales.
T = Terminales.
P = Reglas de Producción.
S = Axioma Inicial.

1.3 Comprobaciones de tipos en expresiones.


La labor de comprobación de tipos consiste en conferir a las construcciones
sintácticas del lenguaje la semántica de tipificación y en realizar todo tipo de
comprobaciones de dicha índole. Por su naturaleza, sin embargo, ésta se encuentra
repartida entre la fase de análisis semántico y la generación de código intermedio.

➢ Comprobaciones estáticas
Las comprobaciones estáticas recogen el compendio de todas aquellas tareas de
carácter semántico que, por su naturaleza, pueden ser realizadas directamente
durante la fase de compilación mediante el uso de los artefactos y mecanismos propios
de dicha fase. Este tipo de comprobaciones son beneficiosas puesto que confieren
seguridad a la ejecución del programa.
Características
- Diferente de la dinámica en runtime.
- Ejemplo: comprobación de tipos, flujo de control, unicidad.

➢ Comprobaciones dinámicas.

Las comprobaciones dinámicas son aquellas que no se realizan durante la fase de


compilación y se delegan al momento de la ejecución del programa. Ello requiere
generar código ejecutable específicamente diseñado para realizar tales
comprobaciones. Los lenguajes con una carga excesiva de comprobaciones
dinámicas generan programas más largos, lentos e inseguros en ejecución.

Verificación de tipos.
Comprueba la compatibilidad de tipos de todas las expresiones del código fuente
recuperando la información durante la gestión de declaraciones. Además se asegura
de que no existe en el programa ninguna referencia a ningún símbolo no declarado.

Inferencia de tipos
En lenguajes sin tipificación de variables o con sobrecarga se aplican tareas de
inferencia de tipos en el nivel gramatical de las expresiones para resolver el tipo de
datos de la expresión resultante en función del contexto de evaluación.

1.4 Pila semántica en un analizador sintáctico.


Las pilas y colas son estructuras de datos que se utilizan generalmente para simplificar
ciertas operaciones de programación. Estas estructuras pueden implementarse
mediante arrays o listas enlazadas.

Pila: colección de datos a los cuales se les puede acceder mediante un extremo,
que se conoce generalmente como tope. Las pilas tienen dos operaciones básicas:
➢ Push (para introducir un elemento)
➢ Pop (para extraer un elemento)

Ilustración 2. Pila semántica en un analizador sintáctico.

Sus características fundamentales es que al extraer se obtiene siempre el último


elemento que acabe de insertarse. Por esta razón también se conoce como
estructuras de datos LIFO, una posible implementación mediante listas enlazadas seria
insertando y extrayendo siempre por el principio de la lista.

Las pilas se utilizan en muchas aplicaciones que utilizamos con frecuencia. Las pilas y
colas son estructuras de datos que se utilizan generalmente para simplificar ciertas
operaciones de programación. Estas estructuras pueden implementarse mediante
arrays o listas enlazadas.

Un analizador sintáctico es un autómata de pila que reconoce la estructura de una


cadena de componentes léxicos.

En general, el analizador sintáctico inicializa el compilador y para cada símbolo de


entrada llama al analizador morfológico y proporciona el siguiente símbolo de entrada.
1.4.1 Ventajas.
➢ 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
límite para la integración total del sistema.
➢ Se necesita una memoria auxiliar que nos permita guardar los datos para poder
hacer la comparación.

Ilustración 3. Ejemplo de pila.

Su objetivo teórico es construir un árbol de análisis sintáctico, este raramente se


construye como tal, sino que las rutinas semánticas integradas van generando el árbol
de Sintaxis abstracta. Se especifica mediante una gramática libre de contexto.

El análisis 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.
El análisis sintáctico es la fase en la que se trata de determinar el tipo de los resultados
intermedios, comprobar que los argumentos que tiene un operador pertenecen al
conjunto de los operadores posibles, y si son compatibles entre sí, etc.

1.5 Manejo de errores semánticos.


Un error semántico se produce cuando la sintaxis 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. Hablando en términos
coloquiales, puede hacer que el equipo se quede "colgado".

Un compilador es un sistema que en la mayoría de los casos tiene que manejar una
entrada incorrecta. Sobre todo en las primeras etapas de la creación de un programa,
es probable que el compilador se utilizará para efectuar las características
que debería proporcionar un buen sistema de edición dirigido por la sintaxis, es decir,
para determinar si las variables han sido declaradas antes de usarla, o si faltan
corchetes o algo así. Por lo tanto, el manejo de errores es parte importante de un
compilador y el escritor del compilador siempre debe tener esto presente durante su
diseño. Hay que señalar que los posibles errores ya deben estar considerados al
diseñar un lenguaje de programación. Por ejemplo, considerar si cada proposición
del lenguaje de programación comienza con una palabra clave diferente (excepto la
proposición de asignación, por supuesto). Sin embargo, es indispensable
lo siguiente:
1. El compilador debe ser capaz de detectar errores en la entrada.

2. El compilador debe recuperarse de los errores sin perder demasiada


información.

3. Y sobre todo, el compilador debe producir un mensaje de error que permita al


programador encontrar y corregir fácilmente los elementos(sintácticamente)
incorrectos de su programa.

1.5.1 Clasificación de Errores.


Durante un proceso de resolución de problemas existen varias formas en que
pueden surgir errores, las cuales se reflejan en el código fuente del programa. Desde
el punto de vista del compilador, los errores se pueden dividir en dos
categorías:

1. Errores visibles y Errores invisibles.

Los errores invisibles en un programa son aquellos que no puede detectar el


compilador, ya que no son el resultado de un uso incorrecto del lenguaje
de programación, sino de decisiones erróneas durante el proceso de especificación o
de la mala formulación de algoritmos. Por ejemplo, si se escribe:

a : = b + c ; en lugar de a : = b * c ;

El error no podrá ser detectado por el compilador ni por el sistema de ejecución. Estos
errores lógicos no afectan la validez del programa en cuanto a su corrección sintáctica.
Son objeto de técnicas formales de verificación de programas que no se consideran
aquí. Para conocer más sobre la verificación de programas, consulte, por ejemplo,
[LOEC 87].
Los errores visibles, a diferencia de los errores lógico, pueden ser detectados por el
compilador o al menos por el sistema de ejecución. Estos errores se pueden
caracterizar de la siguiente manera:1. Errores de ortografía y2. Errores que ocurren
por omitir requisitos formales del lenguaje de programación.

Estos errores se presentará porque los programadores no tienen el cuidado


suficiente al programador. Los errores del segundo tipo también pueden ocurrir porque
el programador no comprende a la perfección el lenguaje que se utiliza o porque suele
escribir sus programas en otro lenguaje y, por tanto, emplea las construcciones de
dicho lenguaje (estos problemas pueden presentarse al usar a la vez lenguajes de
programación como PASCAL y MODULA-2, por ejemplo)

1. Errores de ortografía

2. Errores que ocurren por omitir requisitos formales del lenguaje de programación.

Conclusión.
It consists of a set of independent routines, called by the morphological and parsing
parsers.

Semantic analysis uses the syntax tree detected by parsing as input to check for type
constraints and other semantic constraints and prepare for code generation.

In single-pass compilers, calls to semantic routines are made directly from the parser,
and it is the semantic routines that call the code generator. The most used instrument
to achieve this is the attribute grammar.

In two or more pass compilers, semantic analysis is performed independently of code


generation, passing information through an intermediate file, which normally contains
information about the syntax tree in linearized form (to facilitate handling and storage).
in auxiliary memory).
In any case, semantic routines usually make use of a stack (the semantic stack) that
contains the semantic information associated with the operands (and sometimes the
operators) in the form of semantic registers.

Referencias bibliograficas.
1, L. and perfil, V., 2021. Lenguajes y autómatas II. [online]
Lenguajesyautomatas1998.blogspot.com. Available at:
<https://lenguajesyautomatas1998.blogspot.com/2019/04/unidad-4-4.html>
[Accessed 21 October 2021].

Hoffman, J., 2021. Analisis Semantico. [online] Cs.famaf.unc.edu.ar. Available at:


<https://cs.famaf.unc.edu.ar/~hoffmann/md19/10.html> [Accessed 23 September
2021].

También podría gustarte