Lenguajes y Autómatas Unidad 1

21
2015 Alumno: Christian René Guerrero Hernández. N° de control: 12380909. Tutor: Ing. Fidel Ángel Martínez Salazar Unidad Académica: San Fernando. RESUMEN UNIDAD 1 LENGUAJES Y AUTOMATAS 2 Instituto Tecnológico de Ciudad Victoria Educación a

description

LYA 2

Transcript of Lenguajes y Autómatas Unidad 1

Page 1: Lenguajes y Autómatas Unidad 1

2015

Alumno: Christian René Guerrero Hernández.N° de control: 12380909. Tutor: Ing. Fidel Ángel Martínez SalazarUnidad Académica: San Fernando.

RESUMEN UNIDAD 1

ASESOR:

Ing. Miguel Ángel Macías García

LENGUAJES Y AUTOMATAS 2

Instituto Tecnológico de Ciudad Victoria

Educación a Distancia

Page 2: Lenguajes y Autómatas Unidad 1

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 lineal, para facilitar su manejo y

hacer posible su almacenamiento en memoria auxiliar.Las rutinas semánticas suelen

hacer uso de una pila (pila semántica) que contiene la información semántica asociada a

los operandos en forma de registros semánticos.

FUNCIONAMIENTO.

Recibe como entrada el árbol de derivación del programa añade al árbol de derivación

una serie de anotaciones, que permiten determinar la corrección semántica del

programa y preparar la generación de código La salida que genera es un árbol de

derivación con anotaciones semánticas.

FUNCIONES PRINCIPALES.

Identificar cada tipo de instrucción y sus componentes

Completar la Tabla de Símbolos

Realizar distintas comprobaciones y validaciones:

· Comprobaciones de tipos.

· Comprobaciones del flujo de control.

· Comprobaciones de unicidad.

· Comprobaciones de emparejamiento.

El Analizador Semántico finaliza la fase de Análisis del compilador y comienza la fase de

Síntesis, en la cual se comienza a generar el código objeto.

Page 3: Lenguajes y Autómatas Unidad 1

La especificación de la semántica puede realizarse de dos formas:

Lenguaje natural

Especificación formal: Semántica Operacional, semántica denotacional, semántica

Axiomática, Gramáticas con Atributos.

Este análisis es más difícil de formalizar, determina el tipo de los resultados intermedios,

comprobar que los argumentos que tienen un operador pertenecen al conjunto de

operadores posible, y si son compatibles entre sí.

ÁRBOLES DE EXPRESIÓN.

Page 4: Lenguajes y Autómatas Unidad 1

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, por ejemplo, una llamada al método o una

operación binaria, como x < y.

En la ilustración siguiente se muestra un ejemplo de una expresión y su representación

en forma de un árbol de expresión. Las diferentes partes de la expresión tienen un color

distinto para hacerlas coincidir con el nodo correspondiente del árbol de expresión.

También se muestran los diferentes tipos de los nodos del árbol de expresión.

REGLAS PARA LA CONSTRUCCION DE ARBOLES DE EXPRESION

Para construir el árbol de expresiones que represente la expresión matemática es

necesario construir primero la expresión pero en la notación polaca correspondiente y a

partir de esta es que se construye el árbol. El algoritmo usado para transformar una

expresión infija a prefija es explicado a continuación.

Sea A una expresión infija cualquiera, formada por operadores, paréntesis (izquierdos y

derechos) y operandos, también se usará una pila para los operadores. El procedimiento

seguido es el siguiente:

Se lee un elemento de A, si este es un operador o un paréntesis izquierdo, entonces se

actúa la regla 1 y si es un operando se envía la expresión de notación polaca. Si el

elemento leído de A es un paréntesis derecho, se desapilarán elementos de la pila de

operadores hasta encontrar el correspondiente paréntesis izquierdo. Cada elemento

desapilado pasa a formar parte de la notación polaca, excepto los paréntesis. Cuando no

queden elementos en A, se desipilan operadores de la pila, hasta que esta quede vacía.

Regla 1:

Existe un orden de prioridad para los operadores, que de menor a mayor es el siguiente:

suma (+) y resta (-), multiplicación (*) y división (/), exponenciación (^), operadores

unarios. El paréntesis izquierdo lo trataremos como un operador (aunque no lo es) cuyo

orden de prioridad es el mayor de todos cuando se quiera apilar y el menor de todos

cuando esté en la cima de la pila.

Cuando se intente apilar algún operador se hará lo siguiente: si es un operador unario

entonces se apila, si es un operador binario, se comparará su prioridad con el último

insertado en la pila (el de la cima), si su prioridad es mayor, entonces se apilará. Si

Page 5: Lenguajes y Autómatas Unidad 1

ocurre lo contrario (su prioridad es menor o igual) entonces el operador de la cima de la

pila se desapilará y pasará a formar parte de la notación polaca. Se volverá a intentar

apilar el operador siguiendo la misma regla, hasta que se pueda apilar, si la pila queda

vacía también se apila. El paréntesis izquierdo siempre se apilará y no podrá ser

desapilado por ningún operador y por tanto no formará parte de la notación polaca

inversa.

El siguiente ejemplo, ayudará a entender mejor lo dicho anteriormente. Sea la siguiente

expresión infija: 2^sin(y+x)–ln(x).

En la siguiente tabla se muestra paso a paso la conversión a notación postfija. Se usa el

color rojo para señalar los casos en que es necesario desapilar operadores de la pila.

CONSTRUCCIÓN DEL ÁRBOL BINARIO DE EXPRESIONES

Una vez obtenida la expresión en notación postfija, se puede evaluar mediante el uso

nuevamente de una pila. Sin embargo, en nuestro caso se trabaja con un árbol binario

de expresiones, así que lo que se hace es construir el árbol. El algoritmo usado para

construir el árbol no usa como tal la expresión postfija ya conformada, sino que el árbol

se va construyendo usando las mismas reglas con las que se construye la notación

postfija, una pila para los operadores y otra para los nodos del árbol, ambas no son

necesitadas al terminar el árbol. El algoritmo es el siguiente:

Se siguen las mismas reglas expuestas anteriormente usando la pila de operadores,

pero cuando se encuentra un operando o un operador es desapilado, entonces se crea

el nodo correspondiente y se actúa según la regla II. Al finalizar el algoritmo solo debe

quedar un nodo apilado en la pila de nodos, el que constituye el nodo raíz de nuestro

árbol de expresiones.

Regla 2.

Si el nodo corresponde a un operando, entonces se apila. Si el nodo corresponde a una

operador unario entonces se desapilan un nodo de la pila de nodos y es enlazado a la

Page 6: Lenguajes y Autómatas Unidad 1

rama izquierda del nodo correspondiente al operador unario y este último es apilado. Si

el nodo corresponde a un operador binario entonces dos nodos son desapilados de la

pila de nodos, el primero es enlazado a la rama derecha del nodo binario y el segundo a

la rama izquierda, nuevamente este nodo es apilado.

En el siguiente ejemplo se usa la misma expresión infija anterior (2^sen(y+x) – ln (x))

para ilustrar el procedimiento para construir el árbol:

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 subárbol izquierdo y cuando se haya concluido, el subárbol derecho. Otra forma para

entender el recorrido con este método seria seguir el orden: nodo raíz, nodo izquierda,

nodo derecha.

Un recorrido general del árbol en orden previo Preorden produce la cadena

q+ABsenC*X+YZ. Es versión prefija. El recorrido general de orden produce una cadena

AB+CsenXYZ+*q, la cual es la versión posfija de la expresión.

Ejemplo de árbol con etiquetas: el nodo 2 tiene el operador + como etiqueta y sus hijos

izquierdo y derecho representan las expresiones a y b. por tanto, n2 representa (a)+(b) o

Page 7: Lenguajes y Autómatas Unidad 1

más simple, a+b. El nodo n1 representa (a+b)*(a+c) puesto que * es la etiqueta de n1, y

a+b y a+c son los correspondientes expresiones representadas por n2 y n3.

Page 8: Lenguajes y Autómatas Unidad 1

ACCIONES SEMÁNTICAS DE UN ANALIZADOR SINTÁCTICO.

Page 9: Lenguajes y Autómatas Unidad 1

El análisis semántico se realiza después del sintáctico y es más difícil de formalizarque

éste. Se trata de determinar el tipo de los resultados intermedios, comprobar quelos

argumentos que tiene un operador pertenecen al conjunto de los operadoresposibles, y

si son compatibles entre sí, comprobará que el significado de loque se va leyendo es

válido.El análisis semántico utiliza como entrada el árbol sintáctico detectado

paracomprobar restricciones de tipo y otras limitaciones semánticas y preparar

lageneración de código.

La salida teórica de la fase de análisis semántico sería un árbol semántico. Consiste en

un árbol sintáctico en el que cada una de sus ramas ha adquirido el significado quedebe

tener. En el caso de los operadores polimórficos el análisis semántico determina cuál es

el aplicable. Por ejemplo,consideremos la siguiente sentencia de asignación: A:= B + C

En Pascal, el signo “+” sirve para sumar enteros y reales, concatenar cadenas

decaracteres y unir conjuntos. El análisis semántico debe comprobar que B y C sean

deun tipo común o compatible y que se les pueda aplicar dicho operador. Si B y C

sonenteros o reales los sumará, si son cadenas las concatenará y si son

conjuntoscalculará su unión.

Acciones semánticas

Dependiendo del tipo de sentencias, las accionessemánticas pueden agruparse en:

• Sentencias de Declaración: completar la sección de tipos de la Tabla de Símbolos.

• Sentencias ejecutables: realizar comprobaciones detipos entre los operandos

implicados.

• Funciones y procedimientos: comprobar el número, orden y tipo de los parámetros

actuales en cada llamadaa una función o procedimiento.

• Identificación de variables: comprobar si identificador ha sido declarado antes de

utilizarlo.

• Etiquetas: comprobar si hay etiquetas repetidas y validación.

• Constantes: comprobar que no se utilicen en la parte izquierda de una asignación.

• Conversiones y equivalencias de tipo: verificación.

• Sobrecarga de operadores y funciones: detectar ysolventar.

COMPROBACIONES DE TIPOS EN EXPRESIONES.

Page 10: Lenguajes y Autómatas Unidad 1

La comprobación de tipos es una forma de asegurar quelos identificadores relacionados

sean de tiposcompatibles.

Dos identificadores son compatibles de acuerdo a lo siguiente:

• Cuando forman el lado izquierdo y el lado derecho de un operador.

• Cuando forman el lado izquierdo y el lado derecho de una proposición deasignación.

• Cuando sean parámetros reales y formales.

COMPROBACIÓN DE TIPOS EN EXPRESIONES

Las comprobaciones de consistencia que se efectúanantes de la ejecución del programa

fuente, sedenominan comprobaciones estáticas.Las comprobaciones que se realizan

durante laejecución del programa objeto se denominancomprobaciones dinámicas.

La revisión de la sintaxis de un programa fuente es un ejemplo de comprobación

estática, mientras que la comprobación de tipos, es un ejemplo de comprobación que

con frecuencia puede efectuarse en forma estática y que en ocasiones debe realizarse

dinámicamente.

TIPOS

¿Qué es un tipo?

La noción varía de lenguaje a lenguaje.

Consenso

· Un conjunto de valores

· Un conjunto de operadores sobre los valores

Las clases son una instanciación moderna de la noción de tipo

TIPOS Y OPERACIONES

Ciertas Operaciones son legales para cada tipo

No tiene sentido sumar un apuntador a función y un entero en C

Tiene sentido sumar dos enteros

Pero ambos tienen la misma implementación en lenguaje ensamblador!

PILA SEMÁNTICA EN UN ANALIZADOR SINTÁCTICO

Page 11: Lenguajes y Autómatas Unidad 1

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)

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. Al decir pila semántica no se refiere a que hay varios tipos de pila,

hace referencia a que se debe programar única y exclusivamente en un solo lenguaje,

es decir, no podemos mezclar código de C++ con Visual Basic.

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.

Page 12: Lenguajes y Autómatas Unidad 1

Reglas semánticas

Son el conjunto de normas y especificaciones que definen al lenguaje de programación y

están dadas por la sintaxis del lenguaje, las reglas semánticas asignan un significado

lógico a ciertas expresiones definidas en la sintaxis del lenguaje.La evaluación de las

reglas semánticas define los valores de los atributos en los nodos del árbol de análisis

sintáctico para la cadena de entrada. Una regla semántica también puede tener efectos

colaterales, por ejemplo, imprimir un valor o actualizar una variable global.

Compatibilidad de tipos

Durante la fase de análisis semántico, el compilador debe verificar que los tipos y

valores asociados a los objetos de un programa se utilizan de acuerdo con la

especificación del lenguaje. Además debe detectar conversiones implícitas de tipos para

efectuarlas o insertar el código apropiado para efectuarlas así como almacenar

información relativa a los tipos de los objetos y aplicar las reglas de verificación de tipos.

Analizadores descendentes:

Parten del axioma inicial de la gramática, se va descendiendo utilizando las derivaciones

izquierdas, hasta llegar a construir la cadena analizada. Se va construyendo el árbol

desde sus nodos terminales. Es decir, se construye desde los símbolos de cadena hasta

llegar al axioma de la gramática.

Bottom up

Es un principio de muchos años del estilo de programación que los elementos

funcionales de un programa no deben ser demasiado grandes. Si un cierto componente

de un programa crece más allá de la etapa donde está fácilmente comprensible, se

convierte en una masa de la complejidad que encubre errores tan fácilmente como una

ciudad grande encubre a fugitivos.

Page 13: Lenguajes y Autómatas Unidad 1

Top-down

Este método consiste en dividir los problemas en subproblemas más sencillos para

conseguir una solución más rápida. El diseño descendente es un método para resolver

el problema que posteriormente se traducirá a un lenguaje compresible por la

computadora. Un parser ascendente utiliza durante el análisis una pila. En esta va

guardando datos que le permiten ir haciendo las operaciones de reducción que necesita.

Para incorporar acciones semánticas como lo es construir el árbol sintáctico, es

necesario incorporar a la pila del parser otra columna que guarde los atributos de los

símbolos que se van analizando. Estos atributos estarían ligados a la correspondiente

producción en la tabla de parsing. La pila juega un papel fundamental en el desarrollo de

cualquier analizadorsemántico. Dentro de cada elemento de la pila se guardan los

valores que puedentener una expresión.

ESQUEMA DE TRADUCCIÓN

Un esquema de traducción es una gramática independiente de contexto en la que se

encuentran intercalados, en los lados derechos de las reglas de producción, fragmentos

de programa llamados acciones semánticas.Es como una definición dirigida por la

sintaxis con la diferencia de que el orden de evaluación de las reglas semánticas se

muestra explícitamente.Los esquemas de traducción pueden tener tanto atributos

sintetizados como heredados.

Page 14: Lenguajes y Autómatas Unidad 1

Traducción descendente

Se trabaja con esquema de traducción en lugar de hacerlo con definiciones dirigidas por

sintaxis, así que se puede ser explícito en cuanto al orden en que tienen que lugar las

acciones y las evaluaciones de los atributos.

Eliminación de la recursividad izquierda de un esquema de traducción

Como la mayoría de los operadores aritméticos son asociativos por la izquierda, es

natural utilizar gramáticas recursivas por la izquierda para las expresiones. La

transformación se aplica a esquemas de traducción con atributos sintetizados. Para el

análisis sintáctico descendente, se supone que una acción se ejecuta en el mismo

momento en que se expandiría un símbolo en la misma posición. Un atributo heredado

de un símbolo debe ser calculado por una acción que aparezca antes que el símbolo, y

un atributo sintetizado del no terminal de la izquierda se debe calcular después de que

hayan sido calculados todos los atributos de los que depende.

GENERACIÓN DE LA TABLA DE SÍMBOLO Y DE DIRECCIONES

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.

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:

Una tabla de símbolos puede conceptualizarse como una serie de renglones, cada uno

de los cuales contiene una lista de valores de atributos que son asociados con una

variable en particular. Las clases de los atributos que aparecen en una tabla de símbolos

Page 15: Lenguajes y Autómatas Unidad 1

dependen en algún grado de la naturaleza del lenguaje de programación para el cual se

escribe el compilador.

Por ejemplo, un lenguaje puede ser sin tipos, y por lo tanto el atributo tipo no necesita

aparecer en la tabla. Similarmente, la organización de la tabla de símbolos variará

dependiendo de las limitaciones de memoria y tiempo de acceso.

MANEJO DE ERRORES SEMÁNTICOS

Los errores semánticos son pocos y los que existen no se pueden detectar tan fácilmente. Hasta esta etapa los errores son mostrados a los usuarios. Los demás errores ya son muy difíciles de detectar y generalmente se dan en tiempo de ejecución.

Manejo de errores semánticos

• Algunos problemas se presentan durante la fase de gestión de memoria al pasar argumentos o al crear la pila semántica.

• Muchos errores se generan durante la etapa del enlazador, al tratar de obtener código existente de algunas funciones/métodos ya implementadas en bibliotecas/APIs

El análisis semántico es posterior al sintáctico y mucho más difícil de formalizar que

éste. 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. En definitiva, comprobará que el significado de lo que se

va leyendo es válido. La salida teórica de la fase de análisis semántico sería un árbol

semántico. Consiste en un árbol sintáctico en el que cada una de sus ramas ha

adquirido el significado que debe tener. En el caso de los operadores polimórficos (un

único símbolo con varios significados), el análisis semántico determina cuál es el

aplicable.

Page 16: Lenguajes y Autómatas Unidad 1

REFERENCIAS

http://arantxa.ii.uam.es/~epulido/procesadores/semantico1.pdf

http://informatica.isipedia.com/primero/automatas-gramaticas-y-lenguajes/05-analisis-

semantico

http://biblioteca.uns.edu.pe/saladocentes/archivoz/publicacionez/

sesion_iii_3u___analisis_semantico.pdf

https://jesyib.wordpress.com/category/consultas/

https://sites.google.com/site/iscmendezportafolio/arboles-de-expresion

http://www.utm.mx/~jahdezp/archivos%20estructuras/arboles%20con

%20expresiones.pdf

https://es.scribd.com/doc/128330225/1-2-Acciones-semanticas

https://es.scribd.com/doc/219732692/Lenguajes-y-Automatas-II-Unidad-I-Sem-2-2013-

1#download

http://itpn.mx/recursosisc/7semestre/leguajesyautomatas2/Unidad%20I.pdf

http://dsc.itmorelia.edu.mx/~jcolivares/courses/ps207a/ps2_u5.pdf

http://revistas.udistrital.edu.co/ojs/index.php/visele/article/view/246/356