Skip to content

Commit

Permalink
comprobacion de tipos, y ambitos
Browse files Browse the repository at this point in the history
  • Loading branch information
Jose Matute committed May 4, 2012
1 parent a7e1757 commit d651ef3
Show file tree
Hide file tree
Showing 13 changed files with 2,484 additions and 1,209 deletions.
358 changes: 358 additions & 0 deletions ;
@@ -0,0 +1,358 @@
import java_cup.runtime.*;
import java.util.*;
parser code {:

String errores = "";
Boolean has_main = false;
Boolean first_time = true;
Boolean in_method = false;

tabla ambito;
HashMap<String,Tipo> seen_types;
Tipo tmp_tipo;

public int getline(Object info){
if(info instanceof java_cup.runtime.Symbol) {
java_cup.runtime.Symbol s=((java_cup.runtime.Symbol)info);
return s.left;
}
return -1;

}


public void report_error(String message, Object info) {
StringBuffer m = new StringBuffer("Error");
if(info instanceof java_cup.runtime.Symbol) {
java_cup.runtime.Symbol s=((java_cup.runtime.Symbol)info);
if(s.left >= 0) {
m.append(" en linea "+(s.left+1));
if (s.right >= 0)
m.append(", y columna "+(s.right+1));
}
}
message = message.replaceAll("Syntax error","Error de sintaxis");
m.append(" : "+message);

errores += m;
errores += "\n";
System.out.println(m);
}

public void report_fatal_error(String message, Object info) {
message = message.replaceAll("Couldn't repair and continue parse","No se pudo recuperar");
report_error(message, info);

System.exit(1);
}

:}

terminal DO, PARDER, PARIZQ, TO, AS, DIM, SEPARADOR, FIN, REF, SUB, FUNCTION;
terminal IGUAL,LOOP,IF,THEN, ELSE, ELSEIF,END,FOR,NEXT,WHILE ,NUM,TRUE,FALSE;
terminal String NAME,OPREL,TIPO;
terminal WRITE,WRITELN,INPUT;
terminal POR,ENTRE,MAS,MENOS,ERROR;
terminal TYPE,EXIT, PUNTO,CADENA,NOT,SALTOCADENA;
non terminal String vars;
non terminal Tipo tipo;

non terminal Object statement, metodo, programa,linea, declaracion,declar_var, statements, loop_for, do_loop, if_block;
non terminal Object schrodingerArgument,asignacion,if_inner,list_declar,list_expressions,argument, argumentlist, argumentlistHelper,bloque;
non terminal Object variables_declar2,list_declar2,declaracion2,cadena_s,salir_param,variables_declar;
non terminal Object retorno,salir_if,end_func,end_type,regresar,dectype,paramHelper,parametros,end_sub;
non terminal Object rango,salir_loop,escribe,lee,subfunc ,funcion;
non terminal Object fake_f;
non terminal Objeto termino, factor, expression, nombre,funcionCall;


// COSAS QUE FALTAN AHORITA
// manejo de errores

programa ::= FIN statements | statements | FIN |;


statements ::= linea statements
|linea;


linea ::= declar_var FIN
| metodo
| dectype
| error FIN {: parser.report_error(" Se esperaba declaracion de variables, metodos o estructuras",sym.ERROR); :};


variables_declar ::= declar_var FIN;


/*----declaracion de variables----*/

declar_var ::= DIM declaracion;

declaracion ::= vars:n1 AS tipo:t SEPARADOR declaracion
{: if ( parser.first_time && !parser.in_method ){ boolean meter = parser.ambito.agregarATabla(n1,t );
if(!meter ) parser.report_error("Ya existe man, osea chill" + n1,sym.SEPARADOR);
} :}
| vars:n1 AS tipo:t
{: if (parser.first_time && !parser.in_method ){boolean meter = parser.ambito.agregarATabla(n1,t );
if(!meter) parser.report_error("Ya existe man,osea chill" + n1, sym.AS);

}:}


| error {: parser.report_error("Declaracion de variables: Se esperaba ID",sym.ERROR); :} ;

vars ::= NAME:n1 {: RESULT = n1.toLowerCase() ; :}
| NAME:n1 SEPARADOR vars:n2
{: if ( parser.first_time && !parser.in_method )
parser.ambito.agregarATabla(n1.toLowerCase(),parser.seen_types.get("variant") );
RESULT = n2.toLowerCase(); :}
| NAME SEPARADOR error {: parser.report_error("Declaracion de variables: Se esperaba nombre",sym.NAME); :};

tipo ::= TIPO:n1 {:
if( parser.first_time){
Tipo x = parser.seen_types.get(n1.toLowerCase());
RESULT = x;}
:}

| NAME:n1 {:
if(parser.first_time){
Tipo x = parser.seen_types.get(n1.toLowerCase());
if( x ==null)
{
x = new Tipo(n1.toLowerCase());
}
RESULT = x;} :};
/*--------------------------------*/

/*---Declaracion de metodos-------*/
metodo ::= subfunc
| funcion;

subfunc ::= SUB NAME:n1 argumentlist FIN end_sub FIN {: if (n1.toLowerCase().equals("main")) parser.has_main = true; :};

funcion ::= FUNCTION fake_f argumentlist retorno FIN end_func FIN {: parser.ambito = parser.ambito.parent; :}
|FUNCTION fake_f argumentlist retorno FIN error FIN {: parser.report_error("oh well",sym.ERROR); parser.ambito = parser.ambito.parent;:}
| FUNCTION error FIN {: parser.report_error("Se esperaba nombre de funcion",sym.ERROR); :}
| FUNCTION fake_f error PARIZQ retorno FIN end_func FIN {: parser.report_error("error de parametros",sym.ERROR); parser.ambito = parser.ambito.parent;:}
| FUNCTION fake_f error FIN end_func FIN {: parser.report_error("error de parametros",sym.ERROR); parser.ambito = parser.ambito.parent; :}
| FUNCTION fake_f error {: parser.report_error("Error en firma de funcion",sym.ERROR); parser.ambito = parser.ambito.parent; :};


fake_f ::= NAME:n1 {: tabla nuevo_ambito = new tabla(parser.ambito,n1); parser.ambito.hijos.add(nuevo_ambito);
parser.ambito = nuevo_ambito;
parser.tmp_tipo = new Tipo(n1);
parser.tmp_tipo.setTipoFinal(1);

:};

retorno ::= AS tipo:t1 {: parser.tmp_tipo.metodo_var.add(t1);
parser.seen_types.put( parser.tmp_tipo.getName(), parser.tmp_tipo);
:}
| error {: parser.report_error(" No existe tipo de retorno de funcion, se esperaba: As <Tipo>",sym.AS); :};


end_sub ::= bloque END SUB
| END SUB
| END error {: parser.report_error(" Se esperaba End Sub",sym.ERROR); :} ;

end_func ::= bloque END FUNCTION
| END FUNCTION
| bloque END error {: parser.report_error(" Se esperaba End Function", sym.ERROR); :} ;

end_type ::= END TYPE
| END error {: parser.report_error("Se esperaba End Type",sym.ERROR); :};

regresar ::= EXIT SUB FIN
| EXIT FUNCTION FIN
| EXIT error {: parser.report_error(" Salida de metodos: se esperaba Exit Sub o Exit Function",sym.ERROR); :};

/*--------------------------------*/


bloque ::= list_expressions
| list_expressions regresar
| list_declar list_expressions
| list_declar list_expressions regresar
| list_declar
| list_declar regresar
| regresar ;

list_declar ::= variables_declar list_declar
| variables_declar;


list_expressions ::= statement list_expressions | statement ;

statement ::= if_block | loop_for | do_loop | asignacion
|funcionCall FIN
| escribe | lee
| NAME error {: parser.report_error(" Expresion no se esperaba.",sym.ERROR); :} ;

escribe ::= WRITE cadena_s FIN
| WRITE nombre FIN
| WRITE error {: parser.report_error("Se esperaba cadena o variable",sym.WRITE);:}
| WRITELN nombre FIN
| WRITELN cadena_s FIN
| WRITELN error {: parser.report_error("Se esperaba cadena o variable",sym.WRITELN); :};

lee ::= INPUT nombre FIN
| INPUT error {: parser.report_error(" Se esperaba variable",sym.ERROR); :} ;


asignacion ::= nombre IGUAL expression FIN
| nombre IGUAL error FIN {: parser.report_error("No se puede asignar valor, error en expresion ",sym.ERROR); :};

nombre ::= NAME:n1 {: Tipo tmp = ambito.BuscarEnTabla(n1);
System.out.println(tmp.toString());
:}
| NAME PUNTO NAME
| NAME PUNTO error {: parser.report_error(" Error de <id> en asignacion ",sym.ERROR); :};


expression ::= expression MAS termino
| expression MENOS termino
| termino
| expression IGUAL termino;


termino ::= factor POR termino
| factor ENTRE termino
| factor OPREL termino
| factor;


factor ::= PARDER expression PARIZQ
| NOT factor
| NUM
| nombre
| TRUE
| FALSE
| cadena_s
| funcionCall;

cadena_s ::= CADENA SALTOCADENA FIN cadena_s
|CADENA
|CADENA SALTOCADENA error {: parser.report_error("Se esperaba nueva cadena",sym.ERROR); :};


funcionCall ::= NAME PARDER parametros ;

parametros ::= expression paramHelper
| salir_param;

paramHelper ::= SEPARADOR expression paramHelper
| salir_param;

salir_param ::= PARIZQ; // | error {: parser.report_error("Se esperaba )",sym.ERROR); :};


/*---Declaracion de argumentos ---*/



argumentlist ::= PARDER schrodingerArgument;


schrodingerArgument ::= argument argumentlistHelper
| PARIZQ
| error {: parser.report_error("error de argumentos",sym.ERROR); :};


argumentlistHelper ::= SEPARADOR argument argumentlistHelper
| PARIZQ
|error PARIZQ {: parser.report_error("error de argumentos",sym.ERROR); :};

argument ::= REF NAME:n1 AS tipo:t {: parser.ambito.agregarATabla(n1,t);
parser.tmp_tipo.metodo_var.add(t);
:}
| REF NAME AS error {: parser.report_error(" error en argumento, se esperaba un tipo de dato",sym.ERROR); :}
| REF NAME error {: parser.report_error(" error en argumento, se esperaba As <un tipo de dato>",sym.ERROR); :}

| REF error AS tipo {: parser.report_error(" error en argumento, no existe nombre de argumento",sym.NAME); :}
| error NAME AS tipo{: parser.report_error("error en argumento, no existe tipo de referencia",sym.ERROR); :};




/*---if-----*/
//Ya revisado, bexpression es lo que hay que ver

if_block ::= IF expression THEN FIN bloque if_inner
|IF expression FIN bloque if_inner
|IF expression THEN FIN if_inner
|IF expression FIN if_inner
|IF error FIN if_inner {: parser.report_error("Se esperaba expresion booleana",sym.ERROR); :}
|IF error THEN FIN if_inner {: parser.report_error("Se esperaba expresion booleana",sym.ERROR); :}
|IF error FIN bloque if_inner {: parser.report_error("Se esperaba expresion booleana",sym.ERROR); :}
|IF error THEN FIN bloque if_inner {: parser.report_error("Se esperaba expresion booleana",sym.ERROR); :};



if_inner ::= salir_if FIN
| ELSE FIN bloque salir_if FIN
| ELSE FIN salir_if FIN
| ELSE error {: parser.report_error("Error en expresion Else",sym.ERROR); :}
| ELSEIF expression FIN bloque if_inner
| ELSEIF expression THEN FIN bloque if_inner
| ELSEIF expression FIN if_inner
| ELSEIF expression THEN FIN if_inner
| ELSEIF error FIN if_inner {: parser.report_error("Se esperaba expresion booleana",sym.ERROR); :}
| ELSEIF error THEN FIN if_inner {: parser.report_error("Se esperaba expresion booleana",sym.ERROR); :}
| ELSEIF error FIN bloque if_inner {: parser.report_error("Se esperaba expresion booleana",sym.ERROR); :}
| ELSEIF error THEN FIN bloque if_inner {: parser.report_error("Se esperaba expresion booleana",sym.ERROR); :}
| ELSE FIN error salir_if FIN {: parser.report_error("Sentencia inesperada despues del Else",sym.ERROR); :}
| error salir_if{: parser.report_error("Error del bloque if, sentencia no esperada",sym.ERROR); :};

salir_if ::= END IF
| END error {:parser.report_error("Se esperaba End If",sym.ERROR); :};

/*--- do y for --*/
do_loop ::= DO WHILE expression FIN bloque salir_loop
| DO WHILE expression FIN salir_loop
| DO error expression FIN bloque salir_loop {: parser.report_error("Se esperaba While <expresion booleana> ",sym.ERROR); :}
| DO error expression FIN salir_loop {: parser.report_error("Se esperaba While <expresion booleana> ",sym.ERROR); :}
| DO WHILE error FIN salir_loop {: parser.report_error("Se esperaba expresion booleana",sym.ERROR); :}
| DO WHILE error FIN bloque salir_loop {: parser.report_error("Se esperaba expresion booleana",sym.ERROR); :};


salir_loop ::= LOOP FIN
|error {: parser.report_error("se esperaba salida de while",sym.ERROR); :};

loop_for ::= FOR rango FIN bloque NEXT FIN
| FOR rango FIN NEXT FIN
| FOR error FIN NEXT FIN {: parser.report_error("Error en rango",sym.ERROR); :}
| FOR error FIN bloque NEXT FIN {: parser.report_error("Error en rango",sym.ERROR); :}
| FOR rango FIN error {: parser.report_error("Se esperaba un Next",sym.NEXT); :}
| FOR rango FIN bloque error {: parser.report_error("Se esperaba un Next",sym.NEXT); :};

rango ::= NAME IGUAL expression TO expression
| NAME IGUAL TO error {: parser.report_error("Error de rangos, no existe valor inicial",sym.ERROR); :}
| NAME IGUAL error TO {: parser.report_error("Error de rangos, valor inicial y final",sym.ERROR); :}
| NAME IGUAL error {: parser.report_error("Error de rangos/asignacion",sym.ERROR); :}
| NAME IGUAL error TO error {: parser.report_error("Error de rangos",sym.ERROR); :}
| NAME IGUAL expression TO error {: parser.report_error("Se esperaba valor de final",sym.ERROR); :}
| NAME IGUAL error TO expression {: parser.report_error("Se esperaba valor de inicio",sym.ERROR); :}

;

/*---- estructuras ---*/



dectype ::= TYPE NAME:n1 FIN {: if(parser.first_time) {parser.tmp_tipo = new Tipo(n1); parser.tmp_tipo.setTipoFinal(3);} :} list_declar2 end_type FIN
{: if(parser.first_time) {parser.seen_types.put(n1,parser.tmp_tipo);
} :}
| TYPE NAME error end_type FIN {: parser.report_error(" estructura no puede estar vacia",sym.ERROR); :} ;


list_declar2 ::= variables_declar2 list_declar2
| variables_declar2;

variables_declar2 ::= declaracion2 FIN;

declaracion2 ::= DIM NAME:n1 AS tipo:t1 {: if(parser.first_time) parser.tmp_tipo.agregar_atributos(n1,t1); :}
| NAME:n1 AS tipo:t1 {: if( parser.first_time) parser.tmp_tipo.agregar_atributos(n1,t1); :}
| error {: parser.report_error("Se esperaba <id> As <tipo> ",sym.ERROR); :};


0 comments on commit d651ef3

Please sign in to comment.