Skip to content

Instantly share code, notes, and snippets.

@RicardoLara
Last active December 15, 2015 03:19
Show Gist options
  • Save RicardoLara/5193852 to your computer and use it in GitHub Desktop.
Save RicardoLara/5193852 to your computer and use it in GitHub Desktop.
Motor de Karel en Java... Incompleto y con Dudas Existenciales.
package karelmovil;
import java.util.LinkedList;
import java.io.BufferedReader;
import java.io.IOException;
public class KLexer {
public final char ESTADO_ESPACIO = ' ';
public final char ESTADO_PALABRA = 'a';
public final char ESTADO_COMENTARIO = '#';
public final char ESTADO_NUMERO = '0';
public final char ESTADO_SIMBOLO = '+';
private char ultimo_caracter;
private char caracter_actual;
private char abrir_comentario; //Indica cómo fue abierto un comentario
private char estado;
private BufferedReader lector_buffer;
public final String numeros = "0123456789";
public final String palabras = "abcdfeghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-";
public final String simbolos = "(){}*/;,"; //Simbolos permitidos para esta sintaxis
public final String espacios = " \n\t\r";
public final String caracteres = this.numeros+this.palabras+this.simbolos+this.espacios;
public String nombre_archivo;
public String token;
public String sintaxis;
public char linely_chars[6];
//**********************************public String posicion
private LinkedList<KToken> pila_tokens; //Pila de tokens por si me lo devuelven
public int linea;
public int columna;
private boolean tiene_cambio_de_linea;
private boolean debug;
private boolean char_pushed;
public KLexer(BufferedReader archivo, String nombre_archivo, boolean debug){
/*Se construye el analizador con el nombre del archivo*/
//this.archivo = archivo;
this.lector_buffer = archivo;
this.nombre_archivo = nombre_archivo;
this.ultimo_caracter = '';
this.caracter_actual = '';
this.abrir_comentario = '';
this.pila_tokens = new LinkedList<KToken>();
this.char_pushed = false;
this.linea = 1; //El número de linea
this.columna = 0; //El número de columna
this.tiene_cambio_de_linea = false;
this.token = "";
this.estado = this.ESTADO_ESPACIO;
// ************************this.poscicion = ktoken.POSICION_INICIO;
this.sintaxis = "pascal";
this.lonely_chars[] = { ';','{','}','!' };
this.debug = debug;
if (this.debug)
System.out.println("leyendo archivo '"+this.nombre_archivo+"'");
}
public void establecer_sintaxix(String sintaxis)
{
if(sintaxis == "java")
{
this.lonely_chars[5] = '(';
this.lonely_chars[6] = ')';
this.sintaxis = sintaxis;
}
this.sintaxis = sintaxis;
}
public Character lee_caracter() throws IOException{
/*Lee un caracter de la fuente o devuelve uno de la pila si no
está vacía*/
this.ultimo_caracter = this.caracter_actual;
return (char)this.lector_buffer.read();
}
public KToken get_token() throws KarelException{
/*Obtiene el siguiente token. Si la pila tiene tokens le quita
uno, si no, obtiene el siguiente token del archivo*/
if (this.pila_tokens.size()>0)
return (KToken)this.pila_tokens.pop();
else
return this.lee_token();
}
public void push_token(KToken token){
/*Empuja un token en la pila*/
this.pila_tokens.push(token);
}
public KToken lee_token() throws KarelException{
/*Lee un token del archivo*/
while(true){
this.columna += 1;
if( !this.caracter_actual)
break;
if(this.tiene_cambio_de_linea){
this.linea += 1;
this.columna = 0;
this.tiene_cambio_de_linea = false;
}
if (this.estado == this.ESTADO_COMENTARIO){
if (this.debug)
System.out.println("Encontré '"+this.caracter_actual+"' en estado comentario");
if (this.simbolos.indexOf(this.caracter_actual) != -1){ //Lo que puede pasar es que sea basura o termine el comentario
if (this.caracter_actual == ')' && this.abrir_comentario == '(*' && this.ultimo_caracter == '*')
this.estado = this.ESTADO_ESPACIO;
if (this.caracter_actual == '}' && this.abrir_comentario == '{')
this.estado = this.ESTADO_ESPACIO;
if (this.caracter_actual == '/' && this.abrir_comentario == '/*' && this.ultimo_caracter == '*')
this.estado = this.ESTADO_ESPACIO;
} else if(this.caracter_actual == '\n')
this.tiene_cambio_de_linea = true;
} else if (this.estado == this.ESTADO_ESPACIO){
if (this.debug)
System.out.println("Encontré '" + this.caracter_actual + "' en estado espacio");
if (! (this.caracteres.indexOf(this.caracter_actual)!=-1))
throw new KarelException("Caracter desconocido ("+(int)this.caracter_actual+") en la linea "+this.linea+" columna "+this.columna);
if (this.numeros.indexOf(this.caracter_actual)!=-1){
this.token += this.caracter_actual;
this.estado = this.ESTADO_NUMERO;
}else if (this.palabras.indexOf(this.caracter_actual)!=-1){
this.token += this.caracter_actual;
this.estado = this.ESTADO_PALABRA;
}else if (this.simbolos.indexOf(this.caracter_actual)!=-1){
this.push_char(this.caracter_actual); //Podria ser algo valido como ();,
this.estado = this.ESTADO_SIMBOLO;
}else if (this.caracter_actual == '\n')
this.tiene_cambio_de_linea = true;
}else if (this.estado == this.ESTADO_NUMERO){
if (this.debug)
System.out.println("Encontré '" + this.caracter_actual + "' en estado número");
if (!(this.caracteres.indexOf(this.caracter_actual)!=-1))
throw new KarelException("Caracter desconocido ("+(int)this.caracter_actual+") en la linea "+this.linea+" columna "+this.columna);
if (this.numeros.indexOf(this.caracter_actual)!=-1)
this.token += this.caracter_actual;
else if(this.palabras.indexOf(this.caracter_actual)!=-1) //Encontramos una letra en el estado numero, incorrecto
throw new KarelException("Este token no parece valido, linea "+this.linea+" columna "+this.columna);
else if (this.simbolos.indexOf(this.caracter_actual)!=-1){
this.estado = this.ESTADO_SIMBOLO;
this.push_char(this.caracter_actual);
break;
}else if(this.espacios.indexOf(this.caracter_actual)!=-1){
if (this.caracter_actual == '\n')
this.tiene_cambio_de_linea = true;
this.estado = this.ESTADO_ESPACIO;
break; //Terminamos este token
}
}else if (this.estado == this.ESTADO_PALABRA){
if (this.debug)
System.out.println("Encontré '"+this.caracter_actual+"' en estado palabra");
if (! (this.caracteres.indexOf(this.caracter_actual)!=-1))
throw new KarelException("Caracter desconocido ("+(int)this.caracter_actual+") en la linea "+this.linea+" columna "+this.columna);
if (this.palabras.indexOf(this.caracter_actual)!=-1 || this.numeros.indexOf(this.caracter_actual)!=-1)
this.token += this.caracter_actual;
else if (this.simbolos.indexOf(this.caracter_actual)!=-1){
this.estado = this.ESTADO_SIMBOLO;
this.push_char(this.caracter_actual);
break;
}else if (this.espacios.indexOf(this.caracter_actual)!=-1){
if (this.caracter_actual == '\n')
this.tiene_cambio_de_linea = true;
this.estado = this.ESTADO_ESPACIO;
break; //Terminamos este token
}
//****************************** De aquí para abajo falta.
}else if (this.estado == this.ESTADO_SIMBOLO){
if (this.debug)
System.out.println("Encontré '"+this.caracter_actual+"' en estado símbolo");
if (! (this.caracteres.indexOf(this.caracter_actual)!=-1))
throw new KarelException("Caracter desconocido ("+(int)this.caracter_actual+") en la linea "+this.linea+" columna "+this.columna);
if (this.caracter_actual == '{'){
this.abrir_comentario = '{';
this.estado = this.ESTADO_COMENTARIO;
}else if(this.numeros.indexOf(this.caracter_actual)!=-1){
this.estado = this.ESTADO_NUMERO;
this.push_char(this.caracter_actual);
if (this.token.length()>0)
break;
else
continue;
}else if (this.palabras.indexOf(this.caracter_actual)!=-1){
this.estado = this.ESTADO_PALABRA;
this.push_char(this.caracter_actual);
if (this.token.length()>0)
break;
}else if (this.simbolos.indexOf(this.caracter_actual)!=-1){
if (this.ultimo_caracter == '('){
if (this.caracter_actual == '*'){
this.token = "";
this.estado = this.ESTADO_COMENTARIO;
this.abrir_comentario = '(';
continue;
}else{
this.push_char(this.caracter_actual);
break;
}
}else if (this.caracter_actual != '('){ //el único símbolo con continuación
this.token += this.caracter_actual;
break;
}else{
this.token += this.caracter_actual;
continue;
}
}else if (this.espacios.indexOf(this.caracter_actual)!=-1){
if (this.caracter_actual == '\n')
this.tiene_cambio_de_linea = true;
this.estado = this.ESTADO_ESPACIO;
}
}
}
String tokens = this.token;
this.token = "";
return new KToken(tokens, this.linea, this.columna, this.posicion);
}
public KToken next() throws StopIterationException,KarelException{
/*Devuelve un token de la pila si no está vacía o devuelve el
siguiente token del archivo, esta función sirve al iterador de
tokens*/
KToken tokenn = this.get_token();
if (tokenn.token.equals(""))
throw new StopIterationException("Se acabaron los tokens");
return tokenn;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment