diff --git a/practica2/Practica2 David&Jose/Leeme.txt b/practica2/Practica2 David&Jose/Leeme.txt index 1fa25cb..668eafd 100644 --- a/practica2/Practica2 David&Jose/Leeme.txt +++ b/practica2/Practica2 David&Jose/Leeme.txt @@ -1,2 +1,2 @@ Autores: Jose Luis Pariente Martinez y David Heras Pino -Código ejecutado y probado en OS X El Capitan 10.11.1 \ No newline at end of file +Código ejecutado y probado en MacOS X El Capitan 10.11.1 \ No newline at end of file diff --git a/practica2/Practica2 David&Jose/entrega/Leeme.txt b/practica2/Practica2 David&Jose/entrega/Leeme.txt new file mode 100644 index 0000000..668eafd --- /dev/null +++ b/practica2/Practica2 David&Jose/entrega/Leeme.txt @@ -0,0 +1,2 @@ +Autores: Jose Luis Pariente Martinez y David Heras Pino +Código ejecutado y probado en MacOS X El Capitan 10.11.1 \ No newline at end of file diff --git a/practica2/Practica2 David&Jose/entrega/practica2.exe b/practica2/Practica2 David&Jose/entrega/practica2.exe new file mode 100755 index 0000000..0dcb4ab Binary files /dev/null and b/practica2/Practica2 David&Jose/entrega/practica2.exe differ diff --git a/practica2/Practica2 David&Jose/entrega/practica2.l b/practica2/Practica2 David&Jose/entrega/practica2.l new file mode 100755 index 0000000..8b3da5e --- /dev/null +++ b/practica2/Practica2 David&Jose/entrega/practica2.l @@ -0,0 +1,116 @@ +%{ +#include "y.tab.h" +#include + +int nLineas=1; +%} + +entero [0-9]+ +real {entero}+[.]{entero}([eE][-+]?{entero})? +iden [a-zA-Z][a-zA-Z0-9]* +cadena \"(\\.|[^\\"])*\" +operador [+\-*/&|!<>%] +cdc1 \"%d\" +cdc2 \"%f\" +cdc3 \"%c\" +input [^\r\n] +eol (\n|\r|\r\n) +coment ("//"{input}*{eol}?) + +%% + +{entero} { + return NUM_ENTERO; + } + +{real} { + return NUM_REAL; + } + +{cdc1} { + yylval.tipo = 1; + return CDC; + } +{cdc2} { + yylval.tipo = 2; + return CDC; + } +{cdc3} { + yylval.tipo = 3; + return CDC; + } + +{cadena} { + return CADENA; + } + +[ \t] ; + +"define" { + return DEFINE; + } + +"int" { + return INT; + } + +"float" { + return FLOAT; + } + +"char" { + return CHAR; + } + +"int main()" { + return MAIN; + } + +"printf" { + return PRINTF; + } + +"scanf" { + return SCANF; + } + +"if" { + return IF; + } + +"else" { + return ELSE; + } + +"while" { + return WHILE; + } + +"for" { + return FOR; + } + +{iden} { + strcpy(yylval.nombreId, yytext); + return ID; + } + +{operador}|"&&"|"||"|"=="|"<="|">="|"!=" { + return OPERADOR; + } +"++"|"--" { + return OPERADOR2; + } +{coment} { nLineas++; } + +\n { nLineas++; } + +. { + return yytext[0]; + } + +%% + +int yywrap(){ + return 1; +} diff --git a/practica2/Practica2 David&Jose/entrega/practica2.y b/practica2/Practica2 David&Jose/entrega/practica2.y new file mode 100755 index 0000000..777c8e7 --- /dev/null +++ b/practica2/Practica2 David&Jose/entrega/practica2.y @@ -0,0 +1,262 @@ +%{ + +#include +#include +#include +#include + +void yyerror(const char* msg) { + fprintf(stderr, "%s\n", msg); +} +int yylex(void); +FILE *yyin; + +int num_sim = 0; +extern int nLineas; + +struct simbolo{ + char nombre[30]; + int tipo; + int cte; + int inicializado; +}; +struct simbolo tablaSimbolos[50]; +int dim = 0; + +int buscarSimbolo(struct simbolo tablaSimbolos[],char nombre[30],int dim); + +int errores = 0; + +%} + +%union { + int tipo; // 1.int 2.float 3.char + char nombreId[30]; + } + +%token ID +%token DEFINE +%token NUM_ENTERO +%token NUM_REAL +%token CADENA +%token INT +%token FLOAT +%token CHAR +%token MAIN +%token OPERADOR +%token OPERADOR2 +%token PRINTF +%token IF +%token FOR +%token ELSE +%token SCANF +%token WHILE +%token CDC +%type tipo valor_cte val expr +%type id + +%% +programa: declaracionesCtes main {if (errores > 0) { + printf("\n Programa compilado con %d errores en %d lineas\n",errores,nLineas); + }else{ + printf("\n Programa compilado sin errores y con %d lineas\n", nLineas); + } + } + + ; +declaracionesCtes: /*vacia*/ + | declaracionCte declaracionesCtes + ; +declaracionCte: '#' DEFINE ID valor_cte { + int pos = buscarSimbolo(tablaSimbolos, $3, dim); + if (pos != dim){ + printf("\n ERROR lin %d: Constante redeclarado",nLineas); + errores++; + } + else { + //lo añado + tablaSimbolos[dim].tipo = $4; + tablaSimbolos[dim].cte = 1; + tablaSimbolos[dim].inicializado = 1; + strcpy(tablaSimbolos[dim].nombre,$3); + dim++; + } + } + ; +valor_cte: NUM_ENTERO { $$ = 1; } + | NUM_REAL { $$ = 2; } + | CADENA { $$ = 3; } + ; +declaracionVbles: /*vacia*/ + | declaracionVble declaracionVbles + ; +declaracionVble: tipo id ';' { + int pos = buscarSimbolo(tablaSimbolos, $2, dim); + if (pos != dim){ + printf("\n ERROR lin %d: Identificador redeclarado",nLineas); + errores++; + } + else { + //lo añado + tablaSimbolos[dim].tipo = $1; + tablaSimbolos[dim].cte = 0; + tablaSimbolos[dim].inicializado = 0; + strcpy(tablaSimbolos[dim].nombre,$2); + dim++; + } + } + | tipo id '=' expr ';' { + int pos = buscarSimbolo(tablaSimbolos, $2, dim); + if (pos != dim){ + printf("\n ERROR lin %d: Identificador redeclarado",nLineas); + errores++; + } + else { + if ($1 != $4){ + printf("\n ERROR lin %d: No coinciden los tipos", nLineas); + errores++; + }else if ($4 != 4){ //el tipo 4 es indicador de que no existe la variable + //lo añado + tablaSimbolos[dim].tipo = $1; + tablaSimbolos[dim].cte = 0; + tablaSimbolos[dim].inicializado = 1; + strcpy(tablaSimbolos[dim].nombre,$2); + dim++; + } + } + } + ; +tipo: INT { $$ = 1; } + | FLOAT { $$ = 2; } + | CHAR { $$ = 3; } + ; +id: ID { strcpy($$, $1); } + ; +expr: val { $$ = $1; } + | val OPERADOR expr { if ($1 < $3) + { + $$ = $3; + }else{ + $$ = $1; + } + } + ; +val: ID { int pos = buscarSimbolo(tablaSimbolos, $1, dim); + int tipo = tablaSimbolos[pos].tipo; + if (tipo == 0){ + printf("\n ERROR lin %d: Variable %s no declarada", nLineas, $1); + errores++; + tipo = 4; + } + if (tablaSimbolos[pos].inicializado == 0){ + printf("\n ERROR lin %d: Variable %s no inicializada", nLineas, $1); + errores++; + tipo = 4; + } + $$ = tipo; + } + | valor_cte { $$ = $1; } + ; +main: MAIN '{' cuerpo '}' + ; +cuerpo: declaracionVbles instrucciones + ; +instrucciones: /*vacía*/ + | instruccion instrucciones + ; +instruccion: asig ';' + | visu ';' + | lect ';' + | cond + | repe + ; +asig: ID '=' expr { int pos = buscarSimbolo(tablaSimbolos, $1, dim); + int tipo = tablaSimbolos[pos].tipo; + if (tipo == 0){ + printf("\n ERROR lin %d: Variable %s no declarada", nLineas, $1); + errores++; + } + if (tablaSimbolos[pos].cte == 1){ + printf("\n ERROR lin %d: No se puede modificar el valor de una constante", nLineas); + errores++; + } + if ((tipo == 1 && $3 == 2) || (tipo == 3 && $3 == 2)){ //Problemas con entero = float y char = float + printf("\n ERROR lin %d: No coinciden los tipos", nLineas); + errores++; + } + + } + | ID OPERADOR2 + ; +visu: PRINTF '(' listExpr ')' + ; +listExpr: /*vacia*/ + | expr + | expr ',' listExpr + ; +lect: SCANF '(' CDC ',' OPERADOR ID ')' { int pos = buscarSimbolo(tablaSimbolos, $6, dim); + int tipo = tablaSimbolos[pos].tipo; + if (tipo == 0){ + printf("\n ERROR lin %d: Variable %s no declarada", nLineas, $6); + errores++; + } + if ($3 != tipo && tipo != 0){ + printf("\n ERROR lin %d: Tipos incompatibles en scanf", nLineas); + errores++; + } + } + ; +cond: bloqueIF + | bloqueIF else + ; +bloqueIF: IF '(' expr ')' '{' instrucciones '}' + ; +else: ELSE '{' instrucciones '}' + | ELSE cond + ; +repe: for + | while + ; +for: FOR '(' inicia ';' expFOR ';' increm ')' '{' instrucciones '}' + ; +inicia: /*vacia*/ + | asig + ; +expFOR: /*vacia*/ + | expr + ; +increm: /*vacia*/ + | ID OPERADOR2 { int pos = buscarSimbolo(tablaSimbolos, $1, dim); + int tipo = tablaSimbolos[pos].tipo; + if (tipo == 0){ + printf("\n ERROR lin %d: Variable %s no declarada", nLineas, $1); + errores++; + } + else if (tablaSimbolos[pos].inicializado == 0){ + printf("\n ERROR lin %d: Variable %s no inicializada", nLineas, $1); + errores++; + } + } + ; +while: WHILE '(' expr ')' '{' instrucciones '}' + ; + + +%% + +int main() +{ + yyin=fopen("practica2conErrores.c","r"); + yyparse(); + +} + +int buscarSimbolo(struct simbolo tablaSimbolos[],char nombre[50],int dim){ + for (int i=0;i int nLineas=1; -#line 516 "lex.yy.c" +#line 524 "lex.yy.c" #define INITIAL 0 @@ -694,10 +702,10 @@ YY_DECL register char *yy_cp, *yy_bp; register int yy_act; -#line 18 "practica2.l" +#line 20 "practica2.l" -#line 701 "lex.yy.c" +#line 709 "lex.yy.c" if ( !(yy_init) ) { @@ -750,13 +758,13 @@ YY_DECL while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 88 ) + if ( yy_current_state >= 92 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 127 ); + while ( yy_base[yy_current_state] != 131 ); yy_find_action: yy_act = yy_accept[yy_current_state]; @@ -782,163 +790,179 @@ YY_DECL case 1: YY_RULE_SETUP -#line 20 "practica2.l" -{ printf("\n %d NUM_ENTERO",nLineas); +#line 22 "practica2.l" +{ return NUM_ENTERO; } YY_BREAK case 2: YY_RULE_SETUP -#line 24 "practica2.l" -{ printf("\n %d NUM_REAL",nLineas); +#line 26 "practica2.l" +{ return NUM_REAL; } YY_BREAK case 3: YY_RULE_SETUP -#line 28 "practica2.l" -{ printf("\n %d CDC",nLineas); - return CDC; - } +#line 30 "practica2.l" +{ + yylval.tipo = 1; + return CDC; + } YY_BREAK case 4: -/* rule 4 can match eol */ YY_RULE_SETUP -#line 32 "practica2.l" -{ printf("\n %d CADENA",nLineas); +#line 34 "practica2.l" +{ + yylval.tipo = 2; + return CDC; + } + YY_BREAK +case 5: +YY_RULE_SETUP +#line 38 "practica2.l" +{ + yylval.tipo = 3; + return CDC; + } + YY_BREAK +case 6: +/* rule 6 can match eol */ +YY_RULE_SETUP +#line 43 "practica2.l" +{ return CADENA; } YY_BREAK -case 5: +case 7: YY_RULE_SETUP -#line 36 "practica2.l" +#line 47 "practica2.l" ; YY_BREAK -case 6: +case 8: YY_RULE_SETUP -#line 38 "practica2.l" -{ printf("\n %d DEFINE",nLineas); +#line 49 "practica2.l" +{ return DEFINE; } YY_BREAK -case 7: +case 9: YY_RULE_SETUP -#line 42 "practica2.l" -{ printf("\n %d INT",nLineas); +#line 53 "practica2.l" +{ return INT; } YY_BREAK -case 8: +case 10: YY_RULE_SETUP -#line 46 "practica2.l" -{ printf("\n %d FLOAT",nLineas); +#line 57 "practica2.l" +{ return FLOAT; } YY_BREAK -case 9: +case 11: YY_RULE_SETUP -#line 50 "practica2.l" -{ printf("\n %d CHAR",nLineas); +#line 61 "practica2.l" +{ return CHAR; } YY_BREAK -case 10: +case 12: YY_RULE_SETUP -#line 54 "practica2.l" -{ printf("\n %d MAIN",nLineas); +#line 65 "practica2.l" +{ return MAIN; } YY_BREAK -case 11: +case 13: YY_RULE_SETUP -#line 58 "practica2.l" -{ printf("\n %d PRINTF",nLineas); +#line 69 "practica2.l" +{ return PRINTF; } YY_BREAK -case 12: +case 14: YY_RULE_SETUP -#line 62 "practica2.l" -{ printf("\n %d SCANF",nLineas); +#line 73 "practica2.l" +{ return SCANF; } YY_BREAK -case 13: +case 15: YY_RULE_SETUP -#line 66 "practica2.l" -{ printf("\n %d IF",nLineas); +#line 77 "practica2.l" +{ return IF; } YY_BREAK -case 14: +case 16: YY_RULE_SETUP -#line 70 "practica2.l" -{ printf("\n %d ELSE",nLineas); +#line 81 "practica2.l" +{ return ELSE; } YY_BREAK -case 15: +case 17: YY_RULE_SETUP -#line 74 "practica2.l" -{ printf("\n %d WHILE",nLineas); +#line 85 "practica2.l" +{ return WHILE; } YY_BREAK -case 16: +case 18: YY_RULE_SETUP -#line 78 "practica2.l" -{ printf("\n %d FOR",nLineas); +#line 89 "practica2.l" +{ return FOR; } YY_BREAK -case 17: +case 19: YY_RULE_SETUP -#line 82 "practica2.l" -{ printf("\n %d ID",nLineas); +#line 93 "practica2.l" +{ + strcpy(yylval.nombreId, yytext); return ID; } YY_BREAK -case 18: +case 20: YY_RULE_SETUP -#line 86 "practica2.l" -{ printf("\n %d OPERADOR",nLineas); +#line 98 "practica2.l" +{ return OPERADOR; } YY_BREAK -case 19: +case 21: YY_RULE_SETUP -#line 89 "practica2.l" -{ printf("\n %d OPERADOR2",nLineas); +#line 101 "practica2.l" +{ return OPERADOR2; } YY_BREAK -case 20: -/* rule 20 can match eol */ +case 22: +/* rule 22 can match eol */ YY_RULE_SETUP -#line 92 "practica2.l" -{ printf("\n %d COMENTARIO",nLineas); - - } +#line 104 "practica2.l" +{ nLineas++; } YY_BREAK -case 21: -/* rule 21 can match eol */ +case 23: +/* rule 23 can match eol */ YY_RULE_SETUP -#line 96 "practica2.l" +#line 106 "practica2.l" { nLineas++; } YY_BREAK -case 22: +case 24: YY_RULE_SETUP -#line 98 "practica2.l" -{ printf("\n %d %c",nLineas, yytext[0]); +#line 108 "practica2.l" +{ return yytext[0]; } YY_BREAK -case 23: +case 25: YY_RULE_SETUP -#line 102 "practica2.l" +#line 112 "practica2.l" ECHO; YY_BREAK -#line 942 "lex.yy.c" +#line 966 "lex.yy.c" case YY_STATE_EOF(INITIAL): yyterminate(); @@ -1230,7 +1254,7 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 88 ) + if ( yy_current_state >= 92 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -1258,11 +1282,11 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 88 ) + if ( yy_current_state >= 92 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 87); + yy_is_jam = (yy_current_state == 91); return yy_is_jam ? 0 : yy_current_state; } @@ -1935,7 +1959,7 @@ void yyfree (void * ptr ) #define YYTABLES_NAME "yytables" -#line 102 "practica2.l" +#line 112 "practica2.l" diff --git a/practica2/Practica2 David&Jose/practica2.c b/practica2/Practica2 David&Jose/practica2.c deleted file mode 100755 index 52554f8..0000000 --- a/practica2/Practica2 David&Jose/practica2.c +++ /dev/null @@ -1,51 +0,0 @@ -#define PI 3.1416 -#define NUMERO 15 -#define SALUDO "Hola" - -float c,d = 5.3 + 2.4; -int a,b; - -int main(){ - int g; - h = a; - g = a+5; - z = 5 && f; - printf("a a df",a,b,a+b); - scanf("%d",&a); - if(a==4){ - a++; - } - - if(b<9){ - b=5; - }else if (b>9){ - b = a-5; - } - - if(b<9){ - b=5; - }else { - b = a-5; - } - - for (a=1;a>6;a++){ - printf("y eso"); - } - - for (;a>6;){ - printf("y eso"); - } - - while(1){ - a++; - } - - //Practica realizada por - //David Heras Pino - //Jose L Pariente Martinez - //Copyright 2016 © - - - - -} diff --git a/practica2/Practica2 David&Jose/practica2.exe b/practica2/Practica2 David&Jose/practica2.exe index 6eb4a7e..0dcb4ab 100755 Binary files a/practica2/Practica2 David&Jose/practica2.exe and b/practica2/Practica2 David&Jose/practica2.exe differ diff --git a/practica2/Practica2 David&Jose/practica2.h b/practica2/Practica2 David&Jose/practica2.h new file mode 100644 index 0000000..6179184 --- /dev/null +++ b/practica2/Practica2 David&Jose/practica2.h @@ -0,0 +1,9 @@ +#define MAX_SIM 30 /*numero maximo de simbolos para la tabla*/ + +struct simbolo { + char id[20]; // nombre del id + int tipo; // 1.int 2.float 3.char + int inic; // 0 no 1 si +}tabla_simbolos[MAX_SIM]; + +struct simbolo *buscar_simbolo(); diff --git a/practica2/Practica2 David&Jose/practica2.l b/practica2/Practica2 David&Jose/practica2.l index e3a2b4d..8b3da5e 100755 --- a/practica2/Practica2 David&Jose/practica2.l +++ b/practica2/Practica2 David&Jose/practica2.l @@ -10,92 +10,102 @@ real {entero}+[.]{entero}([eE][-+]?{entero})? iden [a-zA-Z][a-zA-Z0-9]* cadena \"(\\.|[^\\"])*\" operador [+\-*/&|!<>%] -cdc \"(%d|%f|%c)\" +cdc1 \"%d\" +cdc2 \"%f\" +cdc3 \"%c\" input [^\r\n] eol (\n|\r|\r\n) coment ("//"{input}*{eol}?) %% -{entero} { printf("\n %d NUM_ENTERO",nLineas); +{entero} { return NUM_ENTERO; } -{real} { printf("\n %d NUM_REAL",nLineas); +{real} { return NUM_REAL; } -{cdc} { printf("\n %d CDC",nLineas); - return CDC; - } - -{cadena} { printf("\n %d CADENA",nLineas); +{cdc1} { + yylval.tipo = 1; + return CDC; + } +{cdc2} { + yylval.tipo = 2; + return CDC; + } +{cdc3} { + yylval.tipo = 3; + return CDC; + } + +{cadena} { return CADENA; } [ \t] ; -"define" { printf("\n %d DEFINE",nLineas); +"define" { return DEFINE; } -"int" { printf("\n %d INT",nLineas); +"int" { return INT; } -"float" { printf("\n %d FLOAT",nLineas); +"float" { return FLOAT; } -"char" { printf("\n %d CHAR",nLineas); +"char" { return CHAR; } -"int main()" { printf("\n %d MAIN",nLineas); +"int main()" { return MAIN; } -"printf" { printf("\n %d PRINTF",nLineas); +"printf" { return PRINTF; } -"scanf" { printf("\n %d SCANF",nLineas); +"scanf" { return SCANF; } -"if" { printf("\n %d IF",nLineas); +"if" { return IF; } -"else" { printf("\n %d ELSE",nLineas); +"else" { return ELSE; } -"while" { printf("\n %d WHILE",nLineas); +"while" { return WHILE; } -"for" { printf("\n %d FOR",nLineas); +"for" { return FOR; } -{iden} { printf("\n %d ID",nLineas); +{iden} { + strcpy(yylval.nombreId, yytext); return ID; } -{operador}|"&&"|"||"|"=="|"<="|">="|"!=" { printf("\n %d OPERADOR",nLineas); +{operador}|"&&"|"||"|"=="|"<="|">="|"!=" { return OPERADOR; } -"++"|"--" { printf("\n %d OPERADOR2",nLineas); +"++"|"--" { return OPERADOR2; } -{coment} { printf("\n %d COMENTARIO",nLineas); - - } +{coment} { nLineas++; } \n { nLineas++; } -. { printf("\n %d %c",nLineas, yytext[0]); +. { return yytext[0]; } diff --git a/practica2/Practica2 David&Jose/practica2.y b/practica2/Practica2 David&Jose/practica2.y index 19ea69f..777c8e7 100755 --- a/practica2/Practica2 David&Jose/practica2.y +++ b/practica2/Practica2 David&Jose/practica2.y @@ -6,15 +6,35 @@ #include void yyerror(const char* msg) { - fprintf(stderr, "%s\n", msg); + fprintf(stderr, "%s\n", msg); } int yylex(void); FILE *yyin; +int num_sim = 0; extern int nLineas; +struct simbolo{ + char nombre[30]; + int tipo; + int cte; + int inicializado; +}; +struct simbolo tablaSimbolos[50]; +int dim = 0; + +int buscarSimbolo(struct simbolo tablaSimbolos[],char nombre[30],int dim); + +int errores = 0; + %} -%token ID + +%union { + int tipo; // 1.int 2.float 3.char + char nombreId[30]; + } + +%token ID %token DEFINE %token NUM_ENTERO %token NUM_REAL @@ -31,99 +51,212 @@ extern int nLineas; %token ELSE %token SCANF %token WHILE -%token CDC - +%token CDC +%type tipo valor_cte val expr +%type id %% -programa: declaracionesCtes declaracionVbles main {printf("\n Todo correcto numero de lineas %d\n",nLineas);} - ; +programa: declaracionesCtes main {if (errores > 0) { + printf("\n Programa compilado con %d errores en %d lineas\n",errores,nLineas); + }else{ + printf("\n Programa compilado sin errores y con %d lineas\n", nLineas); + } + } + + ; declaracionesCtes: /*vacia*/ - | declaracionCte declaracionesCtes - ; -declaracionCte: '#' DEFINE ID valor_cte {printf("\nDeclaracion cte");} - ; -valor_cte: NUM_ENTERO - | NUM_REAL - | CADENA - ; + | declaracionCte declaracionesCtes + ; +declaracionCte: '#' DEFINE ID valor_cte { + int pos = buscarSimbolo(tablaSimbolos, $3, dim); + if (pos != dim){ + printf("\n ERROR lin %d: Constante redeclarado",nLineas); + errores++; + } + else { + //lo añado + tablaSimbolos[dim].tipo = $4; + tablaSimbolos[dim].cte = 1; + tablaSimbolos[dim].inicializado = 1; + strcpy(tablaSimbolos[dim].nombre,$3); + dim++; + } + } + ; +valor_cte: NUM_ENTERO { $$ = 1; } + | NUM_REAL { $$ = 2; } + | CADENA { $$ = 3; } + ; declaracionVbles: /*vacia*/ - | declaracionVble declaracionVbles - ; -declaracionVble: tipo listID ';' {printf("\nDeclaracion vble");} - ; -tipo: INT - | FLOAT - | CHAR - ; -listID: id - | id ',' listID - ; -id: ID - | asig - ; + | declaracionVble declaracionVbles + ; +declaracionVble: tipo id ';' { + int pos = buscarSimbolo(tablaSimbolos, $2, dim); + if (pos != dim){ + printf("\n ERROR lin %d: Identificador redeclarado",nLineas); + errores++; + } + else { + //lo añado + tablaSimbolos[dim].tipo = $1; + tablaSimbolos[dim].cte = 0; + tablaSimbolos[dim].inicializado = 0; + strcpy(tablaSimbolos[dim].nombre,$2); + dim++; + } + } + | tipo id '=' expr ';' { + int pos = buscarSimbolo(tablaSimbolos, $2, dim); + if (pos != dim){ + printf("\n ERROR lin %d: Identificador redeclarado",nLineas); + errores++; + } + else { + if ($1 != $4){ + printf("\n ERROR lin %d: No coinciden los tipos", nLineas); + errores++; + }else if ($4 != 4){ //el tipo 4 es indicador de que no existe la variable + //lo añado + tablaSimbolos[dim].tipo = $1; + tablaSimbolos[dim].cte = 0; + tablaSimbolos[dim].inicializado = 1; + strcpy(tablaSimbolos[dim].nombre,$2); + dim++; + } + } + } + ; +tipo: INT { $$ = 1; } + | FLOAT { $$ = 2; } + | CHAR { $$ = 3; } + ; +id: ID { strcpy($$, $1); } + ; +expr: val { $$ = $1; } + | val OPERADOR expr { if ($1 < $3) + { + $$ = $3; + }else{ + $$ = $1; + } + } + ; +val: ID { int pos = buscarSimbolo(tablaSimbolos, $1, dim); + int tipo = tablaSimbolos[pos].tipo; + if (tipo == 0){ + printf("\n ERROR lin %d: Variable %s no declarada", nLineas, $1); + errores++; + tipo = 4; + } + if (tablaSimbolos[pos].inicializado == 0){ + printf("\n ERROR lin %d: Variable %s no inicializada", nLineas, $1); + errores++; + tipo = 4; + } + $$ = tipo; + } + | valor_cte { $$ = $1; } + ; main: MAIN '{' cuerpo '}' - ; -cuerpo: declaracionVbles instrucciones - ; -instrucciones: instruccion - | instruccion instrucciones - ; -instruccion: asig ';' {printf("\nAsignacion");} - | visu ';' {printf("\nVisualizacion");} - | lect ';' {printf("\nLectura");} - | cond {printf("\nCondicion");} - | repe - ; -asig: ID '=' expr - | ID OPERADOR2 - ; -expr: val - | val OPERADOR expr - ; -val: ID - | valor_cte - ; + ; +cuerpo: declaracionVbles instrucciones + ; +instrucciones: /*vacía*/ + | instruccion instrucciones + ; +instruccion: asig ';' + | visu ';' + | lect ';' + | cond + | repe + ; +asig: ID '=' expr { int pos = buscarSimbolo(tablaSimbolos, $1, dim); + int tipo = tablaSimbolos[pos].tipo; + if (tipo == 0){ + printf("\n ERROR lin %d: Variable %s no declarada", nLineas, $1); + errores++; + } + if (tablaSimbolos[pos].cte == 1){ + printf("\n ERROR lin %d: No se puede modificar el valor de una constante", nLineas); + errores++; + } + if ((tipo == 1 && $3 == 2) || (tipo == 3 && $3 == 2)){ //Problemas con entero = float y char = float + printf("\n ERROR lin %d: No coinciden los tipos", nLineas); + errores++; + } + + } + | ID OPERADOR2 + ; visu: PRINTF '(' listExpr ')' - ; + ; listExpr: /*vacia*/ - | expr - | expr ',' listExpr - ; -lect: SCANF '(' CDC ',' OPERADOR ID ')' - ; -cond: bloqueIF {printf("\nBloque IF");} - | bloqueIF else {printf("\nBloque IF+ELSE");} - ; + | expr + | expr ',' listExpr + ; +lect: SCANF '(' CDC ',' OPERADOR ID ')' { int pos = buscarSimbolo(tablaSimbolos, $6, dim); + int tipo = tablaSimbolos[pos].tipo; + if (tipo == 0){ + printf("\n ERROR lin %d: Variable %s no declarada", nLineas, $6); + errores++; + } + if ($3 != tipo && tipo != 0){ + printf("\n ERROR lin %d: Tipos incompatibles en scanf", nLineas); + errores++; + } + } + ; +cond: bloqueIF + | bloqueIF else + ; bloqueIF: IF '(' expr ')' '{' instrucciones '}' - ; + ; else: ELSE '{' instrucciones '}' - | ELSE cond - ; -repe: for {printf("\nRepeticion: bloque FOR");} - | while {printf("\nRepeticion: bloque WHILE");} - ; + | ELSE cond + ; +repe: for + | while + ; for: FOR '(' inicia ';' expFOR ';' increm ')' '{' instrucciones '}' - ; + ; inicia: /*vacia*/ - | asig - ; + | asig + ; expFOR: /*vacia*/ - | expr - ; + | expr + ; increm: /*vacia*/ - | ID OPERADOR2 - ; + | ID OPERADOR2 { int pos = buscarSimbolo(tablaSimbolos, $1, dim); + int tipo = tablaSimbolos[pos].tipo; + if (tipo == 0){ + printf("\n ERROR lin %d: Variable %s no declarada", nLineas, $1); + errores++; + } + else if (tablaSimbolos[pos].inicializado == 0){ + printf("\n ERROR lin %d: Variable %s no inicializada", nLineas, $1); + errores++; + } + } + ; while: WHILE '(' expr ')' '{' instrucciones '}' - ; + ; %% int main() { - yyin=fopen("practica2.c","r"); - yyparse(); + yyin=fopen("practica2conErrores.c","r"); + yyparse(); } +int buscarSimbolo(struct simbolo tablaSimbolos[],char nombre[50],int dim){ + for (int i=0;i void yyerror(const char* msg) { - fprintf(stderr, "%s\n", msg); + fprintf(stderr, "%s\n", msg); } int yylex(void); FILE *yyin; +int num_sim = 0; extern int nLineas; +struct simbolo{ + char nombre[30]; + int tipo; + int cte; + int inicializado; +}; +struct simbolo tablaSimbolos[50]; +int dim = 0; + +int buscarSimbolo(struct simbolo tablaSimbolos[],char nombre[30],int dim); + +int errores = 0; + /* Enabling traces. */ @@ -147,7 +161,15 @@ extern int nLineas; #endif #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef int YYSTYPE; +typedef union YYSTYPE +#line 32 "practica2.y" +{ + int tipo; // 1.int 2.float 3.char + char nombreId[30]; + } +/* Line 193 of yacc.c. */ +#line 172 "y.tab.c" + YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 @@ -159,7 +181,7 @@ typedef int YYSTYPE; /* Line 216 of yacc.c. */ -#line 163 "y.tab.c" +#line 185 "y.tab.c" #ifdef short # undef short @@ -374,16 +396,16 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 6 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 82 +#define YYLAST 100 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 29 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 29 +#define YYNNTS 28 /* YYNRULES -- Number of rules. */ -#define YYNRULES 53 +#define YYNRULES 51 /* YYNRULES -- Number of states. */ -#define YYNSTATES 105 +#define YYNSTATES 103 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 @@ -399,9 +421,9 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 21, 2, 2, 2, 2, - 27, 28, 2, 2, 23, 2, 2, 2, 2, 2, + 26, 27, 2, 2, 28, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 22, - 2, 26, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 23, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -430,45 +452,44 @@ static const yytype_uint8 yytranslate[] = YYRHS. */ static const yytype_uint8 yyprhs[] = { - 0, 0, 3, 7, 8, 11, 16, 18, 20, 22, - 23, 26, 30, 32, 34, 36, 38, 42, 44, 46, - 51, 54, 56, 59, 62, 65, 68, 70, 72, 76, - 79, 81, 85, 87, 89, 94, 95, 97, 101, 109, - 111, 114, 122, 127, 130, 132, 134, 146, 147, 149, - 150, 152, 153, 156 + 0, 0, 3, 6, 7, 10, 15, 17, 19, 21, + 22, 25, 29, 35, 37, 39, 41, 43, 45, 49, + 51, 53, 58, 61, 62, 65, 68, 71, 74, 76, + 78, 82, 85, 90, 91, 93, 97, 105, 107, 110, + 118, 123, 126, 128, 130, 142, 143, 145, 146, 148, + 149, 152 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { - 30, 0, -1, 31, 34, 39, -1, -1, 32, 31, - -1, 21, 4, 3, 33, -1, 5, -1, 6, -1, - 7, -1, -1, 35, 34, -1, 36, 37, 22, -1, - 8, -1, 9, -1, 10, -1, 38, -1, 38, 23, - 37, -1, 3, -1, 43, -1, 11, 24, 40, 25, - -1, 34, 41, -1, 42, -1, 42, 41, -1, 43, - 22, -1, 46, 22, -1, 48, 22, -1, 49, -1, - 52, -1, 3, 26, 44, -1, 3, 13, -1, 45, - -1, 45, 12, 44, -1, 3, -1, 33, -1, 14, - 27, 47, 28, -1, -1, 44, -1, 44, 23, 47, - -1, 18, 27, 20, 23, 12, 3, 28, -1, 50, - -1, 50, 51, -1, 15, 27, 44, 28, 24, 41, - 25, -1, 17, 24, 41, 25, -1, 17, 49, -1, - 53, -1, 57, -1, 16, 27, 54, 22, 55, 22, - 56, 28, 24, 41, 25, -1, -1, 43, -1, -1, - 44, -1, -1, 3, 13, -1, 19, 27, 44, 28, - 24, 41, 25, -1 + 30, 0, -1, 31, 40, -1, -1, 32, 31, -1, + 21, 4, 3, 33, -1, 5, -1, 6, -1, 7, + -1, -1, 35, 34, -1, 36, 37, 22, -1, 36, + 37, 23, 38, 22, -1, 8, -1, 9, -1, 10, + -1, 3, -1, 39, -1, 39, 12, 38, -1, 3, + -1, 33, -1, 11, 24, 41, 25, -1, 34, 42, + -1, -1, 43, 42, -1, 44, 22, -1, 45, 22, + -1, 47, 22, -1, 48, -1, 51, -1, 3, 23, + 38, -1, 3, 13, -1, 14, 26, 46, 27, -1, + -1, 38, -1, 38, 28, 46, -1, 18, 26, 20, + 28, 12, 3, 27, -1, 49, -1, 49, 50, -1, + 15, 26, 38, 27, 24, 42, 25, -1, 17, 24, + 42, 25, -1, 17, 48, -1, 52, -1, 56, -1, + 16, 26, 53, 22, 54, 22, 55, 27, 24, 42, + 25, -1, -1, 44, -1, -1, 38, -1, -1, 3, + 13, -1, 19, 26, 38, 27, 24, 42, 25, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { - 0, 38, 38, 40, 41, 43, 45, 46, 47, 49, - 50, 52, 54, 55, 56, 58, 59, 61, 62, 64, - 66, 68, 69, 71, 72, 73, 74, 75, 77, 78, - 80, 81, 83, 84, 86, 88, 89, 90, 92, 94, - 95, 97, 99, 100, 102, 103, 105, 107, 108, 110, - 111, 113, 114, 116 + 0, 59, 59, 67, 68, 70, 86, 87, 88, 90, + 91, 93, 108, 129, 130, 131, 133, 135, 136, 144, + 158, 160, 162, 164, 165, 167, 168, 169, 170, 171, + 173, 189, 191, 193, 194, 195, 197, 209, 210, 212, + 214, 215, 217, 218, 220, 222, 223, 225, 226, 228, + 229, 241 }; #endif @@ -480,12 +501,12 @@ static const char *const yytname[] = "$end", "error", "$undefined", "ID", "DEFINE", "NUM_ENTERO", "NUM_REAL", "CADENA", "INT", "FLOAT", "CHAR", "MAIN", "OPERADOR", "OPERADOR2", "PRINTF", "IF", "FOR", "ELSE", "SCANF", "WHILE", "CDC", "'#'", "';'", - "','", "'{'", "'}'", "'='", "'('", "')'", "$accept", "programa", + "'='", "'{'", "'}'", "'('", "')'", "','", "$accept", "programa", "declaracionesCtes", "declaracionCte", "valor_cte", "declaracionVbles", - "declaracionVble", "tipo", "listID", "id", "main", "cuerpo", - "instrucciones", "instruccion", "asig", "expr", "val", "visu", - "listExpr", "lect", "cond", "bloqueIF", "else", "repe", "for", "inicia", - "expFOR", "increm", "while", 0 + "declaracionVble", "tipo", "id", "expr", "val", "main", "cuerpo", + "instrucciones", "instruccion", "asig", "visu", "listExpr", "lect", + "cond", "bloqueIF", "else", "repe", "for", "inicia", "expFOR", "increm", + "while", 0 }; #endif @@ -496,7 +517,7 @@ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 35, 59, 44, 123, 125, 61, 40, 41 + 275, 35, 59, 61, 123, 125, 40, 41, 44 }; # endif @@ -504,22 +525,22 @@ static const yytype_uint16 yytoknum[] = static const yytype_uint8 yyr1[] = { 0, 29, 30, 31, 31, 32, 33, 33, 33, 34, - 34, 35, 36, 36, 36, 37, 37, 38, 38, 39, - 40, 41, 41, 42, 42, 42, 42, 42, 43, 43, - 44, 44, 45, 45, 46, 47, 47, 47, 48, 49, - 49, 50, 51, 51, 52, 52, 53, 54, 54, 55, - 55, 56, 56, 57 + 34, 35, 35, 36, 36, 36, 37, 38, 38, 39, + 39, 40, 41, 42, 42, 43, 43, 43, 43, 43, + 44, 44, 45, 46, 46, 46, 47, 48, 48, 49, + 50, 50, 51, 51, 52, 53, 53, 54, 54, 55, + 55, 56 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { - 0, 2, 3, 0, 2, 4, 1, 1, 1, 0, - 2, 3, 1, 1, 1, 1, 3, 1, 1, 4, - 2, 1, 2, 2, 2, 2, 1, 1, 3, 2, - 1, 3, 1, 1, 4, 0, 1, 3, 7, 1, - 2, 7, 4, 2, 1, 1, 11, 0, 1, 0, - 1, 0, 2, 7 + 0, 2, 2, 0, 2, 4, 1, 1, 1, 0, + 2, 3, 5, 1, 1, 1, 1, 1, 3, 1, + 1, 4, 2, 0, 2, 2, 2, 2, 1, 1, + 3, 2, 4, 0, 1, 3, 7, 1, 2, 7, + 4, 2, 1, 1, 11, 0, 1, 0, 1, 0, + 2, 7 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state @@ -527,51 +548,51 @@ static const yytype_uint8 yyr2[] = means the default is an error. */ static const yytype_uint8 yydefact[] = { - 3, 0, 0, 9, 3, 0, 1, 12, 13, 14, - 0, 9, 0, 4, 0, 0, 2, 10, 17, 0, - 15, 18, 6, 7, 8, 5, 9, 29, 0, 11, - 0, 0, 0, 32, 33, 28, 30, 16, 0, 0, - 0, 0, 0, 0, 20, 21, 0, 0, 0, 26, - 39, 27, 44, 45, 19, 0, 35, 0, 47, 0, - 0, 22, 23, 24, 25, 0, 40, 31, 36, 0, - 0, 48, 0, 0, 0, 0, 43, 35, 34, 0, - 49, 0, 0, 0, 37, 0, 50, 0, 0, 0, - 42, 0, 51, 0, 0, 41, 0, 0, 38, 53, - 52, 0, 0, 0, 46 + 3, 0, 0, 0, 3, 0, 1, 0, 2, 4, + 0, 9, 6, 7, 8, 5, 13, 14, 15, 23, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 22, + 23, 0, 0, 0, 28, 37, 29, 42, 43, 10, + 16, 0, 21, 31, 0, 33, 0, 45, 0, 0, + 24, 25, 26, 27, 0, 38, 11, 0, 19, 20, + 30, 17, 34, 0, 0, 46, 0, 0, 0, 23, + 41, 0, 0, 33, 32, 0, 47, 0, 0, 0, + 12, 18, 35, 23, 48, 0, 0, 23, 40, 0, + 49, 0, 0, 39, 0, 0, 36, 51, 50, 0, + 23, 0, 44 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { - -1, 2, 3, 4, 34, 10, 11, 12, 19, 20, - 16, 32, 44, 45, 46, 68, 36, 47, 69, 48, - 49, 50, 66, 51, 52, 72, 87, 97, 53 + -1, 2, 3, 4, 59, 19, 20, 21, 41, 62, + 61, 8, 22, 29, 30, 31, 32, 63, 33, 34, + 35, 55, 36, 37, 66, 85, 95, 38 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -46 +#define YYPACT_NINF -44 static const yytype_int8 yypact[] = { - -17, 4, 6, 16, -17, 24, -46, -46, -46, -46, - -2, 16, 25, -46, 30, 9, -46, -46, -3, 10, - 15, -46, -46, -46, -46, -46, 16, -46, 8, -46, - 25, 2, 14, -46, -46, -46, 29, -46, -3, 18, - 19, 21, 22, 23, -46, 2, 20, 31, 33, -46, - 26, -46, -46, -46, -46, 8, 8, 8, 48, 32, - 8, -46, -46, -46, -46, -12, -46, -46, 35, 28, - 34, -46, 37, 38, 36, 2, -46, 8, -46, 39, - 8, 53, 42, 43, -46, 2, -46, 45, 57, 2, - -46, 44, 67, 46, 47, -46, 58, 49, -46, -46, - -46, 51, 2, 54, -46 + -16, 6, 11, 2, -16, 19, -44, 10, -44, -44, + 21, 22, -44, -44, -44, -44, -44, -44, -44, 1, + 22, 32, 12, -11, 14, 15, 16, 17, 20, -44, + 1, 23, 25, 26, -44, 27, -44, -44, -44, -44, + -44, -15, -44, -44, 18, 18, 18, 33, 29, 18, + -44, -44, -44, -44, -6, -44, -44, 18, -44, -44, + -44, 38, 24, 28, 31, -44, 34, 35, 37, 1, + -44, 39, 18, 18, -44, 30, 18, 47, 36, 13, + -44, -44, -44, 1, -44, 40, 48, 1, -44, 41, + 62, 42, 43, -44, 54, 44, -44, -44, -44, 49, + 1, 50, -44 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -46, -46, 69, -46, 62, -4, -46, -46, 50, -46, - -46, -46, -45, -46, -11, -26, -46, -46, 1, -46, - 17, -46, -46, -46, -46, -46, -46, -46, -46 + -44, -44, 68, -44, 64, 56, -44, -44, -44, -43, + -44, -44, -44, -30, -44, 45, -44, 4, -44, 46, + -44, -44, -44, -44, -44, -44, -44, -44 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If @@ -581,45 +602,49 @@ static const yytype_int8 yypgoto[] = #define YYTABLE_NINF -1 static const yytype_uint8 yytable[] = { - 61, 21, 35, 40, 1, 38, 6, 17, 5, 15, - 27, 33, 75, 22, 23, 24, 39, 40, 41, 21, - 42, 43, 31, 28, 7, 8, 9, 14, 18, 67, - 83, 70, 29, 26, 74, 22, 23, 24, 30, 54, - 91, 55, 62, 65, 94, 56, 57, 71, 58, 59, - 60, 38, 73, 63, 86, 64, 78, 103, 77, 80, - 93, 81, 79, 85, 82, 88, 89, 92, 90, 95, - 96, 100, 99, 13, 98, 102, 25, 101, 84, 104, - 37, 0, 76 + 50, 60, 43, 64, 23, 1, 68, 56, 57, 25, + 5, 6, 44, 7, 71, 24, 25, 26, 69, 27, + 28, 58, 10, 12, 13, 14, 12, 13, 14, 81, + 16, 17, 18, 84, 11, 40, 23, 42, 88, 79, + 45, 46, 47, 48, 54, 51, 49, 52, 53, 67, + 72, 91, 73, 89, 83, 74, 76, 92, 75, 86, + 87, 80, 90, 77, 78, 94, 93, 98, 97, 96, + 101, 99, 9, 100, 15, 102, 39, 82, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, + 70 }; static const yytype_int8 yycheck[] = { - 45, 12, 28, 15, 21, 3, 0, 11, 4, 11, - 13, 3, 24, 5, 6, 7, 14, 15, 16, 30, - 18, 19, 26, 26, 8, 9, 10, 3, 3, 55, - 75, 57, 22, 24, 60, 5, 6, 7, 23, 25, - 85, 12, 22, 17, 89, 27, 27, 58, 27, 27, - 27, 3, 20, 22, 80, 22, 28, 102, 23, 22, - 3, 23, 28, 24, 28, 12, 24, 22, 25, 25, - 3, 13, 25, 4, 28, 24, 14, 28, 77, 25, - 30, -1, 65 + 30, 44, 13, 46, 3, 21, 49, 22, 23, 15, + 4, 0, 23, 11, 57, 14, 15, 16, 24, 18, + 19, 3, 3, 5, 6, 7, 5, 6, 7, 72, + 8, 9, 10, 76, 24, 3, 3, 25, 25, 69, + 26, 26, 26, 26, 17, 22, 26, 22, 22, 20, + 12, 3, 28, 83, 24, 27, 22, 87, 27, 12, + 24, 22, 22, 28, 27, 3, 25, 13, 25, 27, + 100, 27, 4, 24, 10, 25, 20, 73, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 47, -1, -1, -1, -1, -1, -1, -1, + 54 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 21, 30, 31, 32, 4, 0, 8, 9, 10, - 34, 35, 36, 31, 3, 11, 39, 34, 3, 37, - 38, 43, 5, 6, 7, 33, 24, 13, 26, 22, - 23, 34, 40, 3, 33, 44, 45, 37, 3, 14, - 15, 16, 18, 19, 41, 42, 43, 46, 48, 49, - 50, 52, 53, 57, 25, 12, 27, 27, 27, 27, - 27, 41, 22, 22, 22, 17, 51, 44, 44, 47, - 44, 43, 54, 20, 44, 24, 49, 23, 28, 28, - 22, 23, 28, 41, 47, 24, 44, 55, 12, 24, - 25, 41, 22, 3, 41, 25, 3, 56, 28, 25, - 13, 28, 24, 41, 25 + 0, 21, 30, 31, 32, 4, 0, 11, 40, 31, + 3, 24, 5, 6, 7, 33, 8, 9, 10, 34, + 35, 36, 41, 3, 14, 15, 16, 18, 19, 42, + 43, 44, 45, 47, 48, 49, 51, 52, 56, 34, + 3, 37, 25, 13, 23, 26, 26, 26, 26, 26, + 42, 22, 22, 22, 17, 50, 22, 23, 3, 33, + 38, 39, 38, 46, 38, 44, 53, 20, 38, 24, + 48, 38, 12, 28, 27, 27, 22, 28, 27, 42, + 22, 38, 46, 24, 38, 54, 12, 24, 25, 42, + 22, 3, 42, 25, 3, 55, 27, 25, 13, 27, + 24, 42, 25 }; #define yyerrok (yyerrstatus = 0) @@ -1434,63 +1459,204 @@ yyparse () switch (yyn) { case 2: -#line 38 "practica2.y" - {printf("\n Todo correcto numero de lineas %d\n",nLineas);} +#line 59 "practica2.y" + {if (errores > 0) { + printf("\n Programa compilado con %d errores en %d lineas\n",errores,nLineas); + }else{ + printf("\n Programa compilado sin errores y con %d lineas\n", nLineas); + } + } break; case 5: -#line 43 "practica2.y" - {printf("\nDeclaracion cte");} +#line 70 "practica2.y" + { + int pos = buscarSimbolo(tablaSimbolos, (yyvsp[(3) - (4)].nombreId), dim); + if (pos != dim){ + printf("\n ERROR lin %d: Constante redeclarado",nLineas); + errores++; + } + else { + //lo añado + tablaSimbolos[dim].tipo = (yyvsp[(4) - (4)].tipo); + tablaSimbolos[dim].cte = 1; + tablaSimbolos[dim].inicializado = 1; + strcpy(tablaSimbolos[dim].nombre,(yyvsp[(3) - (4)].nombreId)); + dim++; + } + } + break; + + case 6: +#line 86 "practica2.y" + { (yyval.tipo) = 1; } + break; + + case 7: +#line 87 "practica2.y" + { (yyval.tipo) = 2; } + break; + + case 8: +#line 88 "practica2.y" + { (yyval.tipo) = 3; } break; case 11: -#line 52 "practica2.y" - {printf("\nDeclaracion vble");} +#line 93 "practica2.y" + { + int pos = buscarSimbolo(tablaSimbolos, (yyvsp[(2) - (3)].nombreId), dim); + if (pos != dim){ + printf("\n ERROR lin %d: Identificador redeclarado",nLineas); + errores++; + } + else { + //lo añado + tablaSimbolos[dim].tipo = (yyvsp[(1) - (3)].tipo); + tablaSimbolos[dim].cte = 0; + tablaSimbolos[dim].inicializado = 0; + strcpy(tablaSimbolos[dim].nombre,(yyvsp[(2) - (3)].nombreId)); + dim++; + } + } break; - case 23: -#line 71 "practica2.y" - {printf("\nAsignacion");} + case 12: +#line 108 "practica2.y" + { + int pos = buscarSimbolo(tablaSimbolos, (yyvsp[(2) - (5)].nombreId), dim); + if (pos != dim){ + printf("\n ERROR lin %d: Identificador redeclarado",nLineas); + errores++; + } + else { + if ((yyvsp[(1) - (5)].tipo) != (yyvsp[(4) - (5)].tipo)){ + printf("\n ERROR lin %d: No coinciden los tipos", nLineas); + errores++; + }else if ((yyvsp[(4) - (5)].tipo) != 4){ //el tipo 4 es indicador de que no existe la variable + //lo añado + tablaSimbolos[dim].tipo = (yyvsp[(1) - (5)].tipo); + tablaSimbolos[dim].cte = 0; + tablaSimbolos[dim].inicializado = 1; + strcpy(tablaSimbolos[dim].nombre,(yyvsp[(2) - (5)].nombreId)); + dim++; + } + } + } + break; + + case 13: +#line 129 "practica2.y" + { (yyval.tipo) = 1; } break; - case 24: -#line 72 "practica2.y" - {printf("\nVisualizacion");} + case 14: +#line 130 "practica2.y" + { (yyval.tipo) = 2; } break; - case 25: -#line 73 "practica2.y" - {printf("\nLectura");} + case 15: +#line 131 "practica2.y" + { (yyval.tipo) = 3; } break; - case 26: -#line 74 "practica2.y" - {printf("\nCondicion");} + case 16: +#line 133 "practica2.y" + { strcpy((yyval.nombreId), (yyvsp[(1) - (1)].nombreId)); } break; - case 39: -#line 94 "practica2.y" - {printf("\nBloque IF");} + case 17: +#line 135 "practica2.y" + { (yyval.tipo) = (yyvsp[(1) - (1)].tipo); } break; - case 40: -#line 95 "practica2.y" - {printf("\nBloque IF+ELSE");} + case 18: +#line 136 "practica2.y" + { if ((yyvsp[(1) - (3)].tipo) < (yyvsp[(3) - (3)].tipo)) + { + (yyval.tipo) = (yyvsp[(3) - (3)].tipo); + }else{ + (yyval.tipo) = (yyvsp[(1) - (3)].tipo); + } + } break; - case 44: -#line 102 "practica2.y" - {printf("\nRepeticion: bloque FOR");} + case 19: +#line 144 "practica2.y" + { int pos = buscarSimbolo(tablaSimbolos, (yyvsp[(1) - (1)].nombreId), dim); + int tipo = tablaSimbolos[pos].tipo; + if (tipo == 0){ + printf("\n ERROR lin %d: Variable %s no declarada", nLineas, (yyvsp[(1) - (1)].nombreId)); + errores++; + tipo = 4; + } + if (tablaSimbolos[pos].inicializado == 0){ + printf("\n ERROR lin %d: Variable %s no inicializada", nLineas, (yyvsp[(1) - (1)].nombreId)); + errores++; + tipo = 4; + } + (yyval.tipo) = tipo; + } break; - case 45: -#line 103 "practica2.y" - {printf("\nRepeticion: bloque WHILE");} + case 20: +#line 158 "practica2.y" + { (yyval.tipo) = (yyvsp[(1) - (1)].tipo); } + break; + + case 30: +#line 173 "practica2.y" + { int pos = buscarSimbolo(tablaSimbolos, (yyvsp[(1) - (3)].nombreId), dim); + int tipo = tablaSimbolos[pos].tipo; + if (tipo == 0){ + printf("\n ERROR lin %d: Variable %s no declarada", nLineas, (yyvsp[(1) - (3)].nombreId)); + errores++; + } + if (tablaSimbolos[pos].cte == 1){ + printf("\n ERROR lin %d: No se puede modificar el valor de una constante", nLineas); + errores++; + } + if ((tipo == 1 && (yyvsp[(3) - (3)].tipo) == 2) || (tipo == 3 && (yyvsp[(3) - (3)].tipo) == 2)){ //Problemas con entero = float y char = float + printf("\n ERROR lin %d: No coinciden los tipos", nLineas); + errores++; + } + + } + break; + + case 36: +#line 197 "practica2.y" + { int pos = buscarSimbolo(tablaSimbolos, (yyvsp[(6) - (7)].nombreId), dim); + int tipo = tablaSimbolos[pos].tipo; + if (tipo == 0){ + printf("\n ERROR lin %d: Variable %s no declarada", nLineas, (yyvsp[(6) - (7)].nombreId)); + errores++; + } + if ((yyvsp[(3) - (7)].tipo) != tipo && tipo != 0){ + printf("\n ERROR lin %d: Tipos incompatibles en scanf", nLineas); + errores++; + } + } + break; + + case 50: +#line 229 "practica2.y" + { int pos = buscarSimbolo(tablaSimbolos, (yyvsp[(1) - (2)].nombreId), dim); + int tipo = tablaSimbolos[pos].tipo; + if (tipo == 0){ + printf("\n ERROR lin %d: Variable %s no declarada", nLineas, (yyvsp[(1) - (2)].nombreId)); + errores++; + } + else if (tablaSimbolos[pos].inicializado == 0){ + printf("\n ERROR lin %d: Variable %s no inicializada", nLineas, (yyvsp[(1) - (2)].nombreId)); + errores++; + } + } break; /* Line 1267 of yacc.c. */ -#line 1494 "y.tab.c" +#line 1660 "y.tab.c" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -1704,15 +1870,23 @@ yyparse () } -#line 120 "practica2.y" +#line 245 "practica2.y" int main() { - yyin=fopen("practica2.c","r"); - yyparse(); + yyin=fopen("practica2conErrores.c","r"); + yyparse(); } +int buscarSimbolo(struct simbolo tablaSimbolos[],char nombre[50],int dim){ + for (int i=0;i