Вы находитесь на странице: 1из 27

MONOGRAFA

Compilador usando Jflex Calculadora De Operaciones Basicas

Teora de Compiladores

RESUMEN

En un principio, En 1946 se desarroll el primer ordenador digital, estas mquinas


ejecutaban instrucciones consistentes en cdigos numricos que sealan a los circuitos
de la mquina los estados correspondientes a cada operacin. A esto se le llamo lenguaje
maquina.
Pronto los primeros usuarios de estos ordenadores descubrieron la ventaja de escribir sus
programas mediante claves ms fciles de recordar que esos cdigos numricos; al final,
todas esas claves juntas se traducan manualmente a Lenguaje Mquina.
La tarea de realizar un compilador no fue fcil. El primer compilador de FORTRAN tard
18 aos-persona en realizarse y era muy sencillo.
Como un ejemplo de ello tenemos el hecho de que los espacios en blanco fuesen
ignorados, debido a que el perifrico que se utilizaba como entrada de programas (una
lectora de tarjetas perforadas) contaba correctamente los espacios en blanco.
El lenguaje Java, establece que el compilador no genera cdigo para una mquina
determinada sino para una virtual, la Java Virtual Machine (JVM), que posteriormente ser
ejecutado por un intrprete, normalmente incluido en un navegador de Internet. El gran
objetivo de esta exigencia es conseguir la mxima portabilidad de los programas escritos
y compilados en Java, pues es nicamente la segunda fase del proceso la que depende
de la mquina concreta en la que se ejecuta el intrprete.

INTRODUCCION
En 1946 se desarroll el primer ordenador digital. Pronto los primeros usuarios de estos
ordenadores descubrieron la ventaja de escribir sus programas mediante claves ms
fciles de recordar que esos cdigos numricos; al final, todas esas claves juntas se
traducan manualmente a Lenguaje Mquina. Estas claves constituyen los llamados
lenguajes ensambladores, que se generalizaron en cuanto se dio el paso decisivo de
hacer que las propias mquinas realizaran el proceso mecnico de la traduccin. A este
trabajo se le llama ensamblar el programa.
En el caso particular de que el lenguaje a traducir es un lenguaje de alto nivel y el
lenguaje traducido de bajo nivel, se emplea el trmino compilador.
La tarea de realizar un compilador no fue fcil. El primer compilador de FORTRAN tard
18 aos-persona en realizarse y era muy sencillo. Este desarrollo del FORTRAN estaba
muy influenciado por la mquina objeto en la que iba a ser implementado. Como un
ejemplo de ello tenemos el hecho de que los espacios en blanco fuesen ignorados, debido
a que el perifrico que se utilizaba como entrada de programas (una lectora de tarjetas
perforadas) no contaba correctamente los espacios en blanco.
Paralelamente al desarrollo de FORTRAN en Amrica, en Europa surgi una corriente
ms universitaria, que pretenda que la definicin de un lenguaje fuese independiente de
la mquina y en donde los algoritmos se pudieran expresar de forma ms simple.
En 1969, el lenguaje fue revisado y llev a una nueva versin que se llam ALGOL 60.
Junto a este desarrollo en los lenguajes, tambin se iba avanzando en la tcnica de
compilacin. En 1958, Strong y otros proponan una solucin al problema de que un
compilador fuera utilizable por varias mquinas objeto.
En 1975, con la aparicin de LEX surge el concepto de un generador automtico de
analizadores lxicos a partir de expresiones regulares, basado en el sistema operativo
UNIX. A partir de los trabajos de Chomsky ya citados, se produce una sistematizacin de
la sintaxis de los lenguajes de programacin, y con ello un desarrollo de diversos mtodos
de anlisis sintctico.

A mitad de la dcada de los 60, Knuth define las gramticas LR y describe la construccin
de una tabla cannica de parser LR. Por otra parte, el uso por primera vez de un parsing
descendente recursivo tuvo lugar en el ao 1961. En el ao 1968 se estudian y definen
las gramticas LL as como los parsers predictivos.
En los primeros lenguajes (FORTRAN y ALGOL 60) los tipos posibles de los datos eran
muy simples, y la comprobacin de tipos era muy sencilla.
En la actualidad, el proceso de la compilacin ya est muy asentado. Un compilador es
una herramienta bien conocida, dividida en diversas fases. Algunas de estas fases se
pueden generar automticamente (analizador lxico y sintctico) y otras requieren una
mayor atencin por parte del escritor de compiladores (las partes de traduccin y
generacin de cdigo).
De todas formas, y en contra de lo que quiz pueda pensarse, todava se estn llevando a
cabo varias vas de investigacin en este fascinante campo de la compilacin.

MARCO TEORICO

1. COMPILADOR
Tambin llamado traductor, es cualquier programa que toma como entrada un texto escrito
en un lenguaje, llamado fuente y da como salida otro texto en un lenguaje, denominado
objeto.
En el caso de que el lenguaje fuente sea un lenguaje de programacin de alto nivel y el
objeto sea un lenguaje de bajo nivel (ensamblador o cdigo de mquina), a dicho
traductor se le denomina compilador.

La mejor informacin sobre los errores por parte del compilador as como una mayor
velocidad de ejecucin del cdigo resultante hizo que poco a poco se impusieran los
compiladores.
Hoy en da, y con el problema de la memoria prcticamente resuelto, se puede hablar de
un gran predominio de los compiladores frente a los intrpretes, aunque intrpretes como
los incluidos en los navegadores de Internet para interpretar el cdigo JVM de Java son la
gran excepcin.
Un compilador no es un programa que funciona de manera aislada, sino que necesita de
otros programas para conseguir su objetivo.
1.1)

PARTES DE UN COMPILADOR

La construccin de un compilador involucra la divisin del proceso en una serie de fases


que variar con su complejidad. Generalmente estas fases se agrupan en dos tareas: el
anlisis del programa fuente y la sntesis del programa objeto.

Anlisis: Se trata de la comprobacin de la correccin del programa fuente, e


incluye las fases correspondientes al Anlisis Lxico (que consiste en la
descomposicin del programa fuente en componentes lxicos), Anlisis Sintctico
(agrupacin de los componentes lxicos en frases gramaticales ) y Anlisis
Semntico (comprobacin de la validez semntica de las sentencias aceptadas en
la fase de Anlisis Sintctico).

Sntesis: Su objetivo es la generacin de la salida expresada en el lenguaje objeto


y suele estar formado por una o varias combinaciones de fases de Generacin de
Cdigo (normalmente se trata de cdigo intermedio o de cdigo objeto) y de
Optimizacin de Cdigo (en las que se busca obtener un cdigo lo ms eficiente
posible).

Alternativamente, las fases descritas para las tareas de anlisis y sntesis se pueden
agrupar en Front-end y Back-end:

Front-end: Es la parte que analiza el cdigo fuente, comprueba su validez, genera


el rbol de derivacin y rellena los valores de la tabla de smbolos. Esta parte
suele ser independiente de la plataforma o sistema para el cual se vaya a
compilar, y est compuesta por las fases comprendidas entre el Anlisis Lxico y
la Generacin de Cdigo Intermedio.

Back-end: Es la parte que genera el cdigo mquina, especfico de una


plataforma, a partir de los resultados de la fase de anlisis, realizada por el Front
End.

Esta divisin permite que el mismo Back End se utilice para generar el cdigo mquina de
varios lenguajes de programacin distintos y que el mismo Front End que sirve para
analizar el cdigo fuente de un lenguaje de programacin concreto sirva para generar
cdigo mquina en varias plataformas distintas. Suele incluir la generacin y optimizacin
del cdigo dependiente de la mquina.
El cdigo que genera el Back End normalmente no se puede ejecutar directamente, sino
que necesita ser enlazado por un programa enlazador (linker)

2. INTERPRETES VS COMPILADORES

Inicialmente interpretes eran ms comunes.


Hoy en da, los compiladores son ms comunes:
Compila una vez, ejecuta muchas veces.
Ejecucin programa objeto ms rpida.
Compilador tiene una visin ms global del programa.
Interprete sin embargo da mejor diagnostico de errores.

3. TIPOS DE COMPILADORES

Ensamblador: lenguaje fuente = ensamblador


Compilador con montador: compila modulo independientes y luego los enlaza
Auto compilador: escrito en el mismo lenguaje que va a compilar
Descompilador: realiza proceso inverso a la compilacin.

4. ESTRUCTURA DE UN COMPILADOR

5. ANALISIS LXICO

Lee caracteres uno a uno y forma grupos de caracteres con alguna relacin entre
s (tokens).

Cada token es una secuencia de caracteres tratados como una unica entidad.

6. ANALISIS SINTCTICO

Recibe como entrada los tokens que le pasa el analizador lxico.


Comprueba si los tokens llegan en order correcto (orden permitido por el lenguaje).
La salida es un arbol sintctico (arbol de parse).
Cuando el programa fuente es incorrecto (sintacticamente) el analizador sintactico
es el responsable de producir un mensaje de error.

7. ANALISIS SEMNTICO
Comprueba que lo que el significado de lo que se va leyendo es vlido.
8. GESTION DE ERRORES
Se utiliza en todas las fases, pero especialmente en las de anlisis sintctico y semntico.
Es una tarea difcil:
Un error puede ocultar otros.
Un error puede provocar una avalancha de otros.
Importante tener un buen manejo de errores:
Que detecte todos los errores.
Que no deje de compilar al detectar el primer error.

9. FORMAS DE EXAMINAR UN COMPILADOR


9.1)

FASE DE ANALISIS

En esta fase el programa es descompuesto en sus elementos fundamentales.


Abarca el anlisis lxico, el anlisis sintctico y el anlisis semntico.
Esta fase verifica si el programa en lenguaje fuente es correcto, y recoge la informacin
necesaria en la tabla de smbolos para el mdulo de sntesis.
Si detecta la existencia de errores, se notifican por medio del gestor de errores.

9.2)

FASE DE SINTESIS

Esta fase se lleva a cabo una vez que el mdulo de anlisis ha verificado que el cdigo
fuente es correcto.
La informacin recogida en el mdulo de anlisis y almacenada en la tabla de smbolos
se emplea en la fase de sntesis para la generacin del cdigo objeto.
Abarca la generacin de cdigo intermedio, y en el caso de los compiladores, la
generacin de cdigo y la optimizacin del mismo.

9.3)

AGRUPAMIENTO DE FASES
Front-end: depende del lenguaje fuente, independiente del lenguaje objeto.
Back-end: depende del lenguaje objeto y es independiente del lenguaje fuente.

10. TABLA DE SMBOLOS

Un compilador necesita guardar y usar la informacin de los objetos que va

encontrando en el texto fuente.


Esta informacin se almacena en una estructura de datos interna: tabla de
smbolos, Accesos a la tabla deben ser rpidos.

11. HERRAMIENTAS QUE MUESTRAN TIPOS DE ANLISIS DE PROGRAMAS


FUENTE

11.1) Editores de estructuras


11.2) Impresoras estticas: Una impresora esttica analiza un programa y lo
imprime de forma que la estructura del programa resulte claramente visible.
11.3) Verificadores estticos: Un verificador esttico lee un programa, lo analiza
e intenta descubrir errores potenciales sin ejecutar el programa
11.4) Intrpretes: En lugar de producir un programa objeto como resultado de una
traduccin, un intrprete realiza las operaciones que implica el programa fuente.

12. JFLEX

JFLEX es un generador de analizador lxico para java1 escrito en Java, fue desarrollado
por Elliot Berk Universidad de Princeton. Generador de programas java diseado para
procesamiento lxico, Parte de un conjunto de reglas lxicas. JFlex produce un programa
llamado Yylex que reconoce las cadenas que cumplen dichas reglas.

12.1) OBJETIVOS DE DISEO


Los objetivos de diseo principales de JFLEX son:
Completo soporte Unicode
Rpido generados escneres
Generacin de escner rpido
Sintaxis de especificacin de Conveniente
Independencia de plataforma
Compatibilidad con JLex

La velocidad suele ser proporcional a la cantidad de caracteres en la entrada. El nmero o


la complejidad de la reglas slo influyen sobre el tamao del autmata.

12.2) OPCIONES Y DECLARACIONES


Opciones del cdigo generado:
%class nombre Especifica el nombre de la clase generada como salida de JFlex.
%line y %column activan cuenta de lneas (yyline) y columnas (yycolumn)
respectivamente.
%standalone Genera programa que acepta un fichero de entrada en lnea de comando.
%debug Durante la ejecucin muestra: n lnea de la especificacin, lexema reconocido
y accin ejecutada.

12.3) REGLAS LEXICAS


Especificacin de las expresiones:

expresiones regulares: sean a y b expresiones vlidas

a | b Unin
a b Concatenacin
a* Repeticin 0 o N veces
a+ Repeticin 1 o N veces (= a a*)
a? Opcionalidad
!a Negacin
~a Cualquier cosa que termine

12.4) FUNCIONES DEL JFLEX

yytext() Devuelve el lexema reconocido.


yylength() Devuelve el la longitud del lexema.
yycharat( int n ) Devuelve el ensimo carcter del lexema reconocido.
yypushback( int n ) Considera los n ltimos caracteres del lexema reconocido

como no procesados. Se volvern a leer, pero no se tendrn en cuenta para:


yytext() e yylength().

13. PROYECTO CALCULADORA USANDO JFLEX


13.1) Calculadora
Calc.flex
%%
%byaccj
%{
private Parser yyparser;
public Yylex(java.io.Reader r, Parser yyparser) {
this(r);
this.yyparser = yyparser;
}
%}
NUM = [0-9]+ ("." [0-9]+)?
NL = \n | \r | \r\n
%%
/* operators */

"+" |
"-" |
"*" |
"/" |
"^" |
"(" |
")" { return (int) yycharat(0); }
/* newline */
{NL} { return Parser.NL; }
/* float */
{NUM} { yyparser.yylval = new ParserVal(Double.parseDouble(yytext()));
return Parser.NUM; }
/* whitespace */
[ \t]+ { }
\b

{ System.err.println("Sorry, backspace doesn't work"); }

/* error fallback */
[^] { System.err.println("Error: unexpected character '"+yytext()+"'"); return -1; }
Calcy.y
%{
import java.io.*;
%}
%token NL
/* newline */
%token <dval> NUM /* a number */
%type <dval> exp
%left '-' '+'
%left '*' '/'
%left NEG
%right '^'

/* negation--unary minus */
/* exponentiation
*/

%%
input: /* empty string */
| input line
;
line:

NL
{ if (interactive) System.out.print("Ingrese su operacin: "); }
| exp NL { x=$1 + "";
if(x.equals("Infinity"))System.out.println(" Indeterminado ");
else System.out.println(" = " + x );
if (interactive) System.out.print("Ingrese su operacin: "); }

;
exp:

NUM
{ $$ = $1; }
| exp '+' exp
{ $$ = $1 + $3; }
| exp '-' exp
{ $$ = $1 - $3; }
| exp '*' exp
{ $$ = $1 * $3; }
| exp '/' exp
{ $$ = $1 / $3; }
| '-' exp %prec NEG { $$ = -$2; }
| exp '^' exp
{ $$ = Math.pow($1, $3); }
| '(' exp ')'
{ $$ = $2; }
;

%%
private Yylex lexer;
String x;
private int yylex () {
int yyl_return = -1;
try {
yylval = new ParserVal(0);
yyl_return = lexer.yylex();
}
catch (IOException e) {
System.err.println("IO error :"+e);
}
return yyl_return;
}
public void yyerror (String error) {
System.err.println ("Error: " + error);
}
public void yyerrork (String error) throws Exception {
System.err.println ("Error: " + error);
throw new Exception("Error Exception");
}
public Parser(Reader r) {
lexer = new Yylex(r, this);
}
static boolean interactive;
public static void main(String args[]) throws IOException {
System.out.println("BYACC/Java with JFlex Calculator Demo");

Parser yyparser;
if ( args.length > 0 ) {
// parse a file
yyparser = new Parser(new FileReader(args[0]));
}
else {
// interactive mode
//System.out.println("[Quit with CTRL-D]");
System.out.print("Ingrese su operacn: ");
interactive = true;
yyparser = new Parser(new InputStreamReader(System.in));
}
yyparser.yyparse();
if (interactive) {
System.out.println();
System.out.println("Ingrese una operacion!!!!!!");
}
}
Calculadora.Java
import java.io.*;
public class Parser
{
boolean yydebug;
//do I want debug output?
int yynerrs;
//number of errors so far
int yyerrflag;
//was there an error?
int yychar;
//the current working character
void debug(String msg)
{
if (yydebug)
System.out.println(msg);
}
final static int YYSTACKSIZE = 500; //maximum stack size
int statestk[] = new int[YYSTACKSIZE]; //state stack
int stateptr;
int stateptrmax;
//highest index of stackptr
int statemax;
//state when highest index reached
final void state_push(int state)
{
try {
stateptr++;
statestk[stateptr]=state;
}

catch (ArrayIndexOutOfBoundsException e) {
int oldsize = statestk.length;
int newsize = oldsize * 2;
int[] newstack = new int[newsize];
System.arraycopy(statestk,0,newstack,0,oldsize);
statestk = newstack;
statestk[stateptr]=state;
}
}
final int state_pop()
{
return statestk[stateptr--];
}
final void state_drop(int cnt)
{
stateptr -= cnt;
}
final int state_peek(int relative)
{
return statestk[stateptr-relative];
}
final boolean init_stacks()
{
stateptr = -1;
val_init();
return true;
}
void dump_stacks(int count)
{
int i;
System.out.println("=index==state====value= s:"+stateptr+" v:"+valptr);
for (i=0;i<count;i++)
System.out.println(" "+i+" "+statestk[i]+"
"+valstk[i]);
System.out.println("======================");
}
String yytext;//user variable to return contextual strings
ParserVal yyval; //used to return semantic vals from action routines
ParserVal yylval;//the 'lval' (result) I got from yylex()
ParserVal valstk[];
int valptr;
void val_init()
{
valstk=new ParserVal[YYSTACKSIZE];
yyval=new ParserVal();
yylval=new ParserVal();
valptr=-1;
}
void val_push(ParserVal val)

{
if (valptr>=YYSTACKSIZE)
return;
valstk[++valptr]=val;
}
ParserVal val_pop()
{
if (valptr<0)
return new ParserVal();
return valstk[valptr--];
}
void val_drop(int cnt)
{
int ptr;
ptr=valptr-cnt;
if (ptr<0)
return;
valptr = ptr;
}
ParserVal val_peek(int relative)
{
int ptr;
ptr=valptr-relative;
if (ptr<0)
return new ParserVal();
return valstk[ptr];
}
//#### end semantic value section ####
public final static short NL=257;
public final static short NUM=258;
public final static short NEG=259;
public final static short YYERRCODE=256;
final static short yylhs[] = {
-1,
0, 0, 2, 2, 1, 1, 1, 1, 1, 1,
1, 1,
};
final static short yylen[] = {
2,
0, 2, 1, 2, 1, 3, 3, 3, 3, 2,
3, 3,
};
final static short yydefred[] = {
1,
0, 3, 5, 0, 0, 0, 2, 0, 0, 4, 0, 0, 0, 0, 0, 12, 0, 0, 0,
0,};
final static short yydgoto[] = {
1, 6, 7,};
final static short yysindex[] = {
0, -40, 0, 0, -39, -39, -1, 0, -92,
0,
-39, -39, -39, -39, -39, 0, -30, -30, -92, -92, -92,};
final static short yyrindex[] = {
0, 0, 0, 0, 0, 0, 0, 0, -34,
0,
0, 0, 0, 0, 0, 0, -10, -5, -27, -20, -13,};
final static short yygindex[] = {
0, 54, 0,};

0,
6,
0,

final static int YYTABLESIZE=256;


static short yytable[];
static { yytable();}
static void yytable(){
yytable = new short[]{
5,
5, 15, 0, 0, 4, 4, 10, 10, 10, 0, 10, 13, 10, 8, 8, 8, 14, 8, 0,
8,
9, 9, 9, 0, 9, 0, 9, 11, 11, 11, 7, 11, 7, 11, 7, 6, 0, 6, 0, 6,
13, 12, 0, 11, 0, 14, 16, 13, 12, 0, 11, 0, 14, 0, 0, 0, 0, 8, 9,
0,
0, 0, 0, 15, 17, 18, 19, 20, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 15,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 3, 0,
0, 0, 10, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0,
0, 0, 0, 11, 0, 0, 7, 0, 0, 0, 0, 6, 0, 0, 0, 10,};
}
static short yycheck[];
static { yycheck(); }
static void yycheck() {
yycheck = new short[] {
40, 40, 94, -1, -1, 45, 45, 41, 42, 43, -1,
45, 42, 47, 41, 42, 43, 47, 45, -1, 47, 41, 42, 43, -1, 45, -1, 47, 41,
42, 43,
41, 45, 43, 47, 45, 41, -1, 43, -1, 45, 42, 43, -1, 45, -1, 47, 41, 42,
43, -1,
45, -1, 47, -1, -1, -1, -1, 4, 5, -1, -1, -1, -1, 94, 11, 12, 13, 14, 15,
-1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, 94, -1, -1, -1, -1, -1, -1, 94, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, 257, 258, 258, -1, -1, -1, 257, -1, -1, -1, -1, -1, -1,
257,
-1, -1, -1, -1, -1, -1, 257, -1, -1, -1, -1, -1, -1, 257, -1, -1, 257, -1, -1,
-1,
-1, 257, -1, -1, -1, 257,};
}
final static short YYFINAL=1;
final static short YYMAXTOKEN=259;
final static String yyname[] = {
"end-offile",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null

,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,"'('","')'","'*'","'+'"
,null,"'-'",null,"'/'",null,null,null,null,null,null,null,null,null,null,null,null,
null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,
null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,"'^'",null,null,null
,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,nul
l,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,
null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null
,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,nul
l,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,
null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null
,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,nul
l,null,null,null,null,null,null,null,null,null,null,"NL","NUM","NEG",
};
final static String yyrule[] = {
"$accept : input",
"input :",
"input : input line",
"line : NL",
"line : exp NL",
"exp : NUM",
"exp : exp '+' exp",
"exp : exp '-' exp",
"exp : exp '*' exp",
"exp : exp '/' exp",
"exp : '-' exp",
"exp : exp '^' exp",
"exp : '(' exp ')'",
};
//#line 65 "calcy.y"
private Yylex lexer;
String x;
private int yylex () {
int yyl_return = -1;
try {
yylval = new ParserVal(0);
yyl_return = lexer.yylex();
}
catch (IOException e) {
System.err.println("IO error :"+e);
}
return yyl_return;
}
public void yyerror (String error) {
System.err.println ("Error: " + error);
}
public void yyerrork (String error) throws Exception {
System.err.println ("Error: " + error);

throw new Exception("Error Exception");


}
public Parser(Reader r) {
lexer = new Yylex(r, this);
}
static boolean interactive;
public static void main(String args[]) throws IOException {
System.out.println("Calculadora ");
System.out.println("Curso de Compiladores");
System.out.println("Alumno: Huber Ivan Quispe Maquera");
System.out.println("************************************************");
/*
****************************************************************/
Parser yyparser;
if ( args.length > 0 ) {
// parse a file
yyparser = new Parser(new FileReader(args[0]));
}
else {
// interactive mode
//System.out.println("[Quit with CTRL-D]");
System.out.print("Ingrese su operacion: ");
interactive = true;
yyparser = new Parser(new InputStreamReader(System.in));
}
yyparser.yyparse();
if (interactive) {
System.out.println();
System.out.println("Ingrese una operacion!!!!!!!");
}
}
void yylexdebug(int state,int ch)
{
String s=null;
if (ch < 0) ch=0;
if (ch <= YYMAXTOKEN) //check index bounds
s = yyname[ch]; //now get it
if (s==null)
s = "illegal-symbol";
debug("state "+state+", reading "+ch+" ("+s+")");
}
int yyn;
//next next thing to do
int yym;
//
int yystate; //current parsing state from state table

String yys;

//current token string

int yyparse()
{
boolean doaction;
init_stacks();
yynerrs = 0;
yyerrflag = 0;
yychar = -1;
//impossible char forces a read
yystate=0;
//initial state
state_push(yystate); //save it
val_push(yylval); //save empty value
while (true) //until parsing is done, either correctly, or w/error
{
doaction=true;
if (yydebug) debug("loop");
//#### NEXT ACTION (from reduction table)
for (yyn=yydefred[yystate];yyn==0;yyn=yydefred[yystate])
{
if (yydebug) debug("yyn:"+yyn+" state:"+yystate+" yychar:"+yychar);
if (yychar < 0)
//we want a char?
{
yychar = yylex(); //get next token
if (yydebug) debug(" next yychar:"+yychar);
//#### ERROR CHECK ####
if (yychar < 0) //it it didn't work/error
{
yychar = 0;
//change it to default string (no -1!)
if (yydebug)
yylexdebug(yystate,yychar);
}
}//yychar<0
yyn = yysindex[yystate]; //get amount to shift by (shift index)
if ((yyn != 0) && (yyn += yychar) >= 0 &&
yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
{
if (yydebug)
debug("state "+yystate+", shifting to state "+yytable[yyn]);
//#### NEXT STATE ####
yystate = yytable[yyn];//we are in a new state
state_push(yystate); //save it
val_push(yylval);
//push our lval as the input for next rule
yychar = -1;
//since we have 'eaten' a token, say we need another
if (yyerrflag > 0) //have we recovered an error?
--yyerrflag;
//give ourselves credit
doaction=false;
//but don't process yet
break; //quit the yyn=0 loop
}
yyn = yyrindex[yystate]; //reduce
if ((yyn !=0 ) && (yyn += yychar) >= 0 &&

yyn <= YYTABLESIZE && yycheck[yyn] == yychar)


{ //we reduced!
if (yydebug) debug("reduce");
yyn = yytable[yyn];
doaction=true; //get ready to execute
break;
//drop down to actions
}
else //ERROR RECOVERY
{
if (yyerrflag==0)
{
yyerror("syntax error");
yynerrs++;
}
if (yyerrflag < 3) //low error count?
{
yyerrflag = 3;
while (true) //do until break
{
if (stateptr<0) //check for under & overflow here
{
yyerror("stack underflow. aborting..."); //note lower case 's'
return 1;
}
yyn = yysindex[state_peek(0)];
if ((yyn != 0) && (yyn += YYERRCODE) >= 0 &&
yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
{
if (yydebug)
debug("state "+state_peek(0)+", error recovery shifting to state "+yytable[yyn]+"
");
yystate = yytable[yyn];
state_push(yystate);
val_push(yylval);
doaction=false;
break;
}
else
{
if (yydebug)
debug("error recovery discarding state "+state_peek(0)+" ");
if (stateptr<0) //check for under & overflow here
{
yyerror("Stack underflow. aborting..."); //capital 'S'
return 1;
}
state_pop();
val_pop();
}
}
}

else
//discard this token
{
if (yychar == 0)
return 1; //yyabort
if (yydebug)
{
yys = null;
if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
if (yys == null) yys = "illegal-symbol";
debug("state "+yystate+", error recovery discards token "+yychar+" ("+yys+")");
}
yychar = -1; //read another
}
}//end error recovery
}//yyn=0 loop
if (!doaction) //any reason not to proceed?
continue;
//skip action
yym = yylen[yyn];
//get count of terminals on rhs
if (yydebug)
debug("state "+yystate+", reducing "+yym+" by rule "+yyn+" ("+yyrule[yyn]+")");
if (yym>0)
//if count of rhs not 'nil'
yyval = val_peek(yym-1); //get current semantic value
switch(yyn)
{
//########## USER-SUPPLIED ACTIONS ##########
case 3:
//#line 46 "calcy.y"
{ if (interactive) System.out.print("Ingrese su operacin: "); }
break;
case 4:
//#line 47 "calcy.y"
{ x=val_peek(1).dval + "";
if(x.equals("Infinity"))System.out.println(" Indeterminado ");
else System.out.println("El resultado es: = " + x );
if (interactive) System.out.print("Ingrese su operacion: "); }
break;
case 5:
//#line 54 "calcy.y"
{ yyval.dval = val_peek(0).dval; }
break;
case 6:
//#line 55 "calcy.y"
{ yyval.dval = val_peek(2).dval + val_peek(0).dval; }
break;
case 7:
//#line 56 "calcy.y"
{ yyval.dval = val_peek(2).dval - val_peek(0).dval; }
break;
case 8:
//#line 57 "calcy.y"
{ yyval.dval = val_peek(2).dval * val_peek(0).dval; }

break;
case 9:
//#line 58 "calcy.y"
{ yyval.dval = val_peek(2).dval / val_peek(0).dval; }
break;
case 10:
//#line 59 "calcy.y"
{ yyval.dval = -val_peek(0).dval; }
break;
case 11:
//#line 60 "calcy.y"
{ yyval.dval = Math.pow(val_peek(2).dval, val_peek(0).dval); }
break;
case 12:
//#line 61 "calcy.y"
{ yyval.dval = val_peek(1).dval; }
break;
//#line 473 "Parser.java"
//########## END OF USER-SUPPLIED ACTIONS ##########
}//switch
//#### Now let's reduce... ####
if (yydebug) debug("reduce");
state_drop(yym);
//we just reduced yylen states
yystate = state_peek(0); //get new state
val_drop(yym);
//corresponding value drop
yym = yylhs[yyn];
//select next TERMINAL(on lhs)
if (yystate == 0 && yym == 0)//done? 'rest' state and at first TERMINAL
{
if (yydebug) debug("After reduction, shifting from state 0 to state "+YYFINAL+"");
yystate = YYFINAL;
//explicitly say we're done
state_push(YYFINAL);
//and save it
val_push(yyval);
//also save the semantic value of parsing
if (yychar < 0)
//we want another character?
{
yychar = yylex();
//get next character
if (yychar<0) yychar=0; //clean, if necessary
if (yydebug)
yylexdebug(yystate,yychar);
}
if (yychar == 0)
//Good exit (if lex returns 0 ;-)
break;
//quit the loop--all DONE
}//if yystate
else
//else not done yet
{
//get next state and push, for next yydefred[]
yyn = yygindex[yym];
//find out where to go
if ((yyn != 0) && (yyn += yystate) >= 0 &&
yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
yystate = yytable[yyn]; //get new state
else
yystate = yydgoto[yym]; //else go to new defred

if (yydebug) debug("after reduction, shifting from state "+state_peek(0)+" to state


"+yystate+"");
state_push(yystate); //going again, so push state & val...
val_push(yyval);
//for next action
}
}//main loop
return 0;//yyaccept!!
}
public void run()
{
yyparse();
}
public Parser()
{
//nothing to do
}
public Parser(boolean debugMe)
{
yydebug=debugMe;
}
}
//################### END OF CLASS ##############################

CONCLUSIONES
Este trabajo nos ayudo a comprender como es la creacin de un compilador, ya que en l
se detallan todas y cada una de las partes que involucran a este.

Primeramente se investigo que existen distintos tipos de compiladores, la funcin de los


mismo.
Por otro lado, comprend que un compilador, requiere de una sintaxis y lenguajes
especficos, ya que, al igual que el lenguaje humano, si no lo escribimos correctamente el
compilador no har lo que deseamos.
Se logro aprender que las herramientas que muestran tipos de anlisis de programas
fuente, son muy tiles al momento de crear un programa al codificar un algoritmo, ya que
estas herramientas nos ayudan formateando el texto, corrigiendo errores, entre otros.

REFERENCIAS

http://www.cc.uah.es/ie/docencia/ProcesadoresDeLenguaje/ProcesadoresDeLengu

ajeTema1_3xpagina.pdf
http://www.iua.upf.es/~rramirez/PL2/L02comp.pdf
http://www.willydev.net/descargas/prev/Compila.pdf
http://www.escet.urjc.es/~procesal/transp/Tema2-AnalizadorLexico-JFlex.pdf

Вам также может понравиться