I have this program but it doesn't work, who can help me? When I entry 2+3 and Enter, the .exe file suddenly closes. I have no idea of what's wrong but I need to solve this soon, hope you can help me. Here's lexico.l:
/* Ejemplo para una pequeña calculadora que permite trabajar
con las funciones trigonometricas como el seno y el coseno */
#include <stdio.h>
#include <stdlib.h>
#include "sintactico.tab.h"
int nlines=0;
%}
DIGITO [0-9]
ID [a-zA-Z][a-zA-Z0-9_]*
%%
{DIGITO}+("."{DIGITO}+)? {//printf("Encontrado TKN_NUM: %f\n",atof(yytext));
yylval.real=atof(yytext);
return(TKN_NUM);}
"=" {//printf("Encontrado TKN_ASIGN: %s\n",yytext);
return(TKN_ASIGN);}
"(" {//printf("Encontrado TKN_PAA: %s\n",yytext);
return(TKN_PAA);}
")" {//printf("Encontrado TKN_PAC: %s\n",yytext);
return(TKN_PAC);}
"cos" {//printf("Encontrado TKN_COS: %s\n",yytext);
return(TKN_COS);}
"sen" {//printf("Encontrado TKN_SEN: %s\n",yytext);
return(TKN_SEN);}
{ID} {//printf("Encontrado TKN_ID: %s\n",yytext);
return(TKN_ID);}
"\n" {nlines++;}
.
%%
And sintactico.y file:
%{
/* Ejemplo para una pequeña calculadora que permite trabajar
con funciones trigonometricas como el seno y el coseno */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
extern int yylex(void);
extern char *yytext;
extern int nlines;
extern FILE *yyin;
void yyerror(char *s);
%}
%union
{
float real;
}
%start Calculadora
%token <real> TKN_NUM
%token TKN_ASIGN
%token TKN_PAA
%token TKN_PAC
%token TKN_COS
%token TKN_SEN
%token <real> TKN_ID
%type Calculadora
%type <real> Expresion
%left TKN_MAS TKN_MENOS
%left TKN_MULT TKN_DIV
%%
Calculadora : TKN_ID { printf("El valor de %s es: ", yytext);}
Expresion : TKN_NUM {$$=$1;}|
TKN_PAA Expresion TKN_PAC {$$=$2;}|
TKN_COS TKN_PAA Expresion TKN_PAC {$$=cos($3);}|
TKN_SEN TKN_PAA Expresion TKN_PAC {$$=sin($3);};
%%
void yyerror(char *s)
{
printf("Error %s",s);
}
int main(int argc,char **argv)
{
if (argc>1)
yyin=fopen(argv[1],"rt");
else
yyin=stdin;
yyparse();
printf("FIN del Analisis. Entrada CORRECTA\n");
printf("Numero lineas analizadas: %d\n", nlines);
return 0;
}
What's wrong with it? I'm new with this Flex and Bison and it's hard to me to understand errors.
It looks like you want to use variable names, then you need to read in a string value in the lexer and use it the bison file.
Your %union could look like this:
%union
{
char* str;
float real;
}
Likewise your TNK_ID should be:
%token <str> TKN_ID
And your adapted lexico.l could look something like this:
{DIGITO}+("."{DIGITO}+)? { yylval.real=atof(yytext); return(TKN_NUM); }
= { return TKN_ASIGN; }
\( { return TKN_PAA; }
\) { return TKN_PAC; }
cos { return TKN_COS; }
sen { return TKN_SEN; }
{ID} { yylval.str = strdup(yytext); return TKN_ID; }
\+ { return TKN_MAS; }
\- { return TKN_MENOS; }
\n { nlines++; return '\n'; }
.
Note also that there are now definitions for + and - as well as \n. The variable name is stored in yylval.str.
Calculadora would rather look like this:
Calculadora: { $$ = 0; }
| Calculadora Expresion '\n' { printf("%f\n", $2); }
| Calculadora '\n'
;
And for Expresion
the handling for IDs, assignments as well as plus and minus operation should be added, e.g.
Expresion: TKN_NUM { $$=$1; }
| TKN_ID { $$ = get_symbol($1)->value; }
| TKN_ID TKN_ASIGN Expresion { put_symbol($1, $3); $$ = $3; }
| Expresion TKN_MENOS Expresion { $$ = $1 - $3; }
| Expresion TKN_MAS Expresion { $$ = $1 + $3; }
| TKN_PAA Expresion TKN_PAC { $$ = $2; }
| TKN_COS TKN_PAA Expresion TKN_PAC { $$ = cos($3); }
| TKN_SEN TKN_PAA Expresion TKN_PAC { $$ = sin($3); }
;
Since it seems you want to assign values to variable names, you need a kind of symbol table. You could provide an implemention of void put_symbol(char *name, float value)
and struct symbol_entry *get_symbol(char *name)
. A symbol entry could be defined as:
struct symbol_entry {
char name[50];
float value;
};
Test
A quick test - one line of entry is followed by one line output of the calculator:
5 + 3
8.000000
a = 5 + 3
8.000000
a = 0.5
0.500000
a
0.500000
b = cos(a)
0.877583
c = b + a
1.377583
c
1.377583
Is that what you are looking for?