SINTAXIS Y SEMANTICA DE LENGUAJES

Anuncio
Gramáticas y Autómatas
Wilo Carpio Cáceres
110813
Sintaxis y Semántica del Lenguaje
Wilo Carpio Cáceres
2013
1
Gramáticas y Autómatas
Wilo Carpio Cáceres
110813
INTRODUCCION A LOS COMPILADORES
Wilo Carpio Cáceres
2012
2
Gramáticas y Autómatas
Wilo Carpio Cáceres
110813
3
COMPILACION
Genéricamente el compilador es un software
traductor un programa escrito en un lenguaje de
programación a otro lenguaje de programación,
generando un programa equivalente que la
máquina puede interpretar.
Tal procedimiento de traducción es la compilación,
que traduce el código fuente de un programa en
lenguaje de alto nivel, a otro lenguaje de nivel
inferior, de manera que se puede diseñar un
programa en lenguaje cercano al humano, para
luego compilarlo a un programa procesable por la
computadora.
Una aplicación de las teorías de las gramáticas y
los autómatas es el desarrollo de estos softwares
denominados
compiladores,
cuyo
estudio
introductivo, requiere del conocimiento de los
siguientes conceptos:

TRADUCTOR: Programa que toma como entrada un texto escrito en un lenguaje, llamado fuente y
da como salida otro texto en un lenguaje, denominado objeto.
Texto Lenguaje Fuente → TRADUCTOR → Texto Lenguaje Objeto

COMPILADOR: Traductor cuyo lenguaje fuente es un lenguaje de programación de alto nivel y la
salida es un lenguaje de bajo nivel o ensamblador o código de máquina.
Lenguaje Fuente → COMPILADOR → Lenguaje Objeto
Sus ventajas son:
 Se compila una vez, se ejecuta varias veces.
 La compilación de bucles genera código equivalente al bucle, pero interpretándolo se traduce tantas veces una
línea como veces se repite el bucle.
 Cada mensaje de error es más detallada, por que el compilador tiene vista global del programa.

INTERPRETE: A diferencia del compilador que genera un programa equivalente, el interprete toma
una sentencia del programa fuente en lenguaje de alto nivel y luego la traduce al código equivalente y
al mismo tiempo lo ejecuta.
Sus ventajas son:
 El intérprete requiere menos memoria que un compilador.
 En tiempo de desarrollo, permite más interactividad con el código.

LINKER: Construye un fichero ejecutable añadiendo al fichero objeto generado por el
compilador las cabeceras necesarias y las funciones de librería utilizadas por el programa fuente.

DEPURADOR: Permite seguir paso a paso la ejecución de un programa, siempre que el
compilador haya generado adecuadamente el programa objeto.
Gramáticas y Autómatas
Wilo Carpio Cáceres
4
110813

ENSAMBLADOR: Compilador cuyo lenguaje fuente es el lenguaje ensamblador. Algunos
compiladores, en vez de generar código objeto, generan un programa en lenguaje ensamblador que
debe después convertirse en un ejecutable mediante un programa ensamblador.

COMPILADOR CRUZADO: Genera código en lenguaje objeto para una máquina diferente de
la que se está utilizando para compilar. Se puede construir un compilador de Pascal que genere
código MS- DOS y que el compilador funcione en Linux y se haya escrito en C++.

COMPILADOR CON MONTADOR: Compila distintos módulos de forma independiente y
después es capaz de enlazarlos.

AUTOCOMPILADOR: Compilador escrito en el mismo lenguaje que se va a compilar, asi no
puede ejecutarse la primera vez. Sirve para ampliar lenguajes, mejorar el código generado, etc.

METACOMPILADOR: Compilador de compiladores, es un programa que recibe como entrada
las especificaciones del lenguaje para el que se desea obtener un compilador y genera como salida
el compilador para ese lenguaje.

DESCOMPILADOR: Programa que acepta como entrada código máquina y lo traduce a un
lenguaje de alto nivel, realizando el proceso inverso a la compilación.
Lenguaje Fuente ← DESCOMPILADOR ← Lenguaje Objeto
ETAPAS DE COMPILACIÓN
Generar un programa ejecutable suele abarcar dos pasos.
 Compilación Traduce el código fuente escrito en un lenguaje de programación
almacenado en un archivo a código en bajo nivel (normalmente en código objeto, no
directamente a lenguaje máquina).

Enlazado Enlaza el código de bajo nivel generado de todos los ficheros y subprogramas
que se han mandado compilar y se añade el código de las funciones que hay en las
bibliotecas del compilador para que el ejecutable pueda comunicarse directamente con el
sistema operativo, traduciendo así finalmente el código objeto a código máquina, y
generando un módulo ejecutable.
ACCION DE COMPILACIÓN
Lenguaje Fuente 
Tabla de Símbolos ↔
COMPILADOR






PROGRAMA FUENTE
↓
Análisis Léxico
Análisis Sintáctico
Análisis Semántico
Generar código Intermedio
Optimización de Código
Generación de Código
↓
PROGRAMA OBJETO

Lenguaje Objeto
↔ Manejo de errores
Gramáticas y Autómatas
Wilo Carpio Cáceres
110813
5
TAREAS DE COMPILACIÓN

ANÁLISIS: Comprueba la corrección del programa fuente, abarca las fases de análisis:
o Léxico: En la descomposición del programa fuente en componentes léxicos
o Sintáctico: O agrupación de los componentes léxicos en frases gramaticales
o Semántico: Que comprueba la validez semántica de las sentencias aceptadas.

SÍNTESIS: Genera la salida en el lenguaje objeto y suele estar formado por una o varias
combinaciones de fases de Generación de Código (código intermedio o de código objeto) y de
Optimización de Código (código más eficiente).
FASES DE COMPILACIÓN
Fase
1. FRONT END
Acción
Análiza el código fuente, comprueba su validez, genera el árbol de
derivación y rellena los valores de la tabla de símbolos.
Suele ser independiente de la plataforma o sistema para el cual se vaya a
compilar, y está compuesta por las fases comprendidas entre el Análisis
Léxico y la Generación de Código Intermedio
2. BACK END
Generación y optimización de código que depende del lenguaje objeto y
debe ser independiente del lenguaje fuente
Genera el código máquina, específico de una plataforma, a partir de los
resultados de la fase de análisis, realizada por el Front End.
El código que genera BackEnd no suele ejecutarse directamente, sino que
necesita ser enlazado por un programa enlazador (linker)
DISEÑO DEL COMPILADOR
Requiere:
Especificación
LÉXICA:
SINTÁCTICA:
SEMÁNTICA:
Describe
Con expresiones regulares componentes léxicos o tokens o palabras del
lenguaje. A partir de estas, se construye el analizador léxico del compilador.
La sintaxis o forma o estructura de los programas en lenguaje fuente, usando
una GIC en notación BNF o un diagrama sintáctico. A partir de esta, se
construye el analizador sintáctico del compilador
El significado de cada construcción sintáctica y las reglas semánticas que deben
cumplirse
Gramáticas y Autómatas
Wilo Carpio Cáceres
110813
6
GENERACION DE CÓDIGO INTERMEDIO
El lenguaje intermedio permite construir en menor tiempo un compilador para otra máquina y
compiladores para otros lenguajes fuente, generando códigos para la misma máquina.
OPTIMIZACIÓN DE CÓDIGO
Abarca los procesos del compilador para generar programas objetos más eficientes, rápido en
ejecución, que insuman menos memoria.
GENERACIÓN DE CÓDIGO
El código intermedio optimizado se traduce a una secuencia de instrucciones en ensamblador o en
el código de máquina del procesador, así la sentencia
Z:=X+Y
se convertirá en:
LOAD
X
ADD
Y
STORE
Z
TABLA DE SIMBOLOS
Es una estructura de datos internos donde el compilador almacena información de objetos que
encuentra en el texto fuente, como variables, etiquetas, declaraciones de tipos, etc. En esta tabla, el
compilador puede insertar un nuevo elemento en ella, consultar información, borrar, etc.
MANEJO DE ERRORES
Cada error puede ocultar otros o provocar otros errores que se solucionan con el primero. Frente a
esto se plantean dos criterios para manejar errores:
- Pararse al detectar el primer error
- Detectar todos los errores de una pasada.
ANÁLISIS LÉXICO O SCANNER (AL)
Desde la entrada lee los caracteres uno a uno, para formar TOKENS o secuencia de caracteres con
alguna relación entre sí, que serán tratados como entidad única, que será la entrada para la siguiente
etapa del compilador. En esta fase se manejan los siguientes conceptos:

TOKENS: Símbolos terminales de cada gramática como palabras reservadas, identificadores,
signos de puntuación, constantes numéricas, operadores, cadenas, etc. Existen tokens con varios
signos, como: : =, = =, + =, , etc. Los tokens que tiene dos componentes: Tipo y Valor,
pueden estar constituidas por:

TIRAS ESPECÍFICAS: Son las palabras reservadas que solo tienen tipo, pueden ser: if
then else, function, while, ;, los operadores aritméticos o lógicos :: =, = =, +, =, , etc.

TIRAS NO ESPECÍFICAS: Constituidas por los identificadores, constantes o etiquetas.
Estas tiras tienen tipo y valor. Por ejemplo, si “contador” es un identificador, el tipo de
token será identificador y su valor será la cadena “contador”.
Gramáticas y Autómatas
Wilo Carpio Cáceres
110813
7

PATRÓN: Expresión regular que define el conjunto de cadenas que puede representar a cada uno
de los tokens.

LEXEMA: Cadena que se produce al analizar el texto fuente y encontrar una cadena de caracteres
que representan un token determinado. Así, el lexema es una secuencia de caracteres del código
fuente que concuerda con el patrón de un token.

ATRIBUTOS: Información adicional sobre los tokens en forma de atributos asociados, cuyo
número de depende de cada token; aunque en la práctica el único atributo es el registro que
contiene la información propia como, lexema, tipo de token y línea y columna en la que fue
encontrado.
Ejemplo: Sea el número 2003
 TOKEN
Constante entera
 LEXEMA
2003
 PATRON: ER (+) · Dígito · Dígito*
Para procesar cadenas de caracteres y devolver pares (token, lexema), el analizador léxico
funciona así:
Programa
Fuente

| Analizador | --Token | Analizador
| 
| Léxico: AL |

| Sintáctico: AS |
|
|
|
|
|_______| Tabla de |______|
| Símbolos |
En la misma pasada el AL puede funcionar como subrutina del analizador sintáctico, es la etapa
del compilador que identifica el formato del lenguaje, leyendo para ello, los caracteres del
programa e ignorando sus elementos innecesarios para la siguiente fase, como tabuladores,
comentarios, espacios en blanco, etc.
El AL agrupa por categorías léxicas los caracteres de entrada, estableciendo el alfabeto con el que
se escriben los programas válidos en el lenguaje fuente y rechaza cadenas con símbolos ilegales
del alfabeto, desarrollando para ello las siguientes operaciones:





PROCESO LÉXICO DEL PROGRAMA FUENTE: identificador de tokens y de sus lexemas
que deberán entregar al analizador sintáctico e interaccionar con la tabla de símbolos.
MANEJA EL FICHERO DEL PROGRAMA FUENTE; Abre, lee sus caracteres y cierra.
IGNORA COMENTARIOS: Como separadores, espacios blancos, tabuladores, retornos de
carro, etc.
LOCALIZA ERRORES: Cuando se produce un error sitúa la línea y la posición en el
programa fuente y registra las líneas procesadas.
PROCESO DE MACROS, definiciones, constantes y órdenes de inclusión de otros ficheros.
Para reconocer un tokens el AL lee los caracteres hasta llegar a uno que no pertenece a la
categoría del token leído, el último carácter es devuelto al buffer de entrada para ser leído en
primer lugar en la próxima llamada al analizador léxico. Cuando el AS vuelve a llamar al AL, éste
Gramáticas y Autómatas
Wilo Carpio Cáceres
110813
8
lee los caracteres desde donde quedó en la llamada anterior, hasta completar un nuevo token y
devolver el par Token - Lexema.
CREACION DE ANALIZADORES LEXICOS: Las alternativas son:
o Usar un generador automático de analizadores léxicos, como el LEX: su entrada es un código
fuente con la especificación de las expresiones regulares de los patrones que representan a los
token del lenguaje, y las acciones a tomar cuando los detecte.
o Escribir el AL en lenguaje de alto nivel de uso general utilizando sus funciones de E/S.
o Usar lenguaje ensamblador.
ERRORES LEXICOS
En esta etapa, donde el compilador tiene solo una visión muy local del programa los pocos errores
característicos detectados por el analizador léxico son:


Uso de caracteres que no pertenecen al alfabeto del lenguaje ( ñ o  ).
Palabras que no coinciden con ninguno de los patrones de los tokens posibles
La detección de un error puede implicar:
 Ignorar los caracteres no válidos hasta formar un token según los patrones dados;
 Borrar los caracteres extraños;
 Insertar un carácter que pudiera faltar;
 Reemplazar un carácter presuntamente incorrecto por uno correcto;
 Conmutar las posiciones de dos caracteres adyacentes.
ANÁLISIS SINTÁCTICO O PARSER: (AS)
El AS además de comprobar la corrección de la sintaxis del programa fuente, construye una
representación interna del programa o caso contrario enviar un mensaje de error. Comprueba si
los token van llegando en el orden definido, para luego generar la salida con formato de árbol
sintáctico.
Programa  | Analizador | --Token  | Analizador
| --árbol | Resto de | 
Fuente
| Léxico: AL |  siguiente-- | Sintáctico: AS | sintáctico | etapas |
|
|
|
|
|_______| Tabla de |______|
| Símbolos |
De modo que sus funciones serán:



Aceptar solo lo que es válido sintácticamente.
Explicitar el orden jerárquico que tienen los operadores en el lenguaje de que se trate.
Guiar el proceso de traducción dirigida por la sintaxis.
Gramáticas y Autómatas
Wilo Carpio Cáceres
110813
9
A partir del árbol sintáctico que representa la sintaxis de un programa, el AS construye una
derivación con recorridos por la izquierda o por la derecha del programa fuente, y partir de ellos
construye una representación intermedia de ese programa fuente, que puede ser un árbol sintáctico
abstracto o bien un programa en un lenguaje intermedio.
Así para la sentencia T = X – Y + Z
Árbol Sintáctico
=
/ \
T +
/ \
- Z
/ \
X Y
Árbol Sintáctico Abstracto
Lenguaje Intermedio
| ASIGNAR | T | o |
restar X Y t1
| SUMAR | o | Z |
sumar t1 Z t2
| RESTAR | X | Y |
asignar t2
T
TIPOS DE ANÁLISIS SINTÁCTICO:
Según la teoría de Análisis Sintáctico, hay dos estrategias para construir el árbol sintáctico:

ANÁLISIS DESCENDENTE: Opera desde la raíz de árbol y va aplicando reglas por la
izquierda, de forma de obtener una derivación por izquierda de la cadena de entrada. Recorriendo
el árbol en profundidad de izquierda a derecha, encontraremos en las hojas los tokens, que nos
devuelve el A.L. en ese mismo orden.

ANÁLISIS ASCENDENTE: Desde la cadena de entrada se construye el árbol empezando por las
hojas, luego se crean nodos intermedios hasta llegar a la raíz; construyendo así al árbol de abajo
hacia arriba. El recorrido se hará desde las hojas a la raíz. El orden en el que se van encontrando
las producciones corresponde a la inversa de una derivación por la derecha.
ANÁLISIS SEMÁNTICO
Determina el tipo de los resultados intermedios, comprueba que los argumentos que tiene un operador
pertenecen al conjunto de los operadores posibles, y si son compatibles entre sí, comprueba que el
significado de lo que va leyendo sea válido, de manera de generar como salida teórica un árbol
semántico, que es un árbol sintáctico cuyas ramas han adquirido el significado concerniente.
En caso del símbolo único con varios significados u operador polimórfico, el análisis semántico
determina cuál es aplicable; así, para el signo “+”, que permite sumar números, concatenar cadenas de
caracteres y unir conjuntos, este análisis comprobará que B y C sean de tipo compatible y que se les
pueda aplicar dicho operador y si B y C son números los sumará, si son cadenas las concatenará y si
son conjuntos calculara su unión.
Los compiladores analizan semánticamente los programas para verificar su compatibilidad con las
especificaciones semánticas del lenguaje al cual pertenecen y así poder comprenderlos, para permitir
la recepción por parte del procesador de las órdenes cuando ese programa se ejecuta. Luego de
verificar la coherencia semántica, traduce al lenguaje de la máquina o a una representación portable
entre distintos entornos.
Gramáticas y Autómatas
Wilo Carpio Cáceres
110813
10
Esta fase efectúa la traducción asociada al significado que cada símbolo de la gramática adquiere por
aparecer en una producción, asociándole información o atributos, y acciones semánticas a las reglas
gramaticales, que serán código en un lenguaje de programación; para evaluar los atributos y
manipular dicha información de las tareas de traducción, mediante los siguientes pasos:




Análisis léxico del texto fuente.
Análisis sintáctico de la secuencia de tokens producida por el analizador léxico.
Construcción del árbol de análisis sintáctico.
Recorrido del árbol por el analizador semántico ejecutando las acciones semánticas.
Al actuar la semántica y la traducción, los árboles de análisis sintáctico reciben en cada nodo
información o atributos, dando lugar a los árboles con adornos, de manera que cada símbolo, se
comporta como un registro, cuyos campos son cada uno de sus propios atributos con información
semántica, dando lugar al concepto de gramática atribuida.
Bibliográfica
 Teoría de autómatas y lenguajes formales.
Autómatas y complejidad. Kelly Dean Editorial Prentice Hall

Introducción a la teoría de autómatas, lenguajes y computación
John E. Hopcroft; Jeffrey D. Ullman Editorial Cecsa

Teoría de la computación
J. Gleuu Brokshear Editorial Addison Wesley Iberoamericana
Descargar