jueves, 14 de diciembre de 2017

6. Integración del intérprete

6.1. Lenguaje intermedio


En esta sección se describirá la implementación de un intérprete de un lenguaje intermedio básico. El lenguaje consta únicamente de un tipo int y se basa en una pila de ejecución sobre la que se realizan las principales instrucciones aritméticas. Las instrucciones del lenguaje son:



Desde el punto de vista sintáctico un programa está formado por una secuencia de instrucciones. Las variables y etiquetas son identificadores formados por una secuencia de letras y dígitos que comienzan por letra y se permiten comentarios con el formato de C++ (/*...*/) y (//....).

Ejemplo: El siguiente programa calcula el factorial de un número.

6.2.Construcción del intérprete

martes, 12 de diciembre de 2017

5. Análisis Sintáctico

El analizador sintáctico tiene como objetivo encontrar las estructuras presentes en su entrada.
Estas estructuras se pueden representar mediante el árbol de análisis sintáctico, que explica cómo se puede derivar la cadena de entrada en la gramática que especi ca el lenguaje. Aunque en la práctica es habitual que el árbol de análisis no llegue a construirse, se trata de una abstracción que nos permite entender mejor todo el proceso.

Para construir la especi ficación sintáctica de los lenguajes de programación, se suelen emplear gramáticas incontextuales, generalmente restringidas para que el análisis se pueda realizar demanera efi ciente.
Para que sea posible construir el árbol de análisis, es necesario que la entrada no presente errores sintácticos. En caso de que los haya, el analizador debe informar de su presencia adecuadamente y, si es posible, intentar continuar el análisis.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 tokens 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.
http://www.lcc.uma.es/~galvez/ftp/tci/tictema3.pdf
 

5.1. Aspectos generales de un analizador sintáctico

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.

Tipos generales de analizadores sintácticos para gramáticas:
a) Análisis sintáctico descendente. Construye árboles de análisis sintáctico desde arriba (raíz) hacia abajo (hojas). El análisis se realiza de lo general a lo particular.
b) Análisis sintáctico ascendente. Construyen árboles de análisis sintáctico comenzando en las hojas y suben hacia la raíz. El análisis se realiza de lo particular a lo general.
En ambos casos, se examina la entrada al analizador léxico de izquierda a derecha, un símbolo a la vez.

5.2. Gramáticas y diseño de un árbol gramatical


Una gramática describe de forma natural la estructura jerárquica de muchas construcciones de los lenguajes de programación. Las gramáticas libres de contexto permiten describir la mayoría de los lenguajes de programación, de hecho, la síntaxis de la mayoría de lenguajes de programación está definida mediante gramáticas libres de contexto. Por otro lado, estas gramáticas son suficientemente simples como para permitir el diseño de eficientes algoritmos de análisis sintáctico que, para una cadena de caracteres dada determinen como puede ser generada desde la gramática
Consta de:
• TERMINALES. Símbolos básicos con que se forman las cadenas. Para un lenguaje de programación, cada palabra clave/reservada es un terminal.

• NO TERMINALES. Son variables sintácticas que denotan conjuntos de cadenas (identificadotes o variables). Los no terminales definen conjuntos de cadenas que ayudan a definir el lenguaje generado por la gramática. Imponen una estructura jerárquica sobre el lenguaje que es útil tanto para el análisis sintáctico como para la traducción.

• UN SÍMBOLO INICIAL. En una gramática, es un no terminal que representa un conjunto de cadenas.

• PRODUCCIONES. Especifican cómo se pueden combinar los terminales y no terminales para formar cadenas. Cada producción consta de un No terminal (símbolo inicial), seguido por una flecha o símbolo de asignación, seguida por una cadena de no terminales y terminales.


ESCRITURA DE UNA GRAMATICA

Las gramáticas describen la mayoría de las sintaxis de los lenguajes de programación.Toda construcción que se pueda describir mediante una expresión regular también se puede describir por medio de una gramática.
Por ejemplo, para la expresión regular (a|b)* abb

Y la gramática: A0 → a A0 | b A0| b A1 
A1 → b A2
A2 → bA3 
A3 → є

*Árbol sintáctico de una sentencia de un lenguaje
 Es una representación que se utiliza para describir el proceso de derivación de dicha sentencia. 
Como nodos internos del árbol, se sitúan los elementos no terminales de las reglas de producción que vayamos aplicando, y tantos hijos como símbolos existan en la parte derecha de dichas reglas. 
Veamos un ejemplo: Sea la gramática anterior.
 E Ú E + T | T T Ú T * F | F F Ú ( E ) | a | b 
Supongamos que hay que reconocer: ( a + b ) * a + b 
Si el árbol puede construirse, es que la sentencia es correcta:

5.3. Verificación de sintaxis y aplicación de reglas sintácticas


5.4. Elaboración del PARSER

viernes, 8 de diciembre de 2017

4. Análisis léxico

4.1.  Aspectos generales de un analizador léxico

Image result for analizador lexico
Un analizador léxico es la especificación y el diseño de programas que ejecuten las acciones activadas por patrones dentro de las cadenas.

*La principal función es leer los caracteres de entrada y elaborar como salida una secuencia de componentes léxicos que se utilizaran.

*Convierte una cadena de caracteres en una cadena de palabras.

*Una forma sencilla de crear un analizador léxico consiste en la elaboración de un diagrama que muestre la estructura de los componentes léxicos del archivo fuente, y después hacer la traducción “a mano” del diagrama a un programa para encontrar los componentes léxicos.

*Una herramienta de software que automatiza la construcción de analizadores léxicos, permite que personas con diferentes conocimientos utilicen la concordancia de patrones en sus propias áreas de aplicación.

*La gran ventaja de un generador de analizadores léxicos es que puede utilizar los algoritmos más conocidos de concordancia de patrones, con lo cual crea analizadores léxicos eficientes para los no especialistas en dichas técnicas. 

4.2.  Definición de grafos y autómatas

AFD.
Grafos.
Los grafos no son más que la versión general de un árbol, es decir, cualquier nodo de un grafo puede apuntar a cualquier otro nodo de éste (incluso a él mismo). Este tipo de estructuras de datos tienen una característica que lo diferencia: los grafos se usan para almacenar datos que están relacionados de alguna manera (relaciones de parentesco, puestos de trabajo, ...); por esta razón se puede decir que los grafos representan la estructura real de un problema. En lo que a ingeniería de telecomunicaciones se refiere, los grafos son una importante herramienta de trabajo, pues se utilizan tanto para diseño de circuitos como para calcular la mejor ruta de comunicación en Internet.

Autómata

Se llama autómata a cualquier mecanismo que es capaz de moverse por sí mismo. Si los autómatas se producen en serie tenemos los robots. Y, en el campo de la ficción, si el autómata tiene aspecto humano (por estar recubierto de materia orgánica por ejemplo), tenemos los androides.


También cabe llamar autómata a toda máquina que sigue un programa de instrucciones diseñado por un programador. En este sentido, los ordenadores también son autómatas. Cabe hablar también de autómatas de propósito general o universal y de autómatas de propósito limitado. En el primer caso tenemos los ordenadores convencionales, que están construidos de tal forma que pueden programarse para resolver muchos tipos diferentes de problemas, y en el segundo los computadores diseñados para realizar una tarea específica, como nuestras calculadoras o el computador de un automóvil. Por extensión, también recibe el nombre de "autómata" el programa mismo, o la arquitectura computacional en la que descansa la ejecución del programa, como es el caso de la llamada "máquina de Turing".

http://www.e-torredebabel.com/Psicologia/Vocabulario/Automatas.htm

La teoría de autómatas es una rama de las ciencias de la computación que estudia las máquinas abstractas y los problemas que éstas son capaces de resolver. La teoría de autómatas está estrechamente relacionada con la teoría del lenguaje formal ya que los autómatas son clasificados a menudo por la clase de lenguajes formales que son capaces de reconocer.
Un autómata es un modelo matemático para una máquina de estado finito (FSM sus siglas en inglés). Una FSM es una máquina que, dada una entrada de símbolos, "salta" a través de una serie de estados de acuerdo a una función de transición (que puede ser expresada como una tabla). En la variedad común "Mealy" de FSMs, esta función de transición dice al autómata a qué estado cambiar dados unos determinados estado y símbolo.
La entrada es leída símbolo por símbolo, hasta que es "consumida" completamente (piense en ésta como una cinta con una palabra escrita en ella, que es leída por una cabeza lectora del autómata; la cabeza se mueve a lo largo de la cinta, leyendo un símbolo a la vez) una vez la entrada se ha agotado, el autómata se detiene.
Dependiendo del estado en el que el autómata finaliza se dice que este ha aceptado o rechazado la entrada. Si éste termina en el estado "acepta", el autómata acepta la palabra. Si lo hace en el estado "rechaza", el autómata rechazó la palabra, el conjunto de todas las palabras aceptadas por el autómata constituyen el lenguaje aceptado por el mismo.

4.3.  Definición de clases, estados y tokens

Clase. Es una construcción que permite crear tipos personalizados propios mediante la agrupación de variables de otros tipos, métodos y eventos. Una clase es como un plano. Define los datos y el comportamiento de un tipo. Si la clase no se declara como estática, el código de cliente puede utilizarla mediante la creación de objetos o instancias que se asignan a una variable. La variable permanece en memoria hasta todas las referencias a ella están fuera del ámbito. Si la clase se declara como estática, solo existe una copia en memoria y el código de cliente solo puede tener acceso a ella a través de la propia clase y no de una variable de instancia.


Estados. un estado es una configuración única de información en un programa o máquina. Esto es un concepto que ocasionalmente se ha extendido en varias formas de programación de sistemas tales como lexers y Parsers.

Si el autómata en cuestión es una Máquina de estados finitos, un Autómata con pila o una auténtica Máquina de Turing, un estado es un conjunto particular de instrucciones las cuales serán ejecutadas en respuesta a la entrada de la máquina. Se puede pensar en el estado como algo análogo a la memoria principal de la computadora. El comportamiento del sistema es una función de (a) la definición del autómata, (b) la entrada y (c) el estado actual.
  • Estados Compatibles son estados de una máquina de estados los cuales no tienen conflictos para ningún valor de entrada. Así para cada entrada, ambos estados deben tener la misma salida, y ambos estados deben tener el mismo sucesor (o sucesores sin especificar) o ambos no deben cambiar. Los estados compatibles son redundantes si aparecen en la misma máquina de estados.
  • Estados Equivalentes son los estados de una máquina de estados los cuales, para cada posible secuencia de entrada, la misma secuencia de salida será producida - sin importar cual estado es el estado inicial.
  • Estados Distinguibles son estados en una máquina de estados los cuales tienen al menos una secuencia de entrada la cual causa secuencias de salida diferentes - sin importar cual estado es el estado inicial.


Tokens. Un token es un par que consiste en un nombre de token y un valor de atributo opcional. El nombre del token es un símbolo abstracto que representa un tipo de unidad léxica; por ejemplo, una palabra clave específica o una secuencia de caracteres de entrada que denotan un identificador. Los nombres de los tokens son los símbolos de entrada que procesa el analizador sintáctico.

4.4.  Matriz de transición de estados y matriz de salidas

Una tabla de transiciones es un arreglo (o matriz) bidimensional cuyos elementos proporcionan el resumen de un diagrama de transiciones correspondiente.


Tabla que muestra qué estado se moverá un autómata finito dado, basándose en el estado actual y otras entradas. Una tabla de estados es esencialmente una tabla de verdad en la cual algunas de las entradas son el estado actual, y las salidas incluyen el siguiente estado, junto con otras salidas.

Una tabla de estados es una de las muchas maneras de especificar una máquina de estados, otras formas son un diagrama de estados, y una ecuación característica.

Cuando se trata de un autómata finito no determinista, entonces la tabla de transición muestra todos los estados que se moverá el autómata.

Matriz de salidas.

4.5.  Elaboración del SCANNER


6. Integración del intérprete

6.1. Lenguaje intermedio En esta sección se describirá la implementación de un intérprete de un lenguaje intermedio básico. El lenguaje...