En este post presento un interprete muy simple que puede ser usado como base para la construcción de algo mas complejo, la idea fundamental en ese, es ayudar a comprender el funcionamiento de Java CUP, un generador de analizadores sintácticos LALR para Java y JFLEX un generador de analizadores léxicos basados en tabla también para Java.
El interprete consiste en una aplicación por consola que recibe como parámetro el path del archivo que se desea interpretar, y simplemente ejecuta las instrucciones del archivo en forma secuencial.
El lenguaje permite describir operaciones matemáticas, en notación polaca usando la sintaxis siguiente:
push 10 : para ingresar un numero a la pila
print : para extraer un numero de la pila y mostrarlo en pantalla
add: suma los dos números mas arriba de la pila
sub: resta los dos números mas arriba de la pila
mult: multiplicación de los dos números mas arriba en la pila
div: división de los dos números mas arriba en la pila
Un ejemplo de archivo de entrada para la expresion ( ( 10 + 5 ) + 15 ) * 2
la salida para este ejemplo
la gramatica para este interprete es la siguiente
y para el analizador lexico
Código fuente en NetBeans
El interprete consiste en una aplicación por consola que recibe como parámetro el path del archivo que se desea interpretar, y simplemente ejecuta las instrucciones del archivo en forma secuencial.
El lenguaje permite describir operaciones matemáticas, en notación polaca usando la sintaxis siguiente:
push 10 : para ingresar un numero a la pila
print : para extraer un numero de la pila y mostrarlo en pantalla
add: suma los dos números mas arriba de la pila
sub: resta los dos números mas arriba de la pila
mult: multiplicación de los dos números mas arriba en la pila
div: división de los dos números mas arriba en la pila
Un ejemplo de archivo de entrada para la expresion ( ( 10 + 5 ) + 15 ) * 2
push 10 push 5 add push 15 add push 2 mult print
la salida para este ejemplo
la gramatica para este interprete es la siguiente
package test; import java_cup.runtime.*; parser code {: public CalculadoraDePila calc = new CalculadoraDePila(); :} terminal TOKEN_ADD, TOKEN_SUB, TOKEN_MULT, TOKEN_DIV, TOKEN_PUSH, TOKEN_PRINT; terminal String TOKEN_NUMBER; non terminal Documento; non terminal Lista; non terminal Elemento; Documento ::= Lista {: System.out.println("DOCUMENTO OK"); :}; Lista ::= Lista Elemento {: :} | Elemento {: :}; Elemento ::= TOKEN_ADD {: parser.calc.add(); :} | TOKEN_SUB {: parser.calc.sub(); :} | TOKEN_MULT {: parser.calc.mult(); :} | TOKEN_DIV {: parser.calc.div(); :} | TOKEN_PRINT {: parser.calc.print(); :} | TOKEN_PUSH TOKEN_NUMBER:n {: Integer numero = Integer.parseInt( n ); parser.calc.push( numero ); :};
y para el analizador lexico
package test; import java_cup.runtime.Symbol; %% %{ %} %line %char %cup %% [0-9]+ { return new Symbol( sym.TOKEN_NUMBER , yytext() ); } "push" { return new Symbol( sym.TOKEN_PUSH , yytext() ); } "add" { return new Symbol( sym.TOKEN_ADD , yytext() ); } "sub" { return new Symbol( sym.TOKEN_SUB , yytext() ); } "div" { return new Symbol( sym.TOKEN_DIV , yytext() ); } "mult" { return new Symbol( sym.TOKEN_MULT , yytext() ); } "print" { return new Symbol( sym.TOKEN_PRINT , yytext() ); } [\n\r\t ]+ { } . { System.out.println( "Caracter no Esperado, ERROR LEXICO " + yytext() ); }
Código fuente en NetBeans
Imagine que seria muy complicado entenderle a esto de los interpretes, y con este post que publicaste es de mucha ayuda, se te agradece.. y ahorita que estoy empezando con esto de los compiladores e interpretes queria preguntarte si podrias darme alguna idea de como implementar un interprete para un ciclo while, aunque creo que esto es mas complejo. Saludos
ResponderBorraragregame al chat de google, y platicamos haber si te puedo orientar un poco
ResponderBorrarrudygt@gmail.com
ahora tengo un problema con cup, es ke nos dieron un ejemplo pero parece que esta malo :S, espero comprender ahora, gracias por el ejemplo :)
ResponderBorrar