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();
    }

}