Universidad de San Carlos de Guatemala Facultad de Ingeniería Escuela de Ciencias y Sistemas Organización de Lenguajes y Compiladores 1 2do.

semestre del 2010

JLEX
1. Descripción General
Es una herramienta que sirve de apoyo en la implementación de un analizador léxico, Ayuda al análisis léxico la primer fase de un compilador.

2. Instalación
Para utilizar esta herramienta se debe baja el fuente de JLex (Main.java) de la pagina http://www.cs.princeton.edu/~appel/modern/java/JLex/current/Main.java. Se crea una carpeta en el directorio bin de nuestro jdk llamada JLex y dentro se baja el archivo Main.java Para compilar Jlex se utilizara las siguientes dos sentencias. cd "G:\Archivos de programa\Java\jdk1.6.0_21\bin" javac JLex\Main.java

Las clases se muestran como las siguientes

Debemos bajar también la carpeta de java_cup en la ruta de nuestro bin del jdk.

2.1 Ejemplo de JLex Se propone el ejemplo de un analizador léxico que reconozca los componentes léxico para las declaraciones de variables y las listas de asignaciones con expresiones. Como el que se muestra a continuación: int a1,a2,a3; double b1,b2,b3; string c_1,c_2,c_3; int d1; a1=1; b1=2.0; a2=a1+b1; b2=a1+b2; a3=a2+3; b3=b2*4.0; c_1="hola"; c_2="mundo"; c_3=c_1+" "+c_2; a3=(a1+b1)*(b2+a2); b3=(a1%b1)/(b2%a2); Lo primero que se debe realizar en las definición de expresiones regulares para      Identificadores Palabra reservadas (int, doublé, string) Operadores (=,+,-,*,/,%) Constantes (Numero,Cadena) Otros componentes (Fin de línea, espacios y tabuladores)

Para esto se procede a definir las expresiones regulares y las reglas en el archivo léxico.lex como se muestra a continuación. package ejemplo; import java_cup.runtime.*; import javax.swing.*; import java.util.*; %% %class Yylex %{String literal; String temp_include; %} %{ int columna=1; %} %public %cup %line %full %unicode %ignorecase %char %{ public String sourceFilename; StringBuffer string = new StringBuffer(); int ultimoEstado = 0; public void init(){}; %} %eofval{ {return new Symbol(Token.EOF, null); } %eofval} ALPHA=[A-Za-zÑñ] DIGITO=[0-9] IDENTIFICADOR={ALPHA}({ALPHA}|{DIGITO}|"_")* NUMERO=({DIGITO})+"."({DIGITO})+ CADENA=[\"] [^\"\n]+ [\"\n] %% [\n] { yychar=0;} [ \t\r\n\f] { /* ignore white space. */ } \’ { /* ignore apostrofos. */ }

<YYINITIAL> [\t\r\f] {/*no hace nada, aumenta una columna*/yychar++; } <YYINITIAL> [\n] {yychar=0; /*yyline=0*/} <YYINITIAL>"(" { return new Symbol(Token.OPEN, yyline, yychar, yytext());} <YYINITIAL>")" { return new Symbol(Token.CLOSE, yyline, yychar, yytext());} <YYINITIAL>"+" { return new Symbol(Token.PLUS, yyline, yychar, yytext());} <YYINITIAL>"-" { return new Symbol(Token.MIN, yyline, yychar, yytext());} <YYINITIAL>"*" { return new Symbol(Token.BY, yyline, yychar, yytext());} <YYINITIAL>"/" { return new Symbol(Token.DIV, yyline, yychar, yytext());} <YYINITIAL>"%" { return new Symbol(Token.MOD, yyline, yychar, yytext());} <YYINITIAL>"=" { return new Symbol(Token.EQUAL, yyline, yychar, yytext());} <YYINITIAL>"," { return new Symbol(Token.COMA, yyline, yychar, yytext()); <YYINITIAL>";" { return new Symbol(Token.POINTCOMA, yyline, yychar, yytext());} <YYINITIAL>"int" { return new Symbol(Token.INT, yyline, yychar, yytext());} <YYINITIAL>"double" { return new Symbol(Token.DOUBLE, yyline, yychar, yytext());} <YYINITIAL>"string" { return new Symbol(Token.STRING, yyline, yychar, yytext());} <YYINITIAL>{NUMERO} { return new Symbol(Token.NUMERO, yyline, yychar, yytext());} <YYINITIAL>{IDENTIFICADOR} { return new Symbol(Token.IDENTIFICADOR, yyline, yychar, yytext());} <YYINITIAL>{CADENA} { return new Symbol(Token.CADENA, yyline, yychar, yytext());} .{ System.out.println("error lexico en la fila "+yyline +" y en la columna " + yychar); //interfaz.rotular(“error lexico :”+ yytext()+” en la fila “+yyline +” y en la columna ” + yychar); }

Para poder utilizar únicamente en analizador léxico de JLex se debe de crear una clase a la que llamaremos Token que contendrá todos los token a devolver por nuestro léxico.lex. package ejemplo;

/** CUP generated class containing symbol constants. */ public class Token { /* terminals */ public static final int MOD = 8; public static final int CADENA = 17; public static final int PLUS = 4; public static final int CLOSE = 3; public static final int INT = 12; public static final int EQUAL = 9; public static final int STRING = 14; public static final int COMA = 10; public static final int EOF = 0; public static final int BY = 6; public static final int DIV = 7; public static final int error = 1; public static final int NUMERO = 16; public static final int IDENTIFICADOR = 15; public static final int MIN = 5; public static final int OPEN = 2; public static final int POINTCOMA = 11; public static final int DOUBLE = 13; }

Despues se debe compilar con las herramienta de Jlex creando el archivo bat mostrado a continuacion y ejecutándolo cd "G:\Archivos de programa\Java\jdk1.6.0_21\bin" set CLASSPATH=G:\Archivos de programa\Java\jdk1.6.0_21\bin;%CLASSPATH% set PATH=G:\Archivos de programa\Java\jdk1.6.0_21\bin;%PATH% cd "G:\Documents and Settings\db2admin\Mis documentos\NetBeansProjects\Ejemplo\src\ejemplo" del Yylex.java java JLex.Main lexico.lex rename lexico.lex.java Yylex.java pause

Se ejecuta este archivo y nos dara como resultado un archivo al cual renombramos como Yylex y que será nuestro analizador lexico. Para probarlo se debe crear un proyecto con el nombre que más se prefiera en este caso Ejemplo. Y copiar en directorio de src las carpetas de JLex y java_cup, además en la carpeta del paquete principal en src se debe copiar los archivos generados Yylex.java y Token.java junto al Main el cual debe tener el código siguiente public static void main(String[] args) throws FileNotFoundException, IOException { // TODO code application logic here try{ File f=new File("entrada.txt"); BufferedReader r=new BufferedReader(new FileReader(f)); Yylex scanner=new Yylex(r); Symbol symbol=scanner.next_token(); while(symbol!=null){ System.out.println("token: "+symbol.sym+" valor: "+symbol.value); symbol=(symbol.sym==0) ?null:scanner.next_token(); } } catch(FileNotFoundException e){System.out.println(e.getMessage());} }

Links de de consulta http://muytux.blogspot.com/2010/07/manual-de-jflex.html http://www.basketcase.net84.net/index/?p=318 http://www.cs.princeton.edu/~appel/modern/java/JLex/