J
jiten
Hi all,
I have a small request. I am a newbie to lex/yacc and as part of term
assignment was developing a calculator. But, I have problem that I
cannot perform any real data type operation. Not even addition. At
best, the response is :
Kindly find the two files posted below:
calc.y
==========
%{#include<stdio.h>
%}
/*%union {double real; int integer;}*/
%token <real> REAL
%token <integer> INTEGER
%token PLUS MINUS TIMES DIVIDE LP RP NL UL
%type <real> rexpr
%type <integer> iexpr
%left PLUS MINUS
%left TIMES DIVIDE
%left UMINUS
%%
lines : /* nothing*/
| lines line
;
line : NL
|iexpr NL
{ printf("%d)%d\n", lineno, $1);}
|rexpr UL
{ printf("%d)%15.8lf\n", lineno, $1);}
iexpr : INTEGER
|iexpr PLUS iexpr
{ $$ = $1 + $3; }
|iexpr MINUS iexpr
{ $$ = $1 - $3; }
|iexpr TIMES iexpr
{ $$ = $1 * $3; }
|iexpr DIVIDE iexpr
{ if($3) $$ = $1/$3;
else {yyerror("divide by zero"); }
}
|MINUS iexpr %prec UMINUS
{ $$ = -$2;}
|LP iexpr RP
{ $$ = $2; }
rexpr : REAL
|rexpr PLUS rexpr
{ $$ = $1 + $3; }
|rexpr MINUS rexpr
{ $$ = $1 - $3; }
|rexpr TIMES rexpr
{ $$ = $1 * $3; }
|rexpr DIVIDE rexpr
{ if($3) $$ = $1/$3;
else {yyerror("divide by zero"); }
}
|MINUS rexpr %prec UMINUS
{ $$ = -$2;}
|LP rexpr RP
{ $$ = $2; }
|iexpr PLUS rexpr
{ $$ = (double)$1 + $3; }
|iexpr MINUS rexpr
{ $$ = (double)$1 - $3; }
|iexpr TIMES rexpr
{ $$ = (double)$1 * $3; }
|iexpr DIVIDE rexpr
{ if($3) $$ = (double)$1/$3;
else {yyerror("divide by zero"); }
}
|rexpr PLUS iexpr
{ $$ = $1 +(double)$3;}
|rexpr MINUS iexpr
{ $$ = $1 -(double)$3;}
|rexpr DIVIDE iexpr
{ if($3) $$ = (double)$1/$3;
else{yyerror("divide by zero"); }
}
%%
#include "lex.yy.c"
int lineno;
main()
{
return yyparse();
}
yyerror(char *s)
{
fprintf(stderr, "%s\n", s);
}
=============
calc.l
-----------
%{
#include"y.tab.h"
%}
integer [0-9]+
dreal ([0-9]*\.[0-9]+)
ereal ([0-9]*\.[0-9]+[Ee][+-]?[0-9]+)
real {dreal}|{ereal}
nl \n
%%
[ \t] ;
{integer} { sscanf(yytext, "%d", &yylval.integer);
return INTEGER;
}
{real} { sscanf(yytext, "%lf", &yylval.real);
return REAL;
}
\+ {return PLUS;}
\- {return MINUS;}
\* {return TIMES;}
\/ {return DIVIDE;}
\( {return LP;}
\) {return RP;}
{nl} {extern int lineno; lineno++; return NL;}
.. {return yytext[0];} /* to return any character otherwise
not handled as a single char. token to the parser*/
%%
int yywrap() { return 1;}
Best regards,
Jitender Ahuja
I have a small request. I am a newbie to lex/yacc and as part of term
assignment was developing a calculator. But, I have problem that I
cannot perform any real data type operation. Not even addition. At
best, the response is :
error'.> command not found (e.g., for i/p: 5.0+6.0); else it is 'syntax
Kindly find the two files posted below:
calc.y
==========
%{#include<stdio.h>
%}
/*%union {double real; int integer;}*/
%token <real> REAL
%token <integer> INTEGER
%token PLUS MINUS TIMES DIVIDE LP RP NL UL
%type <real> rexpr
%type <integer> iexpr
%left PLUS MINUS
%left TIMES DIVIDE
%left UMINUS
%%
lines : /* nothing*/
| lines line
;
line : NL
|iexpr NL
{ printf("%d)%d\n", lineno, $1);}
|rexpr UL
{ printf("%d)%15.8lf\n", lineno, $1);}
iexpr : INTEGER
|iexpr PLUS iexpr
{ $$ = $1 + $3; }
|iexpr MINUS iexpr
{ $$ = $1 - $3; }
|iexpr TIMES iexpr
{ $$ = $1 * $3; }
|iexpr DIVIDE iexpr
{ if($3) $$ = $1/$3;
else {yyerror("divide by zero"); }
}
|MINUS iexpr %prec UMINUS
{ $$ = -$2;}
|LP iexpr RP
{ $$ = $2; }
rexpr : REAL
|rexpr PLUS rexpr
{ $$ = $1 + $3; }
|rexpr MINUS rexpr
{ $$ = $1 - $3; }
|rexpr TIMES rexpr
{ $$ = $1 * $3; }
|rexpr DIVIDE rexpr
{ if($3) $$ = $1/$3;
else {yyerror("divide by zero"); }
}
|MINUS rexpr %prec UMINUS
{ $$ = -$2;}
|LP rexpr RP
{ $$ = $2; }
|iexpr PLUS rexpr
{ $$ = (double)$1 + $3; }
|iexpr MINUS rexpr
{ $$ = (double)$1 - $3; }
|iexpr TIMES rexpr
{ $$ = (double)$1 * $3; }
|iexpr DIVIDE rexpr
{ if($3) $$ = (double)$1/$3;
else {yyerror("divide by zero"); }
}
|rexpr PLUS iexpr
{ $$ = $1 +(double)$3;}
|rexpr MINUS iexpr
{ $$ = $1 -(double)$3;}
|rexpr DIVIDE iexpr
{ if($3) $$ = (double)$1/$3;
else{yyerror("divide by zero"); }
}
%%
#include "lex.yy.c"
int lineno;
main()
{
return yyparse();
}
yyerror(char *s)
{
fprintf(stderr, "%s\n", s);
}
=============
calc.l
-----------
%{
#include"y.tab.h"
%}
integer [0-9]+
dreal ([0-9]*\.[0-9]+)
ereal ([0-9]*\.[0-9]+[Ee][+-]?[0-9]+)
real {dreal}|{ereal}
nl \n
%%
[ \t] ;
{integer} { sscanf(yytext, "%d", &yylval.integer);
return INTEGER;
}
{real} { sscanf(yytext, "%lf", &yylval.real);
return REAL;
}
\+ {return PLUS;}
\- {return MINUS;}
\* {return TIMES;}
\/ {return DIVIDE;}
\( {return LP;}
\) {return RP;}
{nl} {extern int lineno; lineno++; return NL;}
.. {return yytext[0];} /* to return any character otherwise
not handled as a single char. token to the parser*/
%%
int yywrap() { return 1;}
Best regards,
Jitender Ahuja