miércoles, 11 de mayo de 2011

Manejo de Buffers de Entrada - Compiladores


Esta sección trata algunos aspectos de la eficiencia relacionados con el manejo de los buffers de entrada, esto toma importancia cuando se busca un esquema de un pre análisis en la entrada para identificar los componentes léxicos, la finalidad de esto es utilizar técnicas que aumenten la velocidad de analizador léxico.

1.    DEFINICION DE TERMINOS

Analizador  léxico
 Lee  la secuencia de caracteres del programa fuente, carácter a carácter, y los agrupa para formar unidades con significado propio, ósea componentes léxicos  o tokens en ingles. Estos componentes léxicos representan: palabras reservadas: if, while, do,  identificadores  asociados a variables, nombres de funciones,  operadores: = * + - / == > < & ! =. . ., etc.

Buffer de datos
Un buffer en informática es un espacio de memoria, en el que se almacenan datos para evitar que el programa o recurso que los requiere, ya sea hardware o software, se quede sin datos durante una transferencia.


Un ejemplo de esto último ocurre en una comunicación telefónica, en la que al realizar una llamada esta se almacena, se disminuye su calidad y el numero de bytes a transferidos, y luego se envían estos datos modificados al receptor.

Pueden ser implementados por software o hardware, aunque la gran mayoría son del primer tipo. Normalmente se usan cuando la frecuencia de transferencia de datos es distinta a la de procesado. Estas diferencias temporales de transmisión son normalmente ajustadas mediante la implementación de un algoritmo con cola (o estructura de tipo FIFO) en memoria, para así escribir datos en la cola a una frecuencia y leerlos a otra.

Se puede ejemplificar la función de un buffer utilizando ésta metáfora: Un buffer es como tener dinero en el banco (buffer), un trabajo (entrada) y unos gastos fijos (salida). Si tienes un trabajo inestable, mientras tengas ciertos ahorros, puedes mantener tus gastos fijos sin problemas, e ir ingresando dinero cuando puedas según vas trabajando. Si los ahorros son pequeños, en seguida que no tengas trabajo, no vas a poder acometer los gastos fijos.


Diferencias con la caché:
Una caché puede ser usada a veces como un buffer, y viceversa. Sin embargo, una caché opera con el supuesto de que los mismos datos van a ser utilizados múltiples veces, que los datos escritos serán leídos en un periodo corto de tiempo, o teniendo en cuenta la posibilidad de múltiples lecturas o escrituras para formar un único bloque más grande. Su premisa básica es reducir los accesos a los almacenamientos de nivel más bajo, los cuales son bastante lentos.

Una caché de disco o archivo de caché guarda las estadísticas de los datos almacenados en él y proporciona datos con un tiempo máximo de espera en modos de escritura en diferido. Un buffer, por el contrario, no hace nada de esto, sino que es utilizado normalmente en entrada, salida y a veces, almacenamiento temporal de datos que se enrutan entre distintos dispositivos o que van a ser modificados de manera no secuencial antes de ser escritos o leídos de manera secuencial.


2.       MANEJO DE LOS BUFFERS DE ENTRADA

Hay tres métodos generales de implantación de un analizador léxico:

1. Utilizar un generador de analizadores léxicos, como el compilador LEX, para producir el analizador léxico a partir de una especificación basada en expresiones regulares. En este caso, el generador proporciona rutinas para leer la entrada y manejarla con buffers.

Nota Personal:
LEX y FLEX no son lo mismo LEX es un software utilizado para generar componentes léxicos para UNIX y como sobran UNIX es un sistema operativo no libre por lo tanto este LEX se convierte en un programa licenciado, FLEX es la versión libre de este sistema ,  FLEX estas desarrollado bajo licencia GNU la cual lo hace un software libre pero con  restricciones, GNU es una licencia orientada  a proteger la libre distribución modificación y uso del software pero a su vez lo protege de intentos de apropiación que lleguen a quitar libertades. GNU es juego de palabras que al final significa IS NOT UNIX su creador recomienda pronunciarlo como ÑU igual que el animal por eso el logo es la cabeza de este animal los que usaron FLEX la pudieron ver, pero al final todos lo pronunciamos como queramos.

2. Escribir el analizador léxico en un lenguaje convencional de programación de sistemas, utilizando las posibilidades de entrada y salida para leer la entrada.

3. Escribir el analizador léxico en lenguaje ensamblador y manejar explícitamente la lectura de la entrada.

Estas tres opciones se relacionan en orden de dificultad reciente para el encargado de la implantación. Aunque los enfoques más difíciles de implementar se convierten en los más rápidos y ya que el analizador léxico no es la más complicada pero si es la única etapa que lee el código fuente esto se puede traducir en tiempo.

3.       PAREJAS DE BUFFERS

Como se puede consumir mucho tiempo moviendo caracteres, se han desarrollado técnicas especializadas en el manejo de buffers para reducir el número de operaciones necesarias para procesar un carácter de entrada.

Se utiliza un buffer dividido en dos mitades de N caracteres cada una (por lo general N es el número de caracteres en un bloque de disco, por ejemplo, 1024 ó 4096). Se leen N caracteres de entrada en cada mitad del buffer con una orden de lectura, en vez de invocar una instrucción de lectura para cada carácter de entrada. Si quedan menos de N caracteres en la entrada, entonces se lee un carácter especial eof, que marca el final del archivo fuente. 

Se mantienen dos apuntadores al buffer de entrada.  La cadena de caracteres entre los dos apuntadores es el lexema en curso.
Al principio, los dos apuntadores apuntan al primer carácter del próximo lexema que hay que encontrar.
Uno de ellos, llamado apuntador delantero, examina hacia delante hasta encontrar una concordancia con un patrón. Una vez determinado el siguiente lexema, el apuntador delantero se coloca en el carácter de su extremo derecho. Después de haber procesado el lexema, ambos apuntadores se colocan en el carácter situado inmediatamente después del lexema.
Cuando el apuntador delantero está a punto de sobrepasar por la marca intermedia del buffer, se llena la mitad derecha con N nuevos caracteres de entrada.
Cuando el apuntador delantero está a punto de sobrepasar el extremo derecho del buffer, se llena la mitad izquierda con N nuevos caracteres de entrada y el apuntador delantero se regresa al principio del buffer.

(Este y el siguiente algoritmo lo escribí interpretando la información que encontré no se puede tomar como base porque no está probado y creo que hasta se puede mejorar en mucho)

If (delantero = final de la primera mitad){
                Recargar la segunda mitad;
                Delantero = delantero + 1;
}
If (delantero = final de la segunda mitad){
                Recargar la primera mitad;
                Pasar delantero al principio de la primera mitad;
}
If(delantero!= final de la primera mitad  &&  delantero!=final de la segunda mitad){
                Delantero=delantero+1;
}

4.       CENTINELAS

El centinela se define como un carácter especial que no puede ser parte del programa fuente. una elección natrual es eof (fin de archivo en ingles), lo que se hace es poner un carácter eof al final de cada mitad para evitar estar haciendo la comprobación con cada lexema, como se encuentran N caracteres de entrada entre los simbolos eof, el promedio de pruebas por cada carácter de entrada es próximo a 1

Delantero=delantero +1;
If (delantero = eof){
                If (delantero = final de la primer mitad){
                               Recargar la segunda mitad;
                               Delantero=delantero+1;
                }
                If(delantero=final de la segunda mitad){
                               Recargar la segunda mitad;
                               Delantero=delantero+1;
                }
                If(delantero!= final de la primera mitad  &&  delantero!=final de la segunda mitad){
                                //eof;
                               Terminar el análisis léxico
                }
}

Fuente de informacion: Wikipedia y  Libro Compiladores Principios Tecnicas Y Herramientas - Aho Sethi Ullman Pearson

martes, 10 de mayo de 2011

Twitter Vs Panaoia Gringa Vs Mal uso de los Terminos

Antes que nada me gustaría definir algunas palabras:

Trending topics (TT): Son las palabras clave más usadas en un momento dado en Twitter. Las keywords de moda, lo que se cuece en el momento, de lo que todo el mundo habla. Por ejemplo #BodaReal #BarcaVsMadril.

América: Nombre dado a un continente, siendo este el segundo más grande del mundo, después de Asia. Ocupa gran parte del Hemisferio Occidental de la Tierra. Debido a su gran tamaño y sus características geográficas, América es dividida tradicionalmente en América del Norte, América Central, las Antillas y América del Sur.

Aclarando este tema podemos deducir que Americano es aquella persona con origen en cualquiera de los países que conforman el continente; Ahora porque todo esto? pues en la madrugada del lunes 9 de mayo de 2011, después de una dolorosa eliminación del equipo América de México, aficionados americanistas vaciaron su frustración en Twitter y de pronto surgió el trend topic "Adiós América" el cual no tardo en llegar al top.

El problema vino cuando twiteros de los Estados Unidos pensaron que el tema "Adiós América" podría referirse a una amenaza terrorista en su contra derivado de la operación militar que asesino al líder de Al Qaeda y ahí empezó la diversión.

 El TT fue retirado de los tópicos mundiales pero reinstalado minutos después cuando personal del propio Twitter explicó el origen del tema, refiriéndose a la eliminación de un equipo mexicano de futbol y no a una amenaza terrorista.

Al final el TT siguió en línea y se creó un nuevo  TT llamado #gringospendejos.


Mis conclusiones serian: Uno que los Gringos tiene razón de estar temerosos y Dos si empezaran a llamarse Estadounidenses y no Americanos en referencia a su nacionalidad nada habría pasado.

miércoles, 4 de mayo de 2011

Flex is a Fast Lexical Analyzer / Generador de analizadores lexicos


Hace unos días en un curso de compiladores, se nos pidió investigar que era LEX y generar un analizador léxico que reconociera una sentencia FOR del tipo for (a=1; a<50; a++), investigando un poco encontré que LEX es un programa para generar scanners o lexers. Lex  fue escrito originalmente por Eric Schmidt y Mike Lesk, es el analizador léxico estándar en los sistemas Unix pero este es un programa propietario ósea licenciado eso hasta donde pude leer, pero existe su versión libre llamada FLEX la cual pueden descargar en su versión 2.5 para Windows desde acá descargar.

 Como funciona pues simple:

1. Se crea un archivo de texto con el código lex se guarda como archivo.l (extensión .l) 
2. Desde línea de comando se compila de esta manera "flex archivo.l"
3. Esto genera en el mismo directorio un archivo  de nombre lex.yy.c (del tipo de código C)
4. Desde cualquier utilitario de C/C++ como  Dev-C se crea  un proyecto y se importa este archivo .c
5. Este archivo debe ser compilado lo cual genera un ejecutable .exe con lo que nosotros pedimos que hiciera.

Acá les pongo un ejemplo como diríamos en Guatemala macheteado de un código lex que analizaría una sentencia FOR correcta, cabe mencionar que todo esto lo hice en unas horas por lo que para expertos en C o en LEX esto podría ser un juego de niños, el codigo ya esta probado y espero les pueda ser util en algun caso.

 /*for ( r = 1; r <= 50; r++ )*/
/* escáner para una sentencia for */

%{
/* se necesita esto para la llamada a atof()*/
#include <math.h>
%}

DIGITO [0-9]
PALABRA for
VARIABLE [a-z]
PI "("
PF ")"
ASIGNA "="
COMPARA <|<=|>|>=|<>
PUNCOM ";"
AUMENTA "+"
ESPACIOS [ \t\n]

%%
{PALABRA}+{ESPACIOS}*+{PI}+{ESPACIOS}*+{VARIABLE}+{ESPACIOS}*+{ASIGNA}+{ESPACIOS}*+{DIGITO}+{ESPACIOS}*+{PUNCOM}+{ESPACIOS}*+{VARIABLE}+{ESPACIOS}*+{COMPARA}+{ESPACIOS}*+{DIGITO}+{ESPACIOS}*+{PUNCOM}+{ESPACIOS}*+{VARIABLE}+{ESPACIOS}*+{AUMENTA}+{AUMENTA}+{ESPACIOS}*+{PF} {
printf( "SENTENCIA FOR CORRECTA: %s (%d)\n\n", yytext,
atoi( yytext ) );
}


{DIGITO}+ {
printf( "ENTERO: %s (%d)\n", yytext,
atoi( yytext ) );
}
{PALABRA}+ {
printf( "PALABRA RESERVADA: %s (%d)\n", yytext,
atoi( yytext ) );
}
{VARIABLE}+ {
printf( "VARIABLE: %s (%d)\n", yytext,
atoi( yytext ) );
}
{PI}+ {
printf( "INICIA: %s (%d)\n", yytext,
atoi( yytext ) );
}
{PF}+ {
printf( "FINALIZA: %s (%d)\n", yytext,
atoi( yytext ) );
}
{ASIGNA}+ {
printf( "ASGINACION DE VALOR: %s (%d)\n", yytext,
atoi( yytext ) );
}
{COMPARA}+ {
printf( "COMPARA: %s (%d)\n", yytext,
atoi( yytext ) );
}
{PUNCOM}+ {
printf( "PUNTO Y COMA: %s (%d)\n", yytext,
atoi( yytext ) );
}
{AUMENTA}+{AUMENTA} {
printf( "AUMENTA VALOR: %s (%d)\n", yytext,
atoi( yytext ) );
}


"{"[^}\n]*"}"
[ \t\n]+
. printf( "CARACTER NO RECONOCIDO: %s\n", yytext );
%%

int yywrap()
{
return(1);
}

main( int argc, char *argv[] )
{
++argv, --argc;
if ( argc > 0 )
yyin = fopen( argv[0], "r" );
else
yyin = stdin;
yylex();
}

martes, 3 de mayo de 2011

Estructura HTML

Siempre he creído que para entender mejor cualquier lenguaje de código, es mejor que te lo expliquen línea por línea, y es lo que trato de hacer con el siguiente código html, les sugiero copiar el código tal como esta en un archivo de tipo .html como "prueba.html" revisarlo, modificarlo y lo que sea necesario para poder entenderlo, si cometi algun error en el codigo les agradecere me lo hagan saber.


Ejemplo Codigo:

<html><!-- Inicia codigo html -->
<head><!-- Inicia cabecera html -->
<!-- Asi se aplican comentarios en html para documentar el codigo  -->

<meta name="description" content="Estructura HTML basico" /> <!-- descripcion general  -->
<meta name="keywords" content="HTML,CSS,XML,JavaScript" /> <!-- Palabras claves separadas por comas que usar los robots de los buscadores  -->
<meta name="author" content="Edsson Gonzalez" /><!-- Autor del html  -->
<meta name="Language" content="Spanish"><!-- Idioma del html  -->
<meta name="robots" content="all | index">
<!-- Si los "Robots" deben tener en cuenta esta página o no:
El valor de content puede ser:
all para que el robot tenga en cuenta esta página y pueda seguir los links contenidos en la misma (este es el valor predeterminado) noindex para que no la tenga en cuenta. none que es lo mismo que noindex, nofollow index para que la tenga en cuenta follow para que pueda seguir los links que haya en la página nofollow lo contrario de follow. -->
<meta http-equiv="Pragma" content="no-cache" ><!-- Esto le indica al navegador que no guarde la página en el caché  -->
<meta http-equiv="Window-target" content="_top" >
<!-- Evitar que una página se muestre dentro de un frame: En Content podemos usar: _top para indicar que se muestre en la página completa, no dentro de un frame, _blank para que se muestre en una nueva ventana -->
<meta http-equiv="Refresh" content="20;url=http://www.nuevaurl.es"><!--Especifica el tiempo en segundos que el explorador tardará en mandarte a una segunda dirección URL -->
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><!-- Define el juego de caracteres a utilizar  -->

<title>Titulo del HTML</title>

<link rel="stylesheet" type="text/css" href="../estilos.css"><!-- Esto sirve para incluir un archivo externo de estilos en nuestro html -->

<!-- a:link, a:visited, a:hover, a:active sirve para definir que pasara con los enlaces publicados en el html, Cuando aparece text-decoration: underline; significa que cuando el cursor este sobre un enlace o link este mostrara una linea debajo de El  -->
<style type="text/css">
a:link {
    color: #039;
    text-decoration: none;
}
a:visited {
    text-decoration: none;
    color: #F00;
}
a:hover {
    text-decoration: underline;
    color: #039;
}
a:active {
    text-decoration: none;
    color: #F00;
}

.estilotitulo {
    font-family: Arial Black, Gadget, sans-serif;
    font-weight: bold;
    color:#039;
    font-size: 30px;
}
-->
</style>

</head><!-- finaliza cabecera html -->

<body><!-- Inicia el cuerpo del html -->

<!-- Para indicar un salto de linea se utiliza la etiqueta <BR> y para un cambio de parrafo (deja una linea en blanco en medio) se utiliza la etiqueta <P> . -->
Este texto tiene <br> saltos de linea y <p> parrafo.

<!--La etiqueta <P> puede usarse también como etiqueta cerrada <P></P> indicando de esta manera los atributos de un párrafo en concreto. Cuando se usa de esta manera tiene el parámetro align que indica al navegador la forma de "justificar" el parrafo. Los valores posibles son LEFT, RIGHT y CENTER , estando aun en estudio el valor JUSTIFY -->
<p align="right">Este es un ejemplo de un parrafo de texto justificado a la derechar </p>

<!-- En un documento de HTML se pueden indicar seis tipos de cabeceras (tamaños de letra) por medio de las etiquetas <H1><H2><H3>... <H1> será la que muestre el texto en mayor tamaño. -->

<h1>Texto de Prueba</h1>
<h2>Texto de Prueba</h2>
<h3>Texto de Prueba</h3>
<h4>Texto de Prueba</h4>
<h5>Texto de Prueba</h5>
<h6>Texto de Prueba</h6>

<!-- Otros atributos del texto -->
<b>Texto con Negrita</b>
<i>Texto en Cursiva</i>
<u>Texto Subrayado</u>
<s>Texto Tachado </s>


<br>
<!-- Aplicando un estilo definido a un texto, arriba creamos .estilotitulo como un conjuntos de caracteristicas que se pueden aplicar a un texto dentro de nuestro html este pude usarse n veces dentro del mismo-->
<span class="Es1"><span class="estilotitulo">texto con estilo titulo aplicado</span></span>

<br>
<!-- Las listas numeradas representarán los elementos de la lista numerando cada uno de ellos segun el lugar que ocupan en la lista. Para este tipo de lista se utiliza la etiqueta <OL></OL> . Cada uno de los elementos de la lista irá precedido de la etiqueta <LI>. -->

<ol>
    <li>Guatemala</li>
    <li>Mexico</li>
    <li>España</li>
</ol>

<!-- IMAGENES Para incluir una imagen en nuestra página Web utilizaremos la etiqueta <IMG> . Hay dos formatos de imagenes que todos los navegadores modernos reconocen. Son las imágenes GIF y JPG . Cualquier otro tipo de fichero gráfico o de imagen (BMP, PCX, CDR, etc...) no será mostrado por el navegador, a no ser que disponga de un programa externo que permita su visualización.
La etiqueta <IMG> tiene varios parámetros :
src = "imagen" Indica el nombre del fichero gráfico a mostrar.
alt = "Texto" Mostrara el texto indicado en el caso de que el navegador utilizado para ver la página no sea capaz de visualizar la imagen.
border = tamaño Indica el tamaño del "borde" de la imagen. A toda imagen se le asigna un borde que será visible cuando la imagen forme parte de un Hyperenlace.
height = tamaño Indica el alto de la imagen en puntos o en porcentaje. Se usa para variar el tamaño de la imagen original.
width = tamaño Indica el ancho de la imagen en puntos o en porcentaje. Se usa para variar el tamaño de la imagen original.
hspace = margen Indica el numero de espacios horizontales, en puntos, que separarán la imagen del texto que la siga y la anteceda.
vspace = margen Indica el número de puntos verticales que separaran la imagen del texto que le siga y la anteceda.
-->

<img src="news.gif" alt="foto" border="0" height="20" width="99"hspace="20" vspace="10" />

<br>
<!-- Enlaces dentro del html -->
<a href = "http://www.twitter.com/" > Pulse para ir a la página de Twitter </a>

<br>
<!--Un Hiperenlace también puede llevarnos a una zona de nuestra página. Para ello debemos marcar en nuestra pagina las diferentes secciones en las que se divide. Lo hare mos con el parametro name -->
<a name = "seccion1" ></a>

<!-- Esta instrucción marca el inicio de una sección dentro de nuestra página. La seccion se llamará seccion1 . Para hacer un enlace a esta sección dentro de nuestra página lo haríamos de la siguiente forma -->
<a href = "#seccion1" > Primera Parte </a>

<br>
<!--  Asimismo podemos hacer que el Hiperenlace de como resultado el envío de un correo electrónico a una dirección de correo determinada. -->
<a href = mailto:usuario@email.dom> Envíame tus sugerencias </a>

<br>
<!--También podemos realizar un Hiperenlace a un fichero cualquiera. En este caso el navegador intentará "ejecutar" el fichero, y si no puede hacerlo nos preguntará si deseamos grabarlo-->
<a href = "manual.zip" > Pulsa aqui para llevarte una copia del manual. </a>


</body><!-- finaliza el cuerpo del html -->
</html><!-- finaliza codigo html -->