%{
#include<math.h>
#include<string.h>
#include<intmus.h>
/*enlace con lex*/
extern unsigned yylineno;
extern FILE *yyout;
%}
%union{
int valor; /*valor actual*/
TablaSim *sim; /*puntero a tabla de simbolos*/
}
%token READ WRITE MAS MENOS POR DIV PUNTO_Y_COMA MENOS_UNARIO
%token ABRE_PARENT CIERRA_PARENT PUNTO POTENCIA IGUAL MOD
%token <valor> ENTERO
%token <sim> IDENTIF UNDEF
%type <valor> expres
%right IGUAL
%left MAS MENOS
%left POR DIV MOD
%right POTENCIA
%nonassoc MENOS_UNARIO
%%
programa: /*vacio*/
| bloque PUNTO
;
bloque: sentencia PUNTO_Y_COMA
| bloque sentencia PUNTO_Y_COMA
;
sentencia: /*vacio*/
|read
|write
|asigna
|expres
;
read: READ IDENTIF {read_var($2);}
;
write: WRITE IDENTIF {write_var{$2};}
;
asigna: IDENTIF IGUAL expres {$1->valor=$3; $1->tipo=IDENTIF;}
;
expres: ENTERO {$$=$1;}
| IDENTIF {if($1->tipo==UNDEF) execerror("Variable indefinida..!") $$=$1->valor;}
|expres MAS expres {$$ = $1 + $3;}
|expres MENOS expres {$$ = $1 - $3;}
|expres POR expres {$$ = $1 * $3;}
|expres DIV expres {if($3==0) execerror("Division por cero..!"); $$ = $1 / $3; }
|expres MOD expres {if($3==0) execerror("Division por cero..!"); $$ = $1 % $3; }
|expres POTENCIA expres{$$=(int) pow ($1,$3);}
|ABRE_PARENT expres CIERRA_PARENT {$$ = $2;}
|MENOS expres %prec MENOS_UNARIO {$$ = -$2;}
;
%%
void yyerror(char *s){
printf("Error sintactico en linea %d.\n",yylineno);
}
void execerror(char *literal){
fprintf(stderr; "%s en linea %d.\n" literal, yylineno);
}/*fin execerror()*/
/*lectura de variable por pantalla*/
void read_var(TablaSim *p){
printf("%s ? : ",p->nomvar);
scanf("%d",%p->valor);
p->tipo=IDENTIF;
}/*fin read_var()*/
/*muestra variable por pantalla*/
void write_var(TablaSim *p){
printf("%s = %d\n",p->nomvar, p->valor);
}/*fin write_var()*/