COMPILADORES

Compiladores e Intérpretes Carlos Alfredo Ángeles Gutiérrez 1011105041 ¿QUÉ ES EL ANÁLISIS LÉXICO-SINTÁCTICO DE UN LEN

Views 112 Downloads 1 File size 606KB

Report DMCA / Copyright

DOWNLOAD FILE

Recommend stories

Citation preview

Compiladores e Intérpretes Carlos Alfredo Ángeles Gutiérrez 1011105041

¿QUÉ ES EL ANÁLISIS LÉXICO-SINTÁCTICO DE UN LENGUAJE? El análisis léxico-sintáctico tiene por objeto reconocer la forma de las sentencias de un lenguaje. Reconocer la forma de una sentencia implica reconocer sus lexemas y estructuras sintácticas. El resultado del análisis léxico-sintáctico puede ser un error de reconocimiento o una versión de la sentencia reconocida en forma de árbol de sintaxis abstracta (asa). Para reconocer los lexemas de un lenguaje usaremos expresiones regulares y para reconocer estructuras sintácticas usaremos gramáticas independientes de contexto (gramática). Una gramática es un conjunto de reglas.

¿QUE SON LOS LEXEMAS? Los lexemas o tokens son los símbolos terminales que aparecen en la gramática y representan las distintas categorías de palabras y símbolos de puntuación que podemos encontrar en una sentencia del lenguaje.

DESARROLLO Para el desarrollo se utilizo el entorno de desarrollo NetBeans el cual trabaja bajo la plataforma java. En este caso se utilizaron las librerías JFlex y java CUP. JFlex es un generador de analizador léxico (también conocido como generador de escáner) para Java (TM), escrito en Java (TM). Cup es un generador de analizadores sintácticos LALR en Java el cual recibe de entrada un archivo con la estructura de la gramática y su salida es un parser escrito en Java listo para usarse. Se utilizaron cuatro clases que a continuación se describen. Clase AnalisadorLexico.java.- En esta clase se incluye el análisis léxico del programa fuente. es la primera fase de un compilador consistente en un programa que recibe como entrada el código fuente de otro programa (secuencia de caracteres) y produce una salida compuesta de tokens (componentes léxicos) o símbolos. Estos tokens sirven para una posterior etapa del proceso de traducción, siendo la entrada para el analizador sintáctico (en inglés parser). a continuación código y capturas de pantalla. }; /* --------------------------Codigo de Usuario----------------------- */ package ejemplocup; import java_cup.runtime.*; import java.io.Reader; class AnalizadorLexico implements java_cup.runtime.Scanner { public static final int YYEOF = -1; private static final int ZZ_BUFFERSIZE = 16384; public static final int YYINITIAL = 0; private static final int ZZ_LEXSTATE[] = { 0, 0

private static final String ZZ_CMAP_PACKED = "\11\0\1\3\1\2\1\0\1\3\1\1\22\0\1\3\7\0\1\12"+ "\1\13\1\11\1\7\1\0\1\10\2\0\1\4\11\5\1\0\1\6"+ "\uffc4\0"; private static final char zzUnpackCMap(ZZ_CMAP_PACKED);

[]

ZZ_CMAP

private static final int [] ZZ_ACTION = zzUnpackAction(); private static final String ZZ_ACTION_PACKED_0 =

=

"\1\0\1\1\2\2\2\3\1\4\1\5\1\6\1\7"+ "\1\10\1\11"; private static int [] zzUnpackAction() { int [] result = new int[12]; int offset = 0; offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); return result; } private static int zzUnpackAction(String packed, int offset, int [] result) { int i = 0; int j = offset; int l = packed.length(); while (i < l) { int count = packed.charAt(i++); int value = packed.charAt(i++); do result[j++] = value; while (--count > 0); } return j; }

private static final int [] ZZ_ROWMAP = zzUnpackRowMap(); private static final String ZZ_ROWMAP_PACKED_0 = "\0\0\0\14\0\30\0\14\0\14\0\44\0\14\0\14"+ "\0\14\0\14\0\14\0\14"; private static int [] zzUnpackRowMap() { int [] result = new int[12]; int offset = 0; offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); return result; } private static int zzUnpackRowMap(String packed, int offset, int [] result) { int i = 0; /* index in packed string */ int j = offset; /* index in unpacked array */ int l = packed.length(); while (i < l) { int high = packed.charAt(i++) 0); } return j; } private static final int ZZ_UNKNOWN_ERROR = 0; private static final int ZZ_NO_MATCH = 1; private static final int ZZ_PUSHBACK_2BIG = 2; private static final String ZZ_ERROR_MSG[] = { "Unkown internal scanner error", "Error: could not match input", "Error: pushback value was too large" };

private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); private static final String ZZ_ATTRIBUTE_PACKED_0 = "\1\0\1\11\1\1\2\11\1\1\6\11"; private static int [] zzUnpackAttribute() { int [] result = new int[12]; int offset = 0; offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); return result; } private static int zzUnpackAttribute(String packed, int offset, int [] result) { int i = 0; /* index in packed string */ int j = offset; /* index in unpacked array */ int l = packed.length(); while (i < l) { int count = packed.charAt(i++); int value = packed.charAt(i++); do result[j++] = value; while (--count > 0); } return j; } private java.io.Reader zzReader; private int zzState; private int zzLexicalState = YYINITIAL; private char zzBuffer[] = new char[ZZ_BUFFERSIZE]; private int zzMarkedPos; private int zzCurrentPos; private int zzStartRead; private int zzEndRead; private int yyline; private int yychar; private int yycolumn; private boolean zzAtBOL = true; private boolean zzAtEOF; private boolean zzEOFDone; private Symbol symbol(int type) { return new Symbol(type, yyline, yycolumn); } /* Generamos un Symbol para el tipo de token encontrado junto con su valor */ private Symbol symbol(int type, Object value) { return new Symbol(type, yyline, yycolumn, value); } AnalizadorLexico(java.io.Reader in) { this.zzReader = in; }

AnalizadorLexico(java.io.InputStream in) { this(new java.io.InputStreamReader (in, java.nio.charset.Charset.forName("UTF-8"))); } private static char [] zzUnpackCMap(String packed) { char [] map = new char[0x10000]; int i = 0; /* index in packed string */ int j = 0; /* index in unpacked array */ while (i < 42) { int count = packed.charAt(i++); char value = packed.charAt(i++); do map[j++] = value; while (--count > 0); } return map; }

private boolean zzRefill() throws java.io.IOException { if (zzStartRead > 0) { System.arraycopy(zzBuffer, zzStartRead, zzBuffer, 0, zzEndRead-zzStartRead); zzEndRead-= zzStartRead; zzCurrentPos-= zzStartRead; zzMarkedPos-= zzStartRead; zzStartRead = 0; }

if (zzCurrentPos >= zzBuffer.length) { char newBuffer[] = new char[zzCurrentPos*2]; System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length); zzBuffer = newBuffer; } int numRead = zzReader.read(zzBuffer, zzEndRead, zzBuffer.length-zzEndRead); if (numRead > 0) { zzEndRead+= numRead; return false; } if (numRead == 0) { int c = zzReader.read(); if (c == -1) { return true; } else { zzBuffer[zzEndRead++] = (char) c; return false; } }

return true; }

public final void yyclose() throws java.io.IOException { zzAtEOF = true; /* indicate end of file */ zzEndRead = zzStartRead; /* invalidate buffer */ if (zzReader != null) zzReader.close(); }

public final void yyreset(java.io.Reader reader) { zzReader = reader; zzAtBOL = true; zzAtEOF = false; zzEOFDone = false; zzEndRead = zzStartRead = 0; zzCurrentPos = zzMarkedPos = 0; yyline = yychar = yycolumn = 0; zzLexicalState = YYINITIAL; if (zzBuffer.length > ZZ_BUFFERSIZE) zzBuffer = new char[ZZ_BUFFERSIZE]; }

public final int yystate() { return zzLexicalState; } public final void yybegin(int newState) { zzLexicalState = newState; }

public final String yytext() { return new String( zzBuffer, zzStartRead, zzMarkedPos-zzStartRead ); } public final char yycharat(int pos) { return zzBuffer[zzStartRead+pos]; } public final int yylength() { return zzMarkedPos-zzStartRead; } private void zzScanError(int errorCode) { String message; try { message = ZZ_ERROR_MSG[errorCode]; } catch (ArrayIndexOutOfBoundsException e) { message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR]; } throw new Error(message); } public void yypushback(int number) { if ( number > yylength() ) zzScanError(ZZ_PUSHBACK_2BIG); zzMarkedPos -= number; } private void zzDoEOF() throws java.io.IOException { if (!zzEOFDone) { zzEOFDone = true; yyclose(); } } public java_cup.runtime.Symbol next_token() throws java.io.IOException { int zzInput; int zzAction;

int zzCurrentPosL; int zzMarkedPosL; int zzEndReadL = zzEndRead;

char [] zzBufferL = zzBuffer; char [] zzCMapL = ZZ_CMAP;

}

zzAction = zzState;

int [] zzTransL = ZZ_TRANS; int [] zzRowMapL = ZZ_ROWMAP; int [] zzAttrL = ZZ_ATTRIBUTE;

zzForAction: { while (true) {

while (true) { zzMarkedPosL = zzMarkedPos;

if (zzCurrentPosL < zzEndReadL) zzInput = zzBufferL[zzCurrentPosL++]; else if (zzAtEOF) { zzInput = YYEOF; break zzForAction; } else {

boolean zzR = false; for (zzCurrentPosL = zzStartRead; zzCurrentPosL < zzMarkedPosL; zzCurrentPosL++) { switch (zzBufferL[zzCurrentPosL]) { case '\u000B': case '\u000C': case '\u0085': case '\u2028': case '\u2029': yyline++; yycolumn = 0; zzR = false; break; case '\r': yyline++; yycolumn = 0; zzR = true; break; case '\n': if (zzR) zzR = false; else { yyline++; yycolumn = 0; } break; default: zzR = false; yycolumn++; } } if (zzR) { boolean zzPeek; if (zzMarkedPosL < zzEndReadL) zzPeek = zzBufferL[zzMarkedPosL] == '\n'; else if (zzAtEOF) zzPeek = false; else { boolean eof = zzRefill(); zzEndReadL = zzEndRead; zzMarkedPosL = zzMarkedPos; zzBufferL = zzBuffer; if (eof) zzPeek = false; else zzPeek = zzBufferL[zzMarkedPosL] == '\n'; } if (zzPeek) yyline--; } zzAction = -1; zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL; zzState = ZZ_LEXSTATE[zzLexicalState]; int zzAttributes = zzAttrL[zzState]; if ( (zzAttributes & 1) == 1 ) {

zzCurrentPos = zzCurrentPosL; zzMarkedPos = zzMarkedPosL; boolean eof = zzRefill(); zzCurrentPosL = zzCurrentPos; zzMarkedPosL = zzMarkedPos; zzBufferL = zzBuffer; zzEndReadL = zzEndRead; if (eof) { zzInput = YYEOF; break zzForAction; } else { zzInput = zzBufferL[zzCurrentPosL++]; } } int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMapL[zzInput] ]; if (zzNext == -1) break zzForAction; zzState = zzNext; zzAttributes = zzAttrL[zzState]; if ( (zzAttributes & 1) == 1 ) { zzAction = zzState; zzMarkedPosL = zzCurrentPosL; if ( (zzAttributes & 8) == 8 ) break zzForAction; } } }

zzMarkedPos = zzMarkedPosL; switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) { case 1: { throw new Error("Caracter ilegal "); } case 10: break; case 2: { /* ignora el espacio */ } case 11: break; case 3: { System.out.print(yytext()); return symbol(sym.ENTERO, new Integer(yytext())); } case 12: break; case 4: { return symbol(sym.SEMI); } case 13: break; case 5: { System.out.print(" + ");

return symbol(sym.OP_SUMA); } case 14: break; case 6: { System.out.print(" - "); return symbol(sym.OP_RESTA); } case 15: break; case 7: { System.out.print(" * "); return symbol(sym.OP_MULT); } case 16: break; case 8: { System.out.print(" ( "); return symbol(sym.PARENIZQ); } case 17: break;

case 9: { System.out.print(" ) "); return symbol(sym.PARENDER); } case 18: break; default: if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { zzAtEOF = true; zzDoEOF(); { return new java_cup.runtime.Symbol(sym.EOF); } } else { zzScanError(ZZ_NO_MATCH); } } } } }

Clase AnalisadorSintactico.java.- En esta clase se incluye el análisis sintáctico tomando como base la salida del analizador léxico. Un analizador sintáctico (o parser) es una de las partes de un compilador que transforma su entrada en un árbol de derivación. El análisis sintáctico convierte el texto de entrada en otras estructuras (comúnmente árboles), que son más útiles para el posterior análisis y capturan la jerarquía implícita de la entrada. Un analizador léxico crea tokens de una secuencia de caracteres de entrada y son estos tokens los que son procesados por el analizador sintáctico para construir la estructura de datos, por ejemplo un árbol de análisis o árboles de sintaxis abstracta. A continuación código y capturas de pantallas. package ejemplocup; import java_cup.runtime.*; import java.io.FileReader;

public class AnalizadorSintactico extends java_cup.runtime.lr_parser {

public AnalizadorSintactico() {super();} public AnalizadorSintactico(java_cup.runtime.Scanner s) {super(s);}

public AnalizadorSintactico(java_cup.runtime.Scanner java_cup.runtime.SymbolFactory sf) {super(s,sf);}

s,

protected static final short _production_table[][] = unpackFromStrings(new String[] { "\000\014\000\002\002\004\000\002\002\004\000\002\002" + "\003\000\002\007\002\000\002\003\005\000\002\004\005" + "\000\002\004\005\000\002\004\003\000\002\005\005\000" + "\002\005\003\000\002\006\005\000\002\006\003" });

public short[][] production_table() {return _production_table;}

protected static final short[][] _action_table = unpackFromStrings(new String[] { "\000\024\000\006\010\004\012\012\001\002\000\006\010" + "\004\012\012\001\002\000\010\002\uffff\010\uffff\012\uffff" + "\001\002\000\014\004\ufffa\005\ufffa\006\ufffa\007\017\011" + "\ufffa\001\002\000\010\002\024\010\004\012\012\001\002" + "\000\010\004\ufffe\005\015\006\014\001\002\000\014\004" + "\ufff8\005\ufff8\006\ufff8\007\ufff8\011\ufff8\001\002\000\014" + "\004\ufff6\005\ufff6\006\ufff6\007\ufff6\011\ufff6\001\002\000" + "\004\004\022\001\002\000\006\010\004\012\012\001\002" + "\000\006\010\004\012\012\001\002\000\014\004\ufffc\005" + "\ufffc\006\ufffc\007\017\011\ufffc\001\002\000\006\010\004" + "\012\012\001\002\000\014\004\ufff9\005\ufff9\006\ufff9\007" + "\ufff9\011\ufff9\001\002\000\014\004\ufffb\005\ufffb\006\ufffb" + "\007\017\011\ufffb\001\002\000\010\002\ufffd\010\ufffd\012" + "\ufffd\001\002\000\010\002\001\010\001\012\001\001\002" + "\000\004\002\000\001\002\000\010\005\015\006\014\011" + "\026\001\002\000\014\004\ufff7\005\ufff7\006\ufff7\007\ufff7" + "\011\ufff7\001\002" }); public short[][] action_table() {return _action_table;} protected static final short[][] _reduce_table = unpackFromStrings(new String[] { "\000\024\000\014\002\006\003\004\004\007\005\005\006" + "\010\001\001\000\010\004\024\005\005\006\010\001\001" + "\000\002\001\001\000\002\001\001\000\012\003\022\004" + "\007\005\005\006\010\001\001\000\004\007\012\001\001" + "\000\002\001\001\000\002\001\001\000\002\001\001\000" + "\006\005\020\006\010\001\001\000\006\005\015\006\010" + "\001\001\000\002\001\001\000\004\006\017\001\001\000" + "\002\001\001\000\002\001\001\000\002\001\001\000\002" + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + "\001" }); public short[][] reduce_table() {return _reduce_table;} protected CUP$AnalizadorSintactico$actions action_obj; protected void init_actions() { action_obj = new CUP$AnalizadorSintactico$actions(this); } public java_cup.runtime.Symbol do_action( int act_num, java_cup.runtime.lr_parser parser, java.util.Stack stack, int top) throws java.lang.Exception { return action_obj.CUP$AnalizadorSintactico$do_action(act_num, parser, stack, top); }

public int start_state() {return 0;} public int start_production() {return 1;} public int EOF_sym() {return 0;} public int error_sym() {return 1;}

/* Reporte de error encontrado. */ public void report_error(String message, Object info) { StringBuilder m = new StringBuilder("Error"); if (info instanceof java_cup.runtime.Symbol) { java_cup.runtime.Symbol s = ((java_cup.runtime.Symbol) info); if (s.left >= 0) { m.append(" in line "+(s.left+1)); if (s.right >= 0) m.append(", column "+(s.right+1)); } } m.append(" : "+message); System.err.println(m); } /* Cuando se encuentra un error de donde el sistema no puede recuperarse, se lanza un error fatal. Se despliega el mensaje de error y se finaliza la ejecucion. */ public void report_fatal_error(String message, Object info) { report_error(message, info); System.exit(1); } /* Metodo main para garantizar la ejecucion del analizador lexico y sintactico, ademas que se pase como parametro la tabla de simbolos correspondiente. */ public static void main(String[] args){ try { AnalizadorSintactico asin = new AnalizadorSintactico( new AnalizadorLexico( new FileReader(args[0]))); Object result = asin.parse().value; System.out.println("\n*** Resultados finales ***"); } catch (Exception ex) { ex.printStackTrace(); } } } class CUP$AnalizadorSintactico$actions { private final AnalizadorSintactico parser; /** Constructor */ CUP$AnalizadorSintactico$actions(AnalizadorSintactico parser) { this.parser = parser; } public final java_cup.runtime.Symbol CUP$AnalizadorSintactico$do_action( int CUP$AnalizadorSintactico$act_num, java_cup.runtime.lr_parser CUP$AnalizadorSintactico$parser, java.util.Stack CUP$AnalizadorSintactico$stack, int CUP$AnalizadorSintactico$top) throws java.lang.Exception { java_cup.runtime.Symbol CUP$AnalizadorSintactico$result; switch (CUP$AnalizadorSintactico$act_num) { case 11: // termino ::= ENTERO {

Integer RESULT =null; int eleft = ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.peek()).left; int eright = ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.peek()).right; Integer e = (Integer)((java_cup.runtime.Symbol) CUP$AnalizadorSintactico$stack.peek()).value; RESULT = e; CUP$AnalizadorSintactico$result parser.getSymbolFactory().newSymbol("termino",4, ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.peek()), ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.peek()), RESULT); } return CUP$AnalizadorSintactico$result;

=

RESULT = new Integer(f.intValue() * e.intValue());

/*. . . . . . . . . . . . . . . . . . . .*/ case 10: // termino ::= PARENIZQ expr PARENDER { Integer RESULT =null; int eleft = ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.elementAt(CUP $AnalizadorSintactico$top-1)).left; int eright = ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.elementAt(CUP $AnalizadorSintactico$top-1)).right; Integer e = (Integer)((java_cup.runtime.Symbol) CUP$AnalizadorSintactico$stack.elementAt(CUP$AnalizadorSintactico$top1)).value; RESULT = e; CUP$AnalizadorSintactico$result = parser.getSymbolFactory().newSymbol("termino",4, ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.elementAt(CUP $AnalizadorSintactico$top-2)), ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.peek()), RESULT); } return CUP$AnalizadorSintactico$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 9: // factor ::= termino { Integer RESULT =null; int tleft = ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.peek()).left; int tright = ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.peek()).right; Integer t = (Integer)((java_cup.runtime.Symbol) CUP$AnalizadorSintactico$stack.peek()).value; RESULT = t; CUP$AnalizadorSintactico$result parser.getSymbolFactory().newSymbol("factor",3, ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.peek()), ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.peek()), RESULT); } return CUP$AnalizadorSintactico$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 8: // factor ::= factor OP_MULT termino { Integer RESULT =null;

int fleft = ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.elementAt(CUP $AnalizadorSintactico$top-2)).left; int fright = ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.elementAt(CUP $AnalizadorSintactico$top-2)).right; Integer f = (Integer)((java_cup.runtime.Symbol) CUP$AnalizadorSintactico$stack.elementAt(CUP$AnalizadorSintactico$top2)).value; int eleft = ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.peek()).left; int eright = ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.peek()).right; Integer e = (Integer)((java_cup.runtime.Symbol) CUP$AnalizadorSintactico$stack.peek()).value;

=

CUP$AnalizadorSintactico$result = parser.getSymbolFactory().newSymbol("factor",3, ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.elementAt(CUP $AnalizadorSintactico$top-2)), ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.peek()), RESULT); } return CUP$AnalizadorSintactico$result; /*. . . . . . . . . . . . . . . . . . . .*/ case 7: // expr ::= factor { Integer RESULT =null; int nleft = ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.peek()).left; int nright = ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.peek()).right; Integer n = (Integer)((java_cup.runtime.Symbol) CUP$AnalizadorSintactico$stack.peek()).value; RESULT = n; CUP$AnalizadorSintactico$result parser.getSymbolFactory().newSymbol("expr",2, ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.peek()), ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.peek()), RESULT); } return CUP$AnalizadorSintactico$result;

=

/*. . . . . . . . . . . . . . . . . . . .*/ case 6: // expr ::= expr OP_RESTA factor { Integer RESULT =null; int eleft = ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.elementAt(CUP $AnalizadorSintactico$top-2)).left; int eright = ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.elementAt(CUP $AnalizadorSintactico$top-2)).right; Integer e = (Integer)((java_cup.runtime.Symbol) CUP$AnalizadorSintactico$stack.elementAt(CUP$AnalizadorSintactico$top2)).value; int fleft = ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.peek()).left; int fright = ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.peek()).right; Integer f = (Integer)((java_cup.runtime.Symbol) CUP$AnalizadorSintactico$stack.peek()).value;

RESULT = new Integer(e.intValue() - f.intValue()); CUP$AnalizadorSintactico$result = parser.getSymbolFactory().newSymbol("expr",2, ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.elementAt(CUP $AnalizadorSintactico$top-2)), ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.peek()), RESULT); } return CUP$AnalizadorSintactico$result;

case 3: // NT$0 ::= { Object RESULT =null; int eleft = ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.peek()).left; int eright = ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.peek()).right; Integer e = (Integer)((java_cup.runtime.Symbol) CUP$AnalizadorSintactico$stack.peek()).value; System.out.println(" = " + e);

/*. . . . . . . . . . . . . . . . . . . .*/ case 5: // expr ::= expr OP_SUMA factor { Integer RESULT =null; int eleft = ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.elementAt(CUP $AnalizadorSintactico$top-2)).left; int eright = ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.elementAt(CUP $AnalizadorSintactico$top-2)).right; Integer e = (Integer)((java_cup.runtime.Symbol) CUP$AnalizadorSintactico$stack.elementAt(CUP$AnalizadorSintactico$top2)).value; int fleft = ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.peek()).left; int fright = ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.peek()).right; Integer f = (Integer)((java_cup.runtime.Symbol) CUP$AnalizadorSintactico$stack.peek()).value;

CUP$AnalizadorSintactico$result parser.getSymbolFactory().newSymbol("NT$0",5, ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.peek()), ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.peek()), RESULT); } return CUP$AnalizadorSintactico$result;

=

case 2: // expr_list ::= expr_part { Object RESULT =null; CUP$AnalizadorSintactico$result parser.getSymbolFactory().newSymbol("expr_list",0, ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.peek()), ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.peek()), RESULT); } return CUP$AnalizadorSintactico$result;

=

RESULT = new Integer(e.intValue() + f.intValue()); CUP$AnalizadorSintactico$result = parser.getSymbolFactory().newSymbol("expr",2, ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.elementAt(CUP $AnalizadorSintactico$top-2)), ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.peek()), RESULT); } return CUP$AnalizadorSintactico$result; case 4: // expr_part ::= expr NT$0 SEMI { Object RESULT =null; // propagate RESULT from NT$0 RESULT = (Object) ((java_cup.runtime.Symbol) CUP$AnalizadorSintactico$stack.elementAt(CUP$AnalizadorSintactico$top1)).value; int eleft = ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.elementAt(CUP $AnalizadorSintactico$top-2)).left; int eright = ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.elementAt(CUP $AnalizadorSintactico$top-2)).right; Integer e = (Integer)((java_cup.runtime.Symbol) CUP$AnalizadorSintactico$stack.elementAt(CUP$AnalizadorSintactico$top2)).value; CUP$AnalizadorSintactico$result = parser.getSymbolFactory().newSymbol("expr_part",1, ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.elementAt(CUP $AnalizadorSintactico$top-2)), ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.peek()), RESULT); } return CUP$AnalizadorSintactico$result;

case 1: // $START ::= expr_list EOF { Object RESULT =null; int start_valleft = ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.elementAt(CUP $AnalizadorSintactico$top-1)).left; int start_valright = ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.elementAt(CUP $AnalizadorSintactico$top-1)).right; Object start_val = (Object)((java_cup.runtime.Symbol) CUP$AnalizadorSintactico$stack.elementAt(CUP$AnalizadorSintactico$top1)).value; RESULT = start_val; CUP$AnalizadorSintactico$result = parser.getSymbolFactory().newSymbol("$START",0, ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.elementAt(CUP $AnalizadorSintactico$top-1)), ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.peek()), RESULT); } CUP$AnalizadorSintactico$parser.done_parsing(); return CUP$AnalizadorSintactico$result;

case 0: // expr_list ::= expr_list expr_part { Object RESULT =null; CUP$AnalizadorSintactico$result = parser.getSymbolFactory().newSymbol("expr_list",0, ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.elementAt(CUP $AnalizadorSintactico$top-1)), ((java_cup.runtime.Symbol)CUP$AnalizadorSintactico$stack.peek()), RESULT);

} return CUP$AnalizadorSintactico$result;

"Invalid action number found in internal parse table"); }

/* . . . . . .*/ default: throw new Exception(

} }

Clase Inicio.java es la clase principal donde se ejecutan las fases de análisis y se accede a la tabla de símbolos. A continuación código y capturas de pantalla.

package ejemplocup; import java.io.File; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Scanner; import java.util.logging.Level; import java.util.logging.Logger; public class Inicio { public final static int GENERAR = 1; public final static int EJECUTAR = 2; public final static int SALIR = 3; /** * Es un menu para elegir entre generar el analizador lexico y sintactico, o * ejecutarlos sobre un archivo de pruebas */ public static void main(String[] args) { java.util.Scanner in = new Scanner(System.in);

int valor = 0; do { System.out.println("Elija una opcion: "); System.out.println("1) Generar"); System.out.println("2) Ejecutar"); System.out.println("3) Salir"); System.out.print("Opcion: "); valor = in.nextInt(); switch (valor) { /* Generamos el analizador lexico y sintactico. lcalc.flex contiene la definicion del analizador lexico ycalc.cup contiene la definicion del analizador sintactico */ case GENERAR: { System.out.println("\n*** Generando ***\n"); String archLexico = ""; String archSintactico = ""; if (args.length > 0) { System.out.println("\n*** Procesando archivos custom ***\n"); archLexico = args[0]; archSintactico = args[1];

} else { System.out.println("\n*** Procesando archivo default

break; } default: { System.out.println("Opcion no valida!"); break; }

***\n"); archLexico = "alexico.flex"; archSintactico = "asintactico.cup"; } String[] alexico = {archLexico}; String[] asintactico = {"-parser", "AnalizadorSintactico", archSintactico}; jflex.Main.main(alexico); try { java_cup.Main.main(asintactico); } catch (Exception ex) { Logger.getLogger(Inicio.class.getName()).log(Level.SEVERE, null, ex); } //movemos los archivos generados boolean mvAL = moverArch("AnalizadorLexico.java"); boolean mvAS = moverArch("AnalizadorSintactico.java"); boolean mvSym= moverArch("sym.java"); if(mvAL && mvAS && mvSym){ System.exit(0); } System.out.println("Generado!"); break; } case EJECUTAR: { /* Ejecutamos el analizador lexico y sintactico sobre un archivo de pruebas. */ String[] archivoPrueba = {"test.txt"}; AnalizadorSintactico.main(archivoPrueba); System.out.println("Ejecutado!"); break; } case SALIR: { System.out.println("Adios!");

} } while (valor != 3); } public static boolean moverArch(String archNombre) { boolean efectuado = false; File arch = new File(archNombre); if (arch.exists()) { System.out.println("\n*** Moviendo " + arch + " \n***"); Path currentRelativePath = Paths.get(""); String nuevoDir = currentRelativePath.toAbsolutePath().toString() + File.separator + "src" + File.separator + "ejemplocup" + File.separator + arch.getName(); File archViejo = new File(nuevoDir); archViejo.delete(); if (arch.renameTo(new File(nuevoDir))) { System.out.println("\n*** Generado " + archNombre + "***\n"); efectuado = true; } else { System.out.println("\n*** No movido " + archNombre + " ***\n"); } } else { System.out.println("\n*** Codigo no existente ***\n"); } return efectuado; } }

Clase sym.java.- es la clase donde se almacena la tabla de símbolos. La tabla de símbolos es una estructura de datos que usa el proceso de traducción de un lenguaje de programación, por un compilador o un intérprete, donde cada símbolo en el código fuente de un programa está asociado con información tal como la ubicación, el tipo de datos y el ámbito de cada variable, constante o procedimiento. A continuación capturas de pantalla y código.

package ejemplocup; /** CUP generated class containing symbol constants. */ public class sym { /* terminals */ public static final int OP_RESTA = 4; public static final int OP_SUMA = 3; public static final int ENTERO = 8; public static final int OP_MULT = 5; public static final int SEMI = 2; public static final int EOF = 0; public static final int PARENIZQ = 6; public static final int error = 1; public static final int PARENDER = 7; }

Ejecución.- la ejecución es el proceso en el cual leemos un archivo fuente y lo analizamos con nuestro programa. A continuación el archivo o texto a analizar en nuestro caso es un fichero txt llamado test 2*3;2+3*3;4*4+2;3*(2+3*4)+1;5+90; Y los resultados:

Elegimos la opción 1) Generar

Volvemos a ejecutar

Elegimos opción dos en este caso es el análisis de nuestro documento test.txt

Bibliografía JAVA A TOPE:TRADUCTORES Y COMPILADORES CON LEX/YACC, JFLEX/CUP Y JAVACC. EDICIÓN ELECTRÓNICA. GÁLVEZ ROJAS SERGIO. MORA MATA MIGUEL ÁNGEL