domingo, septiembre 25, 2005

Algunas Verificaciones Sintácticas

Parámetros: para limitar que los procedimientos o funciones solo tenga al menos 4 parámetros, se maneja el atributo “Parámetro” en la tabla de símbolos que es de tipo booleano (si el valor esta en verdadero indica que es parámetro, en caso contrario no es parámetro). Además en la tabla se agrego el atributo “Ámbito” el cual guarda el nombre del área de declaración (ya sea global, función o procedimiento). La búsqueda de la cantidad de parámetros se realiza mediante los atributos “Ámbito, Expresión (ó variables) y Parámetro”, se captura todas las expresiones de un ámbito y luego por medio de un contador se va aumentado si el parámetro es verdadero. Al final si el contador es mayor que 4 se despliega un mensaje de error, esta operación se realiza hasta recorrer todas las expresiones de los ámbitos.

Duplicados globales: Como ya se tiene almacenados toda la información (expresión, tipo, ámbito, línea, columna, parámetro, lexema) de las variables en la tabla de símbolos, primero se capturan todas la variables globales y después se hace una búsqueda en las variables locales, si se encuentra una variable local declarada igual a una variable global, el programa despliega un mensaje de error.

Verificación local: se despliega error si alguno de los parámetros tiene el mismo nombre que su función o procedimiento padre. También verifica que no se declaran variables con el mismo nombre que su función o procedimiento padre. Para ambos casos se despliega un mensaje de error.

Verificación de Tipos: esta verificación se realiza dentro del parser, cuando el parser llega a la gramática en donde se realizan las asignaciones (variable:=valor), primero tomo la información (texto, línea, columna) de la variable y la información del valor, segundo la tabla de símbolos cuanta con una función (sus parámetros son una expresión y el ámbito de la expresión) que retorna el tipo de la expresión (ó variable ó valor). Como ya tenemos el tipo de la variable y del valor ahora se verifican los siguientes casos:
  1. El valor es un Entero (variable:=12), este debe cumplir que la variable sea también de tipo entero.

  2. El valor es un carácter (variable:=”c”), este debe cumplir que la variable sea también de tipo carácter.

  3. El valor es un String (variable:=’hola’), no se pueden aplicar Strings a variables de tipo entero o carácter.

  4. Si retorna que el valor no tiene tipo es porque se esta aplicando una asignación a un procedimiento.

  5. El caso en donde los dos son identificadores (el valor puede ser un identificador simple o un a función) , simplemente se hace una comparación de los tipos, si no coinciden se despliega un error

  6. Nota: en este momento no se esta verificando el tipo de asignaciones complejas (x:=a+b)

domingo, septiembre 18, 2005

Tabla de Smbolos

Clase que mantiene los tokens que se son leídos durante la compilación, hasta el momento solamente por el analizador léxico (solo por prueba), esto no debería ser así, si no cuando se ejecute el parser empezar a ingresar.

package TurboDragon;
import java_cup.runtime.*;
import java.util.*;

public class ClsTablaSimbolos {
private ArrayList Linea = new ArrayList();
private ArrayList Columna = new ArrayList();
private ArrayList Lexema = new ArrayList();
private ArrayList Expresion = new ArrayList();
public ClsTablaSimbolos() { }

public void AddSymbol( ClsObjectToken objectToken ) {
this.Expresion.add( objectToken.GetExpresion() );
this.Lexema.add( objectToken.GetLexema() );
this.Linea.add( objectToken.GetLinea() );
this.Columna.add( objectToken.GetColumna() );
}

public void DelSymbol( int index ) {
this.Expresion.remove(index);
this.Lexema.remove(index);
this.Linea.remove(index);
this.Columna.remove(index);
}

public void ClearTable() {
this.Expresion.clear();
this.Lexema.clear();
this.Linea.clear();
this.Columna.clear();
}

public boolean ExistSymbol( Object expresion ){
return this.Expresion.contains(expresion);
}

public int FindSymbol( Object expresion ){
return this.Expresion.indexOf(expresion);
}

public int SizeTable(){
return this.Expresion.size();
}

public ClsObjectToken GetSymbol( int index ) {
return new ClsObjectToken( this.Expresion.get(index), this.Lexema.get(index), this.Linea.get(index), this.Columna.get(index) );
}
}

La clase ClsObjectToken es la que mantiene los atributos del token, como ser la expresión, el lexema o al tipo que pertenece, la línea y la posición del token.

domingo, septiembre 04, 2005

Comentarios Abiertos

Comentarios Abiertos sin Cerrar

Para resolver este problema utiliza la ayuda de una clase “ClsComments”, la cual lleva un control sobre los comentarios que han sido abiertos y cerrados, cada vez que se abre un comentario la clase cuenta con una ArrayList que guarda tipos boléanos (inicialmente esta con el valor falso) y cambia a valor verdadero cuando encuentra que se cerro el comentario, al terminar de leer el archivo (Fin de Archivo), se recorre el ArrayList y si encuentra con un comentario con valor falso, retorna un mensaje de error. Esta clase funciona dentro del lexer, cada vez que encuentre el estado de comentario la clase empieza a llevar el control de los comentario (Encontró Comentario Abierto, valor es igual a falso, este valor cambiara hasta que encuentre el comentario cerrado). Se implemento un ArrayList ya que cada vez que se encuentra un comentario abierto se crea un Objeto (que guarda la línea, la posición y el valor booleano).

public class ClsComments {
    private ArrayList Linea = new ArrayList();
    private ArrayList Columna = new ArrayList();    
    private ArrayList FinComments = new ArrayList();    
    
    public ClsComments() { }

    public void NewComment(int Row, int Col ) {
        Linea.add( String.valueOf(Row) );
        Columna.add( String.valueOf(Col) );
    }

    public void FinComentario( boolean Value ) {
        FinComments.add( String.valueOf(Value) );        
    }

    public int getLinea( int index ){      
        int value=0;
        try {
            value = Integer.valueOf( Linea.get(index).toString() ).intValue();            
        } catch(Exception e) {}
        return value;
    }

    public int getColumna( int index ) {
        int value = 0;
        try {
            value = Integer.valueOf( Columna.get(index).toString() ).intValue();            
        } catch(Exception e) {}        
        return value;
    }

    public boolean getFinComentario(int index) {
        boolean value=false;
        try {
            value = Boolean.valueOf( FinComments.get(index).toString() ).booleanValue();            
        } catch(Exception e) {}        
        return  value;
    }  

    public void newFinComentario( int index, boolean Value ) {
        FinComments.set(index,String.valueOf(Value) );
    }

    public int Len() {
        return Linea.size();
    }

    public void Limpiar() {
        Linea.clear();
        Columna.clear();
        FinComments.clear();
    }

}

domingo, agosto 28, 2005

Informe Avance Proyecto # 1 (Parte 2)

Puntos alcanzados del proyecto:


  • Verificación de comentarios tipo:”{ … }”

//-- Comentario Sin Abrir "}"
<YYINITIAL> {TK_COMENTARIOCERRADO_1}* {
ClsErrores Handler = new ClsErrores();
Handler.Error( 2, yyline, yychar );
}
//-- Comentario Sin Abrir "*)"
<YYINITIAL> {TK_COMENTARIOCERRADO_2}* {
ClsErrores Handler = new ClsErrores();
Handler.Error( 2, yyline, yychar );
}
//-- Verifica el tipo de comentario "{ ... }"
<YYINITIAL> {TK_COMENTARIOABIERTO_1} { yybegin(COMMENTS1); }
<COMMENTS1> [^({TK_COMENTARIOABIERTO_2TK_COMENTARIOCERRADO_2})] { /**/ }
<COMMENTS1> {TK_COMENTARIOCERRADO_1} { yybegin(YYINITIAL); }
//-- Si dentro de un comentario "{ ... }" se encuentra "(*" se toma como comentario anidado
<COMMENTS1> {TK_COMENTARIOABIERTO_2}* {
yybegin(YYINITIAL);
ClsErrores Handler = new ClsErrores();
Handler.Error( 1, yyline, yychar );
}
//-- Si dentro de un comentario "{ ... }" se encuentra "*)" se toma como comentario anidado
<COMMENTS1> {TK_COMENTARIOCERRADO_2}* {
yybegin(YYINITIAL);
ClsErrores Handler = new ClsErrores();
Handler.Error( 1, yyline, yychar );
}
//-- Si dentro de un comentario "{ ... }" se encuentra "{" se toma como comentario anidado
<COMMENTS1> {TK_COMENTARIOABIERTO_1}* {
yybegin(YYINITIAL);
ClsErrores Handler = new ClsErrores();
Handler.Error( 1, yyline, yychar );
}


  • Verificación de comentarios tipo:”(* … *)”

//-- Verifica el tipo de comentario "(* ... *)"
<YYINITIAL> {TK_COMENTARIOABIERTO_2} { yybegin(COMMENTS2); }
<COMMENTS2> [^({}TK_COMENTARIOABIERTO_2TK_COMENTARIOCERRADO_2)] { /**/ }
<COMMENTS2> {TK_COMENTARIOCERRADO_2} { yybegin(YYINITIAL); }
//-- Si dentro de un comentario "(* ... *)" se encuentra "{" se toma como comentario anidado
<COMMENTS2> {TK_COMENTARIOABIERTO_1}* {
yybegin(YYINITIAL);
ClsErrores Handler = new ClsErrores();
Handler.Error( 1, yyline, yychar );
}

//-- Si dentro de un comentario "(* ... )*" se encuentra "}" se toma como comentario anidado
<COMMENTS2> {TK_COMENTARIOCERRADO_1}* {
yybegin(YYINITIAL);
ClsErrores Handler = new ClsErrores();
Handler.Error( 1, yyline, yychar );
}

//-- Si dentro de un comentario "(* ... )*" se encuentra ")*" se toma como comentario anidado
<COMMENTS2> {TK_COMENTARIOABIERTO_2}* {
yybegin(YYINITIAL);
ClsErrores Handler = new ClsErrores();
Handler.Error( 1, yyline, yychar );
}

Nota: en la verificación de comentarios no se ha definido cuando el comentario es abierto, pero no se ha cerrado, ¿Alguna sugerencia?



Informe Avance Proyeto #1 (Parte 1)

Puntos Alcanzados del proyecto:

  • Validar el tamaño de declaración de un Identificador

<YYINITIAL> {IDENTIFICADOR} {
int Len = yytext().length();
if (Len>12) {
ClsErrores Handler = new ClsErrores();
Handler.Error( 10, yyline, yychar );
}
else {
return new Symbol( sym.IDENTIFICADOR, new TokenValue( yytext(), yyline, yychar ) );
}
}

  • Validar Strings

//-- Definicion para identificar cadenas de String
<YYINITIAL> {TK_APOSTROFE} { yybegin(STRING); }
<STRING>[^(\n'{}TK_COMENTARIOABIERTO_2TK_COMNETARIOCERRADO_2TK_APOSTROFE_2)] { string.append( yytext() ); }
<STRING> {TK_APOSTROFE} {
yybegin(YYINITIAL);
int Len = string.length();
if (Len>255) {
ClsErrores Handler = new ClsErrores();
Handler.Error( 5, yyline, yychar );
}
else {
return new Symbol( sym.STRINGCONST, new TokenValue( string.toString(), yyline, yychar ) );
}
}
<STRING> {TK_APOSTROFE_2} { string.append( "\'" ); }
<STRING> [{] { string.append( "{" ); }
<STRING> [}] { string.append( "}" ); }
<STRING> {TK_COMENTARIOABIERTO_2} { string.append( "(*" ); }
<STRING> {TK_COMENTARIOCERRADO_2} { string.append( "*)" ); }
//-- Si encuentra un salto de linea se determina como cadena invalida
<STRING> [\n] {
yybegin(YYINITIAL);
ClsErrores Handler = new ClsErrores();
Handler.Error( 6, yyline, yychar );
}

  • Validar Carácter

//-- Definicion para identificar caracter
<YYINITIAL> {TK_COMILLA} { yybegin(CARACTER); }
<CARACTER> [^(\n\")] { caracter.append( yytext() ); }
<CARACTER> {TK_COMILLA} {
yybegin(YYINITIAL);
int Len = caracter.length();
System.out.println(caracter.toString());
if (Len==0) {
ClsErrores Handler = new ClsErrores();
Handler.Error( 8, yyline, yychar );
}
else if (Len>1) {
ClsErrores Handler = new ClsErrores();
Handler.Error( 7, yyline, yychar );
}
else {
return new Symbol( sym.CHARCONST, new TokenValue( caracter.toString(), yyline, yychar ) );
}
}

  • Validar Número

<YYINITIAL> {NUMERO} {
Integer Numero = new Integer( yytext() );
int Num = Numero.intValue();
if (Num<-65536 Num>65536){
ClsErrores Handler = new ClsErrores();
Handler.Error( 4, yyline, yychar );
}
else {
return new Symbol( sym.NUMERO, new TokenValue( yytext(), yyline, yychar ) );
}
}

  • Validar Números que empiecen con 0 amenos que sea el valor cero.

//-- Validacion para el token Número (no debe comenzar con cero a menos que sea el valor cero)
<YYINITIAL> [0]+[0-9]* {
yybegin(YYINITIAL);
ClsErrores Handler = new ClsErrores();
Handler.Error( 9, yyline, yychar );
}

domingo, agosto 21, 2005

Interfaz gráfica & Lexer
El ambiente grafica consta de tres áreas:
  1. Menú: esta formado por el menú “opciones” y “Ayuda”. El menú “Opciones” presenta las opciones de poder cargar un archivo ya sea un programa de pascal o un archivo de texto. Además, presenta la opción de poder compilar el archivo cargado (cada vez que se compile se guardara el archivo y se ejecutara el Lexer y el Parser) y por ultimo se cuenta con la opción de salir del programa. El menú “Ayuda” brinda información sobre el programa y sobre su desarrollador.
  2. Editor de Texto: es en donde se podrá editar código pascal este presentara en el lado izquierdo presentara la línea de código, en la parte inferior derecha presentara la columna en donde se encuentra actualmente y en la parte superior del editor se muestra la dirección del programa actualmente editando.
  3. Mensajes de Error: es la parte en donde se muestra la serie de problemas que se encontraron al momento de compilar el programa, aquí se muestra el tipo de error y la posición en donde se encuentra.

    Lexer: es la fase en donde se identifican si las palabras reservadas del lenguaje, identificadores, números, caracteres, Strings, comentarios cumplen con las reglas definidas por el programador. Para realizar el analizador léxico se esta utilizando el pluging “ANTLR” (me oriente a utilizar este pluging ya que lo encontré un poco mas sencillo de utilizar). Como primer paso fue crear un archivo en donde se encontrara la definición del Lexer, es aquí en donde se establecen los tokens para las palabras reservadas, operadores lógicos y otros signos que pertenecen al alfabeto del lenguaje de pascal como ser: ‘.’, ‘;’, ‘(‘, ‘)’, etc. Además, se aplicaron los métodos visto en clase para definir lo que son dígitos, letras y con estos poder definir lo que son números, identificadores.

    Problemas:
    1.) la restricción de que los números no pueden empezar con el digito cero a menos que este representado el valor cero, Mi definición para número es “NUMERO: ‘0’(‘1’..’9’)(DIGITO)*”, ahora cuando lo compilo y encuentra por ejemplo el numero 001 me retorna que no se encontró ningún error y entiendo por que se así, aquí va mi pregunta ¿El Lexer es el que detecta esta restricción o es el parser?

    2.) Otro problema que tengo es cuando aplico la definición para identificadores “ID:LETRA(LETRADIGITO)*” para palabras largas (“Ej: paleontologo”) no me las acepta, pero si captura palabras pequeñas y estas si son aceptadas.

miércoles, agosto 17, 2005

Editor Grafico de Turbo Dragon

El editor de pascal cuenta con las opciones de poder cargar archivos de pascal (*.pas) y archivos de texto, además el editor muestra en la parte izquierda el número de línea de cada línea de código que este contenido en el archivo. Al momento de compilar el código se mostrara todos los errores generados en un área de texto no editable en la cual se mostrar información acerca del error y en que posición se encuentra.

Nota: Todas las palabras reservadas se mostraran en negrita, Ej.: “for i=1 to 10”

¿Porque micro-pascal?, lo habia definido así por las restricciones que se tiene, como ser que solo numeros enteros, limite de parametros de funciones, etc.



domingo, agosto 07, 2005

Laboratorio # 1

Al principio tuve problemas para configurar las opciones jflex.bat, ya que la ruta el path de java no estaba correcto, por lo cual estuve un buen rato tratando de corregirlo, además, no sabia que el comando rem significaba comentarios.

Al no tener correcto el path de java no podía compilar Cup, pero después de corrgir el path todo salio muy bien. Después de esto no tuve problemas la generar el archivo yyler.java.

Tuve problemas para poder compilar los archivos parser.java, sym.java y yylex.java, me genero varios errore, los cuales quise corregir pero no puede llegar a compilar el archivo yylex.java, ya que no estaban definidas en la clase sym, algunos términos como “TIMES, PLUS, etc”, por consiguiente no pude correr Example.parser ni tampoco realizar los cambios que requería el laboratorio # 1.
También tuve problemas para aplicar las opciones de jflex en eclipse, no entendí muy bien que es lo que debía realizar.
Para el inciso de que solo acepte número menores que 64, primero construi una expresión regular en donde solamente incluyo los digitos del 0 al 64, cuando ingreso el numero aplico la expresión y si ese número no se encuentra definido muestro un mensaje de error.
para cambiar que la operacion se ejecutara con el ENTER y no con el punto y como, en el estado inicial verifico cuando se encuentre con una nueva linea...si la encuentra entonces ejecuta la operación.
Para generar la documentación del programa en Netbeans 3.6 es en la opción de generar Javadoc, primero debemos seleccionar la ubicación en donde se encuentra el archivo ejecutable de javadoc, que generalmente es en donde instalamos -j2sdk1-

Otra forma de verificar que el numero ingresado sea menor que 64, es mediante la función Yytext() (devuelve un String), la cual mantiene la información que se ingreso, este valor lo convertimos en su valor entero mediante la clase Integer, y luego verificamos que este valor entero sea menor que 64.
Eclipse Vs. Netbeans

El primer compilador de Java que utilice fue Netbeans 3.6, es una herramienta muy completa, el cual ofrece un entorno muy fácil de utilizar, y al que me he acostumbrado a usar. Una de las desventaja de Netbeans 3.6 es el consumo de recursos y pensé, es Java! así deben ser los compiladores, Pero no! Después de haber instaldo Eclipse compare el consumo de recursos entre ambos, y resulto que Eclipse consume menos recursos que Netbeans 3.6. Empecé a navegar en el entorno de Eclipse, el cual tiene a primera vista un bonito entorno. Eclipse es muy parecido a netbeans 3.6, lo cual me parece muy perfecto ya que estoy acostumbrado a Netbeans 3.6 y mucho mejor no consume muchos recursos.Algo que no me gusta es que Eclipse no hace diferencia de los "main Class", sino que hay que estar asignando mediante "Run..."cual es el Main. En cambio en Netbeans 3.6 si hace la diferencia y uno solo ejecuta el main que desea correr sin tener antes que asignar cual en "Main Class"

domingo, julio 31, 2005

Just In Time Compiler: En la programación y ambiente Java, JIT compiler es un programa trasforma bytecode de Java (un programa que contiene instrucciones que deben interpretarse) en instrucciones que pueden enviarse directamente al procesador. El bytecode es código plataforma-independiente que puede enviarse y correrse en cualquier plataforma. Además permite una mejor actuación de los programas

Links:
Compiler-Compilers: Es una herramienta de depuración que utilizan los escritores de compiladores (sistemas para ayudar en el proceso de escritura de compiladores), que como cualquier programador puede usar con provecho. Esta herramienta se orienta en torno a modelos particulares de lenguaje y son más adecuados para generar compiladores de lenguajes similares al de los modelos. En pocas palabras es un traductor que tiene como entrada la definición de un lenguaje y como salida el compilador para dicho lenguaje.

Links:


  1. http://www.monografias.com/trabajos11/compil/compil2.shtml
  2. http://algebra.iespana.es/compiladores.htm

Cross-Compiler: Compiladores que pueden ejecutarse en una máquina y produce código objeto para otra máquina.

Links:

  1. http://www.pc-actual.com/Pr%C3%A1ctico/Microconsultas/Inform%C3%A1tica_personal/Linux/20040730014
  2. http://compiler.area51.ipupdater.com/
Intérprete: Acepta programas escritos en un lenguaje de alto nivel, los analiza y los ejecuta bajo control del propio intérprete. En este caso, no se genera un programa equivalente en otro lenguaje, como ocurre con un compilador por lo que, si se desea repetir la ejecución del programa, es preciso volver a traducirlo.

Los programas interpretados suelen ser más lentos que los compilados, pero los intérpretes son más flexibles como entornos de programación y depuración.

¿No entendiste?...bueno ahí te va una Analogía: Comparando su actuación con la de una persona, un compilador equivale a un traductor profesional que, a partir de un texto, prepara otro independiente traducido a otra lengua, mientras que un intérprete corresponde al intérprete humano, que traduce de viva voz las palabras que oye, sin dejar constancia por escrito.
En la actualidad el entorno más común de uso de los intérpretes informáticos es Internet, debido a la posibilidad que éstos tienen de ejecutarse independientemente de la plataforma.

Ejemplos: PHP, Javascript, ASP (hasta la versión 3) y HTML son ejemplos de lenguajes interpretados.

Links:
Maquinas Virtuales: El concepto de máquinas virtuales consiste en la posibilidad de ejecutar simultáneamente varios sistemas operativos en una misma máquina, de modo que cada uno de ellos "crea" que tiene una máquina dedicada para si mismo.

Por Ejemplo: La máquina virtual "VMWare" debido a que permite aplicar este concepto sobre PC's (linux o windows). Un Poco de Historia: El concepto de virtualización lo introdujo IBM en sus sistemas operativos hace unos 20 años. También de esta misma compañía viene, a mi entender, el logro más espectacular con respecto a la virtualización del hardware. Lograron ejecutar más de 44.000 Sistemas Operativos Linux simultáneamente en la misma máquina real!!!

¿Has Escuchado el Termino...JAVA?: Cuando una persona desarrolla una aplicación en un lenguaje como C o C++, el archivo binario que genera el compilador y que contiene el código que implementa dicha aplicación, se puede ejecutar únicamente sobre la plataforma sobre la cual fue desarrollada, debido a que dicho código es especifico a esa plataforma.

La plataforma Java se encuentra por encima de otras plataformas. El código que generan sus compiladores no es específico de una maquina física en particular, sino de una máquina virtual. Aún cuando existen múltiples implantaciones de la Máquina Virtual Java, cada una específica de la plataforma sobre la cual subyace, existe una única especificación de la máquina virtual, que proporciona una vista independiente del hardware y del sistema operativo sobre el que se esté trabajando. De esta manera un programador en Java “escribe su programa una vez, y lo ejecuta donde sea”

Ventajas: La primera es que presentan un medio excelente para alcanzar la portabilidad y no cabe duda que introduce otro nivel de abstracción y de protección, entre la computadora y el software que ejecuta sobre ella. Esto cobra particular importancia en un ambiente donde el código que ejecutamos proviene de algún lugar del mundo y es escrito por alguna "buena" persona.

Desventaja: Los lenguajes basados en máquina virtual son más lentos que los lenguajes completamente compilados, debido a la sobrecarga que genera tener una capa de software intermedia entre la aplicación y el hardware de la computadora.


Links:

  1. http://labsopa.dis.ulpgc.es/so-itig/tema3/tsld027.htm
  2. http://www.enbytes.com/noticias/enbytesidf03.htm
  3. http://www.microsoft.com/spain/windowsxp/virtualpc/evaluation/overview2004.asp

miércoles, julio 20, 2005

¿Qué es un Ing. de Sistemas para Mí?

Es una leyenda Personal, un paso mas para finalizar un capitulo de la vida, con el cual me ayuda a iniciar otro. Es una clasificación eduacativa y social que inicia a la persona a desarrollarse como independiente e interactuar en un ambiente de resposanbilidad con el fin de ayudar a eliminar obstaculos que intervienen ha alcanzar nuestro proposito: "Satisfacer nuestras necesidades"