Sp-ps1 : generación de código java para un análisis léxico (página 3)
Enviado por FRANCISCO RIOS ACOSTA
Ing. Francisco Ríos Acosta SP-PS1 : generación de código java para un análisis léxico Instituto Tecnológico de la Laguna, julio del 2009. pag. 14 de 29 Fig. No. 5.5 Simulación del analizador léxico. Fig. No. 5.6 Código java generado por SP-PS1 : clases Lexico y Automata.
Ing. Francisco Ríos Acosta SP-PS1 : generación de código java para un análisis léxico Instituto Tecnológico de la Laguna, julio del 2009. pag. 15 de 29 6 Clase Lexico y clase Automata. Las clases generadas por el programa SP-PS1 no hacen sino implementar las ideas plasmadas por Aho, Sethi y Ulman en su libro del dragón. De acuerdo a lo anterior , se hace un esbozo de lo que significan los segmentos de código java generados para cada clase, tanto de la clase Lexico como de la clase Automata. Clase Lexico.
//————————————— // clase Lexico //————————————— public class Lexico { final int TOKREC = 7; final int MAXTOKENS = 500; private String[] _lexemas; private String[] _tokens; private String _lexema; private int _noTokens; private int _i; private int _iniToken; private Automata oAFD;
public Lexico() // constructor por defecto { _lexemas = new String[MAXTOKENS]; _tokens = new String[MAXTOKENS]; oAFD = new Automata(); _i = 0; _iniToken = 0; _noTokens = 0; }
public void Inicia() { _i = 0; _iniToken = 0; _noTokens = 0; _lexemas = new String[MAXTOKENS]; _tokens = new String[MAXTOKENS]; } public void Analiza(String texto) { Boolean recAuto; int noAuto; while (_i < texto.length()) { recAuto=false; noAuto=0; for(;noAuto< TOKREC&&!recAuto;) if(oAFD.Reconoce(texto,this,noAuto)) recAuto=true; else noAuto++; if (recAuto) { _lexema = texto.substring(_iniToken, _i); switch (noAuto) { //————– Automata delim————– case 0 : _tokens[_noTokens] = "delim"; break; //————– Automata Id————– case 1 : _tokens[_noTokens] = "Id"; break; //————– Automata OpAsig————– case 2 : _tokens[_noTokens] = "OpAsig"; break; //————– Automata oparit————– case 3 : _tokens[_noTokens] = "oparit";
La constante TOKREC contiene al número de tokens a reconocer. MAXTOKENS es el número máximo de parejas tokens-lexema que se pueden almacenar en los arreglos _tokens y _lexemas. _lexemas representa al arreglo donde se almacena al lexema correspondiente al token reconocido. _tokens es un arreglo que contiene al token reconocido su clasificación-. _lexema es una cadena que contiene al lexema del token que se reconoce en un determinado instante en la ejecución del análisis léxico. _noTokens es el número de tokens que se han reconocido. _i es un puntero al caracter en el texto de entrada que se lee durante el reconocimiento. _iniToken tiene al caracter donde se inicia el reconocimiento del siguiente token. oAFD es un objeto que contiene a los TOKREC autómatas traducidos a implementación en código.
Constructor de la clase
Inicializa al objeto perteneciente a la clase Lexico. Igual en código al constructor. Establece los límites del reconocimiento desde el índice 0 al texto.length()-1 Es el ciclo que implementa el uso de los AFDs óptimos contenidos en el objeto oAFD para reconocer un token. La variable noAuto representa al número del AFD que el analizador léxico utiliza en el ciclo para tratar de realizar el reconocimiento de un token.
La sentencia if se encarga de probar si se ha reconocido a un token en el ciclo del for. La variable noAuto contiene al número del autómata que ha efectuado el reconocimiento exitoso. En el atributo _lexema se almacena al lexema del token reconocido. El switch() permite guardar al token reconocido.
Ing. Francisco Ríos Acosta SP-PS1 : generación de código java para un análisis léxico Instituto Tecnológico de la Laguna, julio del 2009. pag. 16 de 29 break; //————– Automata num————– case 4 : _tokens[_noTokens] = "num"; break; //————– Automata sep————– case 5 : _tokens[_noTokens] = "sep"; break; //————– Automata termInst————– case 6 : _tokens[_noTokens] = "termInst"; break; } _lexemas[_noTokens++] = _lexema; } else _i++; _iniToken = _i; } } // fin del método Analiza()
public int getI() { return _i; }
public void setI(int valor) { _i=valor; }
public int getIniToken() { return _iniToken; // clase Automata //————————————— public class Automata { String _textoIma; int _edoAct;
private char SigCar(int i) { if (i == _textoIma.length()) return ' '; else return _textoIma.charAt(i); }
public Boolean Reconoce(String texto,Lexico oAnaLex,int noAuto) { char c; _textoIma = texto; Se almacena el lexema y entonces se incrementa el atributo _noTokens para llevar la cuenta de cuantas parejas tokens-lexemas se han almacenado identificado- durante el proceso del análisis léxico. Se incrementa el atributo _i para como recuperación del error. Un error ocurre cuando ninguno de los AFDs ensamblados reconoce a la entrada.
Ya que se reconozca o no a un token, el proceso de reconocimiento del siguiente token inicia en el caracter apuntado por el atributo _i. SIN COMENTARIOS }
public String[] Tokens() { return _tokens; }
public String[] Lexemas() { return _lexemas; }
} // fin de la clase Lexico //—————————-
Clase Automata.
//————————————— _textoIma es una referencia al texto de entrada. _edoAct contiene el estado actual del AFD que está tratando de reconocer a un token.
El método SigCar() retorna al caracter indizado por el atributo _i de la clase Lexico. Cuando el atributo _i sobrepasa la frontera superior de la cadena _textoIma, retorna el caracter el cual tiene una alta probabilidad de no encontrarse en el texto de entrada. El método Reconoce() inicia el reconocimiento del token usando el AFD cuyo número orden- está dado por la variable noAuto. En este ejemplo el rango de valores de noAuto es de 0 a 6 -7 tokens = 7 AFDs-.
Ing. Francisco Ríos Acosta SP-PS1 : generación de código java para un análisis léxico Instituto Tecnológico de la Laguna, julio del 2009. pag. 17 de 29 String lenguaje; switch (noAuto) { //————– Automata delim————– case 0 : _edoAct = 0; break; //————– Automata Id————– case 1 : _edoAct = 3; break; //————– Automata OpAsig————– case 2 : _edoAct = 6; break; //————– Automata oparit————– case 3 : _edoAct = 9; break; //————– Automata num————– case 4 : _edoAct = 11; break; //————– Automata sep————– case 5 : _edoAct = 16; break; //————– Automata termInst————– case 6 : _edoAct = 18; break; } while(oAnaLex.getI()< =_textoIma.length()) switch (_edoAct) { //————– Automata delim————– case 0 : c=SigCar(oAnaLex.getI()); oAnaLex.setI(oAnaLex.getI()+1); if ((lenguaje=" nrt").indexOf(c)>=0) { oAnaLex.setI(oAnaLex.getIniToken()); return false; } break; case 1 : c=SigCar(oAnaLex.getI()); oAnaLex.setI(oAnaLex.getI()+1); if ((lenguaje=" nrt").indexOf(c)>=0) if ((lenguaje="!"#$%&'()*+,- ./0123456789:;< =>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[/]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬-®¯°±²³´µ¶·¸¹º»¼½¾¿f").indexOf(c)>=0) _edoAct=2; else { oAnaLex.setI(oAnaLex.getIniToken()); return false; } break; case 2 : oAnaLex.setI(oAnaLex.getI()-1); return true; //————– Automata Id————– case 3 : c=SigCar(oAnaLex.getI()); oAnaLex.setI(oAnaLex.getI()+1); if ((lenguaje="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz").indexOf(c)>=0) _edoAct=4; else if ((lenguaje="_").indexOf(c)>=0) _edoAct=4; else { oAnaLex.setI(oAnaLex.getIniToken()); return false; } break; case 4 : c=SigCar(oAnaLex.getI()); oAnaLex.setI(oAnaLex.getI()+1); if ((lenguaje="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz").indexOf(c)>=0) _edoAct=4; else if ((lenguaje="_").indexOf(c)>=0) _edoAct=4; else if ((lenguaje="0123456789").indexOf(c)>=0) _edoAct=4; else if ((lenguaje=" !"#$%&'()*+,-./:;< =>?@[/]^`{|}~ ¡¢£¤¥¦§¨©ª«¬-®¯°±²³´µ¶·¸¹º»¼½¾¿ntrf").indexOf(c)>=0) _edoAct=5; else { oAnaLex.setI(oAnaLex.getIniToken()); return false; } break; case 5 : oAnaLex.setI(oAnaLex.getI()-1); return true; //————– Automata OpAsig————– case 6 : c=SigCar(oAnaLex.getI()); oAnaLex.setI(oAnaLex.getI()+1); if ((lenguaje="=").indexOf(c)>=0) if ((lenguaje="+").indexOf(c)>=0) if ((lenguaje="-").indexOf(c)>=0) _edoAct=7; else _edoAct=8; else _edoAct=8; else Este switch() asigna al valor del _edoAct estado actual- el estado de inicio del AFD cuyo número está dado por noAuto. De esta manera el reconocimiento inicia con el AFD adecuado.
El while() cumple con la función de un ciclo en el que se está leyendo la entrada, se prueba el estado actual para efectuar una transición a otro estado, o bien se falla falla el AFD cuyo número está dado por noAuto-, o bien se acepta se reconoce al token-.
Transición al estado 1.
_edoAct=1; else Falla el AFD. En la falla se hace el valor del atributo _i igual al del atributo _iniToken, para luego retornar un false falla en el reconocimiento dentro del método Reconoce()-.
_edoAct=1; else Aceptación con Retraer(), es decir, el atributi _i se decrementa en una unidad. Luego se retorna true.
Ing. Francisco Ríos Acosta pag. 18 de 29 SP-PS1 : generación de código java para un análisis léxico Instituto Tecnológico de la Laguna, julio del 2009. if ((lenguaje="*").indexOf(c)>=0) _edoAct=8; else if ((lenguaje="/").indexOf(c)>=0) _edoAct=8; else { oAnaLex.setI(oAnaLex.getIniToken()); return false; } break; case 7 : return true; case 8 : c=SigCar(oAnaLex.getI()); oAnaLex.setI(oAnaLex.getI()+1); if ((lenguaje="=").indexOf(c)>=0) _edoAct=7; else { oAnaLex.setI(oAnaLex.getIniToken()); return false; } break; //————– Automata oparit————– case 9 : c=SigCar(oAnaLex.getI()); oAnaLex.setI(oAnaLex.getI()+1); if ((lenguaje="+").indexOf(c)>=0) if ((lenguaje="-").indexOf(c)>=0) if ((lenguaje="*").indexOf(c)>=0) if ((lenguaje="/").indexOf(c)>=0) _edoAct=10; else _edoAct=10; else _edoAct=10; else _edoAct=10; else _edoAct=12; else
_edoAct=12; else { oAnaLex.setI(oAnaLex.getIniToken()); return false; } break; case 10 : return true; //————– Automata num————– case 11 : c=SigCar(oAnaLex.getI()); oAnaLex.setI(oAnaLex.getI()+1); if ((lenguaje="0123456789").indexOf(c)>=0) { oAnaLex.setI(oAnaLex.getIniToken()); return false; } break; case 12 : c=SigCar(oAnaLex.getI()); oAnaLex.setI(oAnaLex.getI()+1); if ((lenguaje="0123456789").indexOf(c)>=0) if ((lenguaje=" !"#$%&'()*+,- /:;< =>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[/]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬-®¯°±²³´µ¶·¸¹º»¼½¾¿ntrf").indexOf(c)>=0) _edoAct=13; else if ((lenguaje=".").indexOf(c)>=0) _edoAct=14; else _edoAct=15; else
_edoAct=15; else { oAnaLex.setI(oAnaLex.getIniToken()); return false; } break; case 13 : oAnaLex.setI(oAnaLex.getI()-1); return true; case 14 : c=SigCar(oAnaLex.getI()); oAnaLex.setI(oAnaLex.getI()+1); if ((lenguaje="0123456789").indexOf(c)>=0) { oAnaLex.setI(oAnaLex.getIniToken()); return false; } break; case 15 : c=SigCar(oAnaLex.getI()); oAnaLex.setI(oAnaLex.getI()+1); if ((lenguaje="0123456789").indexOf(c)>=0) if ((lenguaje=" !"#$%&'()*+,- /:;< =>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[/]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬-®¯°±²³´µ¶·¸¹º»¼½¾¿ntrf").indexOf(c)>=0) _edoAct=13; else if ((lenguaje=".").indexOf(c)>=0) _edoAct=13; else { oAnaLex.setI(oAnaLex.getIniToken()); return false; } break; //————– Automata sep————– case 16 : c=SigCar(oAnaLex.getI()); oAnaLex.setI(oAnaLex.getI()+1); if ((lenguaje="(").indexOf(c)>=0) if ((lenguaje=")").indexOf(c)>=0) _edoAct=17; else _edoAct=17; else { oAnaLex.setI(oAnaLex.getIniToken()); return false; } break; case 17 : return true; //————– Automata termInst————– case 18 : c=SigCar(oAnaLex.getI()); oAnaLex.setI(oAnaLex.getI()+1); if ((lenguaje=";").indexOf(c)>=0) _edoAct=19; else { oAnaLex.setI(oAnaLex.getIniToken()); return false; } break;
Ing. Francisco Ríos Acosta SP-PS1 : generación de código java para un análisis léxico Instituto Tecnológico de la Laguna, julio del 2009. pag. 19 de 29 case 19 : return true; } switch (_edoAct) { case 2 : // Autómata delim case 5 : // Autómata Id case 13 : // Autómata num oAnaLex.setI(oAnaLex.getI()-1); return true; } return false; } } // fin de la clase Automata 7 Construcción de la aplicación java que efectúa el análisis léxico. Creación de un nuevo proyecto. En la sección 1 se había mencionado que el IDE a utilizar para desarrollar la aplicación java es el NetBeans 6.7. Así que de una vez es menester ejecutar dicho programa según se muestra en la fig. 7.1. Fig. No. 7.1 NetBeans 6.7 IDE.
Luego se debe crear un nuevo proyecto utilizando el botón New Project señalado en la fig. 7.1 y ubicado en la parte superior izquierda del menú principal del IDE NetBeans. NetBeans responde con una caja de diálogo para selección del tipo de proyecto, fig. 7.2. En este caso la selección es en Categories: Java y en Projects: Java Application. Luego se hace click en el botón cuya leyenda es Next >. Ahora se tiene de respuesta una nueva caja de diálogo New Java Application, donde se debe ingresar el nombre del proyecto, la carpeta donde se va a crear el proyecto, si se va a crear la clase main, entre otras cosas. La fig. 7.3 muestra los valores que ha seleccionado el que esto escribe. El lector debe seleccionar los suyos cuidando de des-seleccionar la caja de selección con leyenda Create Main Class. Este switch() permite efectuar el reconocimiento de un token que se encuentra al final de la cadena de entrada, y que además su AFD en su estado de aceptación tiene el Retraer(). En este caso, la lógica del programa se sale del while() sin reconocer, por lo que se debe atrapar esta situación dentro del switch() de manera que todos los estados de aceptación de todos los AFDs con Retraer() deberán ser tomados en cuenta en los case de este switch(). Una vez que son atrapados los estados de aceptación de los AFDs con Retraer(), se hace el decremento del atributo _i y entonces se retrona el true aceptación o reconocimiento de un token-.
Ing. Francisco Ríos Acosta SP-PS1 : generación de código java para un análisis léxico Instituto Tecnológico de la Laguna, julio del 2009. pag. 20 de 29 Fig. No. 7.2 Selección para nuevo proyecto. Fig. No. 7.3 Caja de diálogo New Java Application.
Ing. Francisco Ríos Acosta SP-PS1 : generación de código java para un análisis léxico Instituto Tecnológico de la Laguna, julio del 2009. pag. 21 de 29 Se termina haciendo click en el botón con leyenda Finish, después de lo cual se obtiene la interfase mostrada por la fig. 7.4, donde también es mostrado que se ha abierto el árbol Source Packages del nuevo proyecto analexapp. Fig. No. 7.4 El proyecto analexapp ha sido creado.
Creación de la clase AnaLex.java. Una vez creado el proyecto se sigue con la creación de la forma ventana- que será la contenedora de los componentes de la interfase gráfica de la aplicación. Para crear la forma, es menester hacer click con el botón derecho en el árbol del proyecto Source Packages, luego seleccionar New, luego JFrame Form. NetBeans responde con la ventana de diálogo New JFrame Form, fig. 7.5. Fig. No. 7.5 Creación del JFrame Form AnaLex..
Ing. Francisco Ríos Acosta SP-PS1 : generación de código java para un análisis léxico Instituto Tecnológico de la Laguna, julio del 2009. pag. 22 de 29 Sólo resta hacer click en el botón Finish para terminar con la creación de la forma AnaLex que realmente es una clase java que hereda de la clase JFrame. NetBeans responde con la forma AnaLex en tiempos de diseño. Se observa también que se agrega la clase AnaLex.java la que contiene el código de la aplicación que se está creando, fig. 7.6. Fig. No. 7.6 Aplicación AnaLex.java que hereda a la clase JFrame.
Haciéndo click en el botón Source se puede acceder al código de la clase AnaLex.java :
/* * To change this template, choose Tools | Templates * and open the template in the editor. */
/* * AnaLex.java * * Created on 12/07/2009, 03:18:35 PM */
/** * * @author Ing. Francisco Rios */ public class AnaLex extends javax.swing.JFrame {
/** Creates new form AnaLex */ public AnaLex() { initComponents(); }
/** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // < editor-fold defaultstate="collapsed" desc="Generated Code"> private void initComponents() { Encabezado de la clase AnaLex.java donde se define la herencia de la clase javax.swing.JFrame
Constructor de la clase AnaLex.java
Ing. Francisco Ríos Acosta SP-PS1 : generación de código java para un análisis léxico Instituto Tecnológico de la Laguna, julio del 2009. pag. 23 de 29 setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGap(0, 400, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGap(0, 300, Short.MAX_VALUE) );
pack(); }// < /editor-fold>
/** * @param args the command line arguments */ public static void main(String args[]) { java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new AnaLex().setVisible(true); } }); }
// Variables declaration – do not modify // End of variables declaration }
Lo que sigue es agregar los componentes necesarios para el ingreso del texto de entrada, para ejecutar el análisis léxico, y para la visualización de las parejas token-lexema encontrados. En la tabla siguiente se muestran a los componentes y sus propiedades asignadas a los valores adecuados : Lo que procede es ejecutar la aplicación java para observar si todo está bien. Hacemos click en el botón Source, luego con el botón derecho del ratón seleccionamos en el menú popup la opción Run File y se debe obtener lo mostrado en la fig. 7.7. Método main() que crea una instancia de la clase AnaLex y luego la hace visible a la ventana de la aplicación-.
Ing. Francisco Ríos Acosta SP-PS1 : generación de código java para un análisis léxico Instituto Tecnológico de la Laguna, julio del 2009. pag. 24 de 29 Fig. No. 7.7 Aplicación AnaLex.java en ejecución pero sin hacer nada aún.
Inserción del código java generado por SP-PS1. Antes de agregar la definición del objeto oAnaLex es menester añadir las 2 clases Lexico y Automata al proyecto analexapp, las cuales son generadas por el programa SP-PS1 siguiendo los pasos descritos en la sección 5. Las clases se añaden una por una, y se dejan vacias de manera que el paso siguiente será el de pegar el código java generado por el SP-PS1. Para agregar una clase al proyecto se hace click en el árbol Source Packages del proyecto, luego en el menú popup se selecciona New, para entonces seleccionar Java Class, a lo que Netbeans responde con la ventana New Java Class vista en la fig. 7.8. Es necesario ingresar en la ventana Class Name el nombre de la clase que en este caso es Lexico. Fig. No. 7.8 Creación y adición de la clase Lexico al proyecto analexapp.
Ing. Francisco Ríos Acosta SP-PS1 : generación de código java para un análisis léxico Instituto Tecnológico de la Laguna, julio del 2009. pag. 25 de 29 Una vez que se ha ingresado el nombre de la clase, se completa la adición de la clase al proyecto haciendo click en el botón Finish. Lo mismo se realiza para la adición de la clase Automata al proyecto. Si todo ha sido efectuado de manera adecuada, entonces se tendrá el proyecto con las 2 clases Lexico y Automata añadidas a él, pero estarán vacias. La fig. 7.9 muestra el proyecto con la clase Lexico visualizada. Fig. No. 7.9 Clases Lexico y Automata agregadas al proyecto analexapp.
Solo resta insertar el código java generado para las 2 clases Lexico y Automata, cuestión que es muy simple ya que sólo es necesario utilizar el portapapeles y ¡listo!. Después de haber efectuado el copia y pega del código de las clases Lexico y Automata copia del SP-PS1, pega en NetNBeans-, una revisión de NO ERRORES debe realizarse en las 2 clases. Si no hay errores, entonces se va por buen camino, de lo contrario se debe volver atrás y tratar de encontrar donde se cometió el error. La fig. 7.10 muestra el proyecto analexapp con la inserción del código sin error.
Definición del objeto oAnaLex. El objeto oAnaLex es la instancia creada que pertenece a la clase Lexico. oAnaLex será el encargado de realizar el análisis léxico del texto de entrada, invocando al método Analiza() definido en la clase Lexico. El objeto oAnaLex es definido dentro de la clase AnaLex tanto como atributo como de la reserva del espacio en memoria dentro del constructor de dicha clase, tal y como se muestra enseguida.
public class AnaLex extends javax.swing.JFrame { Lexico oAnaLex; /** Creates new form AnaLex */ public AnaLex() { oAnaLex=new Lexico(); initComponents(); }
La fig. 7.11 muestra la clase AnaLex con el objeto oAnaLex definido según se mencionó anteriormente.
Ing. Francisco Ríos Acosta SP-PS1 : generación de código java para un análisis léxico Instituto Tecnológico de la Laguna, julio del 2009. pag. 26 de 29 Fig. No. 7.10 Inserción del código en las clases Lexico y Automata sin error. Fig. No. 7.11 Definición del objeto oAnaLex en la clase AnaLex.java
Llamada a la ejecución del análisis léxico. El análisis léxico se efectúa hasta que el usuario haga click sobre el botón con leyenda ANALISIS LEXICO de la aplicación. Las acciones que deben codificarse en este botón son las de inicializar al objeto oAnaLex, para luego efectuar el mensaje de Analiza() teniendo como objeto precisamente a oAnaLex. La inserción del código seleccionando al componente jButton1 y haciendo click con el botón derecho del ratón se selecciona en el menú popup la opción de Events, luego la opción Action, siguiendo con la opción actionPerformed.
Ing. Francisco Ríos Acosta SP-PS1 : generación de código java para un análisis léxico Instituto Tecnológico de la Laguna, julio del 2009. pag. 27 de 29 NetBeans responde enviando el control a la ventana Source código de la clase AnaLex.java-, agregando el método jButton1ActionPerformed() según se ilustra en la fig. 7.12. Fig. No. 7.12 Método jButton1ActionPerformed() añadido.
Dentro de este método se inserta el código que efectúa la inicialización del objeto oAnaLex, realiza el análisis léxico mediante el mensaje al objeto oAnaLex que incluye al método Analiza() cuyo parámetro es el texto de entrada. El código ya insertado es :
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { // TODO add your handling code here: oAnaLex.Inicia(); oAnaLex.Analiza(jTextArea1.getText()); }
La ejecución del proyecto la clase AnaLex.java- produce una aplicación corriendo OK pero sin visualizar los resultados del análisis léxico, fig.7.13. Fig. No. 7.13 Ejecución de la aplicación java sin visualización del resultado del análisis léxico.
Ing. Francisco Ríos Acosta SP-PS1 : generación de código java para un análisis léxico Instituto Tecnológico de la Laguna, julio del 2009. pag. 28 de 29 Visualización de las parejas token-lexema encotradas durante el proceso de análisis léxico. El componente jTable1 perteneciente a la clase JTable requiere para su caracterización, un modelo. Un modelo hereda de la clase abstracta AbstractTableModel, que se encuentra dentro del paquete javax.swing.table. Entonces lo que propone lo que esto escribe es crear una nueva clase con el nombre de ModeloDeTabla, dentro del proyecto analexapp de la aplicación qu se está construyendo. Después de añadir la nueva clase, el proyecto en la etapa de diseño muestra la cara según la fig. 7.14. Fig. No. 7.14 Clase ModeloDeTabla añadida al proyecto. Lo que sigue es agregar el código siguiente a la clase ModeloDeTabla.
import javax.swing.table.AbstractTableModel; public class ModeloDeTabla extends AbstractTableModel { private String[] columnNames = {"TOKEN","LEXEMA"}; private Object[][] data;
public ModeloDeTabla(String[] tokens,String[] lexemas) { data=new Object[tokens.length][2]; for(int i=0;i< tokens.length;i++) { data[i][0]=tokens[i]; data[i][1]=lexemas[i]; } } public int getColumnCount() { return columnNames.length; }
public int getRowCount() { return data.length; } @Override public String getColumnName(int col) { return columnNames[col]; } Se importa el paquete javax.swing.table.AbstractTableModel ya que la clase ModeloDeTabla es derivada de la clase AbstractTableModel.
El arreglo columnNames se inicializa con el nombre de las columnas por consiguiente se tiene el número de columnas-. Al constructor se le pasan de parámetro los arreglos de tokens y de lexemas que contienen lógicamente las parejas token- lexema encontrados durante el análisis léxico. Estas parejas token-lexema se depositan en el arreglo bidimensional de objetos data. data primero es dimensionado usando el constuctor de la clase Object.
Ing. Francisco Ríos Acosta SP-PS1 : generación de código java para un análisis léxico Instituto Tecnológico de la Laguna, julio del 2009. pag. 29 de 29 public Object getValueAt(int row, int col) { return data[row][col]; } } // fin de la clase ModeloDeTabla
Sólo falta agregar las sentencias que definen al modelo de la tabla, la llamada al constructor para pasarle los arreglos tokens y lexemas, de manera que se pueda caracterizar dicha tabla. Todo se hará dentro de la clase AnaLex.java, así que para accederla se debe hacer click en el botón Source.
/** * * @author Ing. Francisco Rios */ public class AnaLex extends javax.swing.JFrame { Lexico oAnaLex; ModeloDeTabla modelo=null; /** Creates new form AnaLex */ public AnaLex() { oAnaLex=new Lexico(); modelo=new ModeloDeTabla(oAnaLex.Tokens(),oAnaLex.Lexemas()); initComponents(); } /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ @SuppressWarnings("unchecked") private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { // TODO add your handling code here: oAnaLex.Inicia(); oAnaLex.Analiza(jTextArea1.getText()); modelo=new ModeloDeTabla(oAnaLex.Tokens(),oAnaLex.Lexemas()); jTable1.setModel(modelo); } Fig. No. 7.15 Ejecución de la aplicación java que efectúa un análisis léxico. Definición del objeto modelo y su asignación a null. Se crea en memoria al objeto modelo de manera que pueda ser usado en la inicialización de los componentes. Se crea en cada análisis léxico al objeto modelo, pero ahora se le pasan de parámetro a su constructor los arreglos que contienen a los tokens y a los lexemas que se han encontrado durante el proceso del análisis léxico. Luego se asigna el modelo al componente jTable1. La ejecución de la aplicación cuya clase principal es Analex.java se muestra en la fig. 7.15.
Página anterior | Volver al principio del trabajo | Página siguiente |