DIAGRAMA DE CONWAY

 Es una herramienta gráfica para describir la sintaxis de un lenguaje. en ella se usan símbolos terminales y no terminales, que se representan:

Terminales: con un circulo o rectángulo redondeado
No terminales: con un rectángulo

Los diagramas se enlazan con flechas que indican e orden en que se deben realizar la interpretación. por ejemplo la sintaxis de una identificador se hace así:


En esta definición vemos que 
La opción es un camino alternativo que se puede seguir o no, como en el caso del guión bajo. Las 
alternativas están en caminos que bifurcan como en letra y dígito. Lo que se puede repetir está formando un circuito que se puede recorrer cualquier número de veces. El elemento no terminal que se está definiendo figura como una etiqueta. 

Read Users' Comments (0)

NOTACIÓN DE CHOMSKY


Según Chomsky, una gramática formal es una estructura matemática, consistente en un conjunto de reglas que definen la forma de construir  todas y cada una de las cadenas de caracteres que componen un determinado lenguaje, denominadas sentencias, y donde el conjunto de todas las sentencias constituye el lenguaje. Como no se describe el significado de dichas sentencias, sino únicamente su forma, de ahí procede el calificativo de formal. Además de las reglas, la descripción de una gramática formal se completa con dos conjuntos de símbolos, denominados alfabetos, uno, denominado terminal,  de los caracteres que conforman las sentencias propias del lenguaje, y otro, el no terminal, constituido por una serie de símbolos auxiliares usados durante el proceso de cómputo y que no aparecen en las sentencias válidas del lenguaje, sino únicamente durante los pasos intermedios. Para finalizar, también se añade un símbolo no terminal especial, denominado inicial, usualmente denotado por la letra S, que sirve para dar comienzo a la construcción de cualquier sentencia.



Read Users' Comments (0)

DIAGRAMAS DE ESTADOS

Es una manera para caracterizar un cambio en un sistema, es decir que los objetos que lo componen modificaron su estado como respuesta a los sucesos y al tiempo.

En los diagramas de estados podemos encontrar  dos elementos: 

Estados: los estados se representas con letras o símbolos dentro de un circulo generalmente.
transiciones: se representan en arcos.


los estados se pueden dividir como las posibles situaciones a las que puede llevar un autómata que estemos describiendo. Dentro de los estados podemos distinguir entre estados estables y inestables.

Cuando existe alguna transición para la cual se llega el mismo estado desde que se parte se dice que es un estado estable mientras que no exista una transición que cumpla esta condición se habla de estado inestable.

ejemplo: se tiene una maquina de venta de refresco:

Estados
1. no hay diner en el interior de la maquina
2. existe el dinero suficiente para sacar el refresco
3. en el interior de la maquina esta cada una de las cantidades permitidas? (monedas de: 10, 20, 50) el refresco cuesta 60 y no se devuelve dinero.

Las transiciones corresponden a los eventos de la entrada que produciran los cambios de estado en el sentido de las flechas.

El cambio de estado se producirá si las condiciones de las entrada coinciden con la etiqueta social a dicha transición luego las transiciones de la maquina de regresco serian:

a. introducir monedas permitidas (10, 20, 50)
b. pulsar el botón para tener el refresco.

Diagrama de estado maquina de refresco


Cuando introducimos una moneda pasaremos al estado con la cantidad actualizada, pero en el caso que sobre pasamos la cantidad del refresco nos quedaremos en los 60 centavos ya que no se devuelve dinero y no es necesario almacenar dicha cantidad superior. Cuando pulsamos el botón de refresco no sucederá nada a menos que no encontremos en el estado 60 en cuyo caso se da el refresco.



Read Users' Comments (1)comentarios

Autómatas de Estado Finitos

Autómata finito: Es un vector que tiene un conjunto de entradas finitas denominadas con la letra i un conjuntos finito de estados (no vacíos) un delta denominado función de transición y un conjunto universal de todos los estados.

Existen dos tipos autómatas finitos, los cuales son:

Autómata finito determinista: es un autómata finito que además es un sistema determinista; es decir, para cada estado en que se encuentre el autómata, y con cualquier símbolo del alfabeto leído, existe siempre a lo más una transición posible desde ese estado y con ese símbolo.



Autómata finito no determinista: Una extensión de los AFD’S es la de permitir que de cada estado o nodo del diagrama de estados salga un número de flechas mayor o menor que |Σ|. Así se puede permitir que falte la flecha correspondiente a alguno de los símbolos del alfabeto, o bien que haya varias flechas que salgan de un solo nodo con la misma etiqueta. Inclusive se permite que las transiciones tengan como etiqueta palabras de varias letras o hasta la palabra vacía.

Definición. Un autómata finito no determinista es un quíntuplo (K, Σ, Δ, s, F), donde K, Σ, s y F tienen el mismo significado para el caso de los AFD y Δ, llamada la relación de transición, es un subconjunto finito K X Σ* X K.



Read Users' Comments (0)

Fases de un Compilador 

Por razones de diseño, la construcción del compilador se divide en varios pasos o fases. Se divide en dos procesos genéricos:

Análisis: El cual hace referencia a la escritura correcta del programa fuente, escrito por un programador.

Síntesis:   Una vez se ha ejecutado el análisis de manera exitosa se procede a agrupará las componentes, que conforman el programa fuente, para construir frases con sentido con el fin de generar una salida.  Que puede ser en lenguaje de máquina o algún otro lenguaje destino que se considere conveniente.

El proceso de análisis  comprende varias fases que son: 

Análisis léxico: Es la fase encargada de la lectura y exploración misma del programa fuente,  Esto
quiere decir que el analizador léxico lee el programa fuente, y lo fracciona en componentes que tienen sentido para el lenguaje de programación que sé está considerando.

Análisis sintáctico: A esta fase le corresponde evaluar que el programa  fuente escrito realmente
cumpla con las especificaciones del lenguaje definido para el compilador.  Para ello normalmente
el programa fuente debe reflejar una estructura especial. Esta debe responder a una serie de reglas, que pueden ser recursivas o no, las cuales se denominan con el nombre de gramáticas.  (Es una de las fases más importantes de la compilación.)

Análisis Semántico:   Esta fase se dedica a determinar si todos los componentes del programa están siendo usados de manera válida, para el contexto en el cual aparecen.  Es decir, se deben los componentes colindantes  a cada componente siendo analizado, antes de determinar que las operaciones ejecutadas por el mismo estén dentro de las operaciones permitidas por el lenguaje, para dicho tipo de situaciones.

Mapa conceptual: Análisis sintáctico y análisis semántico






Una vez el programa fuente ha sido sometido a un análisis completo y se puede tener en cuenta de que esta correctamente escrito.  Solo queda faltando generar algún tipo de salida para que el ciclo de compilación quede completo.

 Las fases restantes hacen una síntesis  del programa fuente para generar la salida.  Estas fases son:

Generación  de código Intermedio: La mayoría de los compiladores modernos intentan optimizar,
hasta donde sea posible, el código que generan. Para lograr esto los compiladores analizan internamente y tratan de generar secuencias  de instrucciones internamente equivalentes a las del programa fuente, o reemplazan instrucciones para hacer un uso más eficiente en la memoria.  Su objeto general es general un código intermedio del programa fuente para que sea usado posteriormente por el optimizador de código.

Optimización de código: El objeto de esta fase es el de mejorar el código fuente escrito para que
sea más rápido de ejecutar, o use de manera más eficiente los recursos de la máquina.  Este proceso se apoya en la generación de código intermedio que fue realizada en la fase anterior.  Por lo general es mucho más complicado optimizar el código basándose en el programa fuente tal  como fue escrito por el programador.

Generación de código: El proceso de generación de código es el que constituye la salida, es decir,
genera el código de máquina que corresponde al programa fuente.  Hay  que recordar la diferencia con los intérpretes y su salida exclusiva de código.

Ejemplo de cómo se compila una línea genérica de un lenguaje:

Tomando una sencilla instrucción del lenguaje pascal se explicará cuál es la forma en que el compilador se comporta en cada fase y etapa respectiva.  Sea la instrucción:
Suma:= ultimo + penúltimo

Inicialmente el analizador léxico leerá la línea carácter a carácter usando como referencia los
espacios en blanco, que indican donde comienza y donde termina cada componen.  El analizador
léxico será invocado de manera sucesiva por el analizador sintáctico y a cada llamada, en su orden
devolviendo lo siguiente:

El identificador:   Suma
El símbolo de asignación: =
El identificador:   último
El operador de suma: +
El identificador:   penúltimo

Luego comienza el análisis sintáctico para verificar que la línea escrita en el lenguaje esta correcta.
Para lo anterior representa en una estructura jerárquica denominada árbol gramatical así:



otro ejemplo: w=f*d/t



Posteriormente al análisis continúa la etapa de síntesis que se realiza en su orden de la siguiente 
manera:

Generación de código intermedio: Consiste en construir un código con variables temporales donde
se use el recurso de memoria para representar cada instrucción de forma temporal.  En el problema que llevamos como ejemplo el código intermedio seria:

Temp1=id2+id3
Id1=Temp1

Después el código intermedio es pasado por el optimizador de código y obtenemos lo siguiente:

Id1=Temp1

La etapa final en el proceso de  síntesis del compilador es convertir el código optimizado a un código entendible por la máquina (lenguaje de maquina o ensamblador).  En nuestro ejemplo queda de la siguiente forma:

Mov Id3, R1     Mueva el contenido de Id3 a R1
Add  Id2, R1    Sume Id2 con lo que tiene en R1
Mov  R1, Id1    lleve el contenido de la suma a Id1

 Un segundo ejemplo sobre la forma en que se trabaja un compilador. Sea la instrucción del lenguaje C: 

Posición = Inicial + Velocidad * 60

Etapa de análisis:
Analizador léxico: 

El identificador:   Posición
El símbolo de asignación:=
El identificador:   Inicial
El operador de suma: +
El identificador:   Velocidad
El operador de suma: *
El identificador constante: 60 

Analizador Sintáctico: (Representación mediante un árbol sintáctico) 


Etapa de Síntesis:
Generación de código intermedio 

Temp1=enteroreal (60) 
Temp2=Id3*temp1
Temp3=id2+temp2
Id1=temp3 
Optimización de código:

Temp1=id3*60 
Id1=1d2+temp1
Generación de código: 

Mov Id3, r2
Mult #60, r2
Mov  r2, r1
Add  Id2, r1
Mov  r1,Id1 




Read Users' Comments (0)

CLASIFICACIÓN DE LOS COMPILADORES

El compilador traduce las instrucciones de una lenguaje de alto nivel a instrucciones de bajo nivel para cada lenguaje de programación se requiere un compilador separado. el compilado traduce todo el programa antes de ejecutarlo. los compiladores son pues programas de traducción insertados en la memoria por el sistema operativo para convertir programas de computo en pulsaciones eléctricas ejecutables.

los compiladores pueden ser:

A. Una sola pasada: es decir examina el código fuente una vez y generan el código objeto.
B. Pasadas múltiples: este compilador requiere pasos intermedios para producir un código en otro lenguaje y una pasada final para producir y optimizar.
C. Optimizacion: lee el código fuente lo analiza descubre errores potenciales sin ejecutar el programa.
D. Compiladores incrementa-les: genera un código objeto instrucción por instrucción cuando el usuario teclea una orden individual
E. ensamblador: E lenguaje fuente es el ensamblador


Read Users' Comments (0)

VENTAJAS  DE LOS COMPILADORES FRENTE A LOS INTERPRETES


- Se compila una vez y se ejecuta n veces.
- En bucles la compilación genera código equivalente al bucle pero interpretándolo se traduce tantas veces una linea como veces se repite el bucle.
- El compilador tiene una visión global del programa pero lo que la información el mensaje de error es mas detallada.

Un compilador no es un programa que funcione de manera aislada si no que necesita de otros programas para conseguir su objetivo el cual es obtener un programa ejecutable a partir de un programa fuente.

Read Users' Comments (0)

Definición del compilador

Que es un compilador: Consiste en mirar la solución de un lenguaje de alto nivel a un lenguaje de bajo nivel.  El proceso de traducir el programa escrito en lenguaje de alto nivel a un formato ejecutable por un computador se conoce como compilación.  O sea, que un compilador es un programa que lee en un lenguaje y traduce a otro lenguaje. 

Hay compiladores que generan otro tipo de salida, para ser usada con fines diferentes al lenguaje de máquina.  Por ejemplo como lo hace un intérprete que ejecuta las operaciones especificadas por un programa. 

Diferencia de compilador y traductores:

Los compiladores presentan diferencias claves respecto a los traductores pues su propósito no es tan particular como el de convertir un lenguaje escrito con unas normas en otro lenguaje que responde a normas distintas; a esta tarea se suma la revisión lexicográfica, sintáctica, semántica y al final la escritura optimizada de un código que puede ser perfectamente entendido por la computadora (código en lenguaje de maquina o ensamblador). 

Read Users' Comments (0)


NACIMIENTO

En la década de los 40 donde nació el primer ordenador se comenzó a crear los primeros códigos numéricos, claves, lenguaje ensamblador, etc. Pero el hombre buscaba la creación de un lenguaje más sencillo donde no tocara solo trabajar con un lenguaje maquina o de bajo nivel, entonces aparecieron los compiladores.

Un compilador es un traductor avanzado que genera un archivo ejecutable optimizado. En otras palabras proceso de traducción de un código fuente, escrito a través de un lenguaje de programación de alto nivel y para que este código pueda ser ejecutada por la computadora además tiene que ser procesada por un lenguaje de máquina.

Un compilador consta de dos partes:

Front End: parte que analiza el código fuente, comprueba su validez, genera el árbol de derivación y rellena los valores de la tabla de símbolos.

Back End: parte en donde se genera el código máquina exclusivo para una plataforma a partir de lo analizado en el front end.

Por lo general el resultado del back end no puede ser ejecutado directamente, se necesita pasar por un proceso de enlazado (linker).


MUSIM/0 

Los componentes léxicos o tokens que conforman el lenguaje son los siguientes: 

• Identificadores, que solo son nombres de variables y están compuestos por una única letra minúscula de rango a-z. 
• Constantes numéricas de un solo digito, de rango 0-9.
• Operadores: +,-,*,/, y %. 
  
Compiladores. Guía 1 
• Símbolo de asignación: = (igual).
• Paréntesis: ( y ).
• Separador de sentencias: ; (punto y coma).
• Indicadores de principio y fin de bloque: { y }.
• Palabras reservadas que están formadas por una letra mayúscula. Tan solo son tres: R (lectura), W(escritura) y M(programa principal). 

Puede observarse que este lenguaje solo permite tres tipos de sentencias: lectura, asignación y escritura. Tiene un solo tipo de datos: entero. Las variables están formadas por una única letra minúscula, y las constantes son de un dígito. Tiene cinco operadores +(adición), -(diferencia),*(producto), /(división entera), y %(modulo). Se permite el
uso de paréntesis.

Ejemplo 1:

M
{
R a;
R b;
c = a + b;
W c;

Analicemos lo que hace este programa.
“R a” y “R b” indica que le leen las variables a y b.
“c = a + b” indica que en la variable c se asignara el
resultado de la suma de a y b.
“W c” indica que se escribirá la variable c.
En pocas palabras, este programa leerá dos variables, las
sumara y finalmente mostrará el resultado en pantalla.

ENSAMPOCO/0

Como lenguaje objeto se utiliza un lenguaje intermedio que es un pequeño ensamblador, que se denomina ENSAMPOCO/0. Este ensamblador trabaja sobre una maquina abstracta, en este caso
particular es una máquina de pila. La maquina tendrá una memoria de 26 celdas cuyas direcciones se nombrarán con las letras de la ‘a’ a la ‘z’, y una pila LIFO donde se realizarán las operaciones aritméticas.

A continuación se describe la forma de trabajo de las distintas instrucciones.

Instrucción Descripción
.CODE
Indica el comienzo del código
PUSHC
Coloca una constante en la pila. El operando
es una constante
PUSHA
Coloca en la pila la dirección de una
variable. El operando es una variable, dado
que las direcciones se denominan con el
nombre de las variables
LOAD
Asume que el último valor insertado en la
pila es una dirección. Esta dirección es
extraída de la pila y en su lugar se pone el
valor ubicado en dicha dirección. No tiene
operando
STORE
Usa los dos últimos elementos de la pila. Uno
es la dirección de una celda y memoria y el
otro el valor a almacenar en dicha celda. El
último elemento de la pila es el valor y el
otro la dirección. Después de ejecutada la
instrucción, los dos elementos implicados son
extraídos de la pila, dejándolos en el mismo
lugar. No tiene operando.
NEG
Cambia el signo del último valor introducido
en la pila, dejándolo en el mismo lugar. No
tiene operando
ADD
Opera con los dos últimos elementos
introducidos en la pila, extrayéndolos y
dejando en su lugar el resultado. Por lo
tanto la pila habrá disminuido en un
elemento. No tiene operando.
MUL
Opera con los dos últimos elementos
introducidos en la pila, extrayéndolos y
dejando en su lugar el producto. Por tanto la
pila habrá disminuido en un elemento. No
tiene operando.
DIV
Opera con los dos últimos elementos
introducidos en la pila, extrayéndolos y
dejando en su lugar el producto. Por lo tanto
la pila habrá disminuido en un elemento. No
tiene operando.
MOD
Opera con los dos últimos elementos
introducidos en la pila, extrayendo primero
el denominador y después el numerador y
dejando en su lugar el modulo. Por tanto, la
pila habrá disminuido en un elemento. No
tiene operando.
INPUT
Toma el valor del buffer de entrada, en este
caso el teclado, y lo coloca en la dirección
asignada a la variable. La pila no sufre
cambios.
OUTPUT
Toma el valor de la dirección indicada y lo
lleva al buffer de salida, en este caso la
pantalla. La pila no sufre cambios.
END
Indica el fin de programa.

Ejemplo 2
A continuación se muestran un programa fuente en MUSIM/0, y su traducción al código intermedio ENSAMPOCO/0

Código en MUSIM/0
M
{
R a;
R b;
z = a + b;
W z;
}


Traduccion a ENSAMPOCO/0 

.CODE
INPUT a
INPUT b
PUSHA z
PUSHA a
LOAD
PUSHA b
LOAD
ADD
STORE
OUTPUT z
END 

Read Users' Comments (0)


INTRODUCCION


Se comenzara con una breve descripción del  nacimiento de los compiladores, dando su definición, partes, fases y tipos.

Como se divide un compilador, ya que en esta parte al ubicar donde se divide sabrás cuales de las fases sirve para cada una de ellas, etc. En general conceptos de compiladores y sus respectivas definiciones de cada una de ellas.




Read Users' Comments (0)