I'm working on a simple calculator in lex/yacc & I'm trying to have some functions return as doubles, rather than integers.
I initially had everything under expr
. Finding out I can't type cast $$
I introduced a new type, DECIMAL
and added it as a new grammar.
Now any function call produces a syntax error and terminates the program.
My code:
%{
#define PI 3.14159265358979
#include <stdio.h>
#include <math.h>
int regs[26];
int base;
int yylex();
int yyerror(char *s);
int yywrap();
%}
%start list
%union {
int a;
double b;
char c;
}
%type <a> expr number DIGIT
%type <c> LETTER
%type <b> DECIMAL
%token DIGIT LETTER
%token EXIT
%token SIN COS TAN SQRT LOG LN
%left '|'
%left '&'
%left '+' '-'
%left '*' '/' '%'
%left UMINUS
%right '^'
%nonassoc SIN COS TAN SQRT LOG LN
%%
list: /* empty */
| list stat '\n'
| list error '\n' {
yyerrok;
};
| list EXIT {
exit(EXIT_SUCCESS);
}
| DECIMAL ;
stat: expr {
printf("%d\n", $1);
}
| LETTER '=' expr {
regs[$1] = $3;
};
expr: '(' expr ')' {
$$ = $2;
}
| expr '*' expr {
$$ = $1 * $3;
}
| expr '/' expr {
$$ = $1 / $3;
}
| expr '%' expr {
$$ = $1 % $3;
}
| expr '+' expr {
$$ = $1 + $3;
}
| expr '-' expr {
$$ = $1 - $3;
}
| expr '&' expr {
$$ = $1 & $3;
}
| expr '|' expr {
$$ = $1 | $3;
}
| '-' expr %prec UMINUS {
$$ = -$2;
}
| expr '^' expr{
$$ = pow($1,$3);
}
| LETTER {
$$ = regs[$1];
}
| number;
DECIMAL:
SIN DECIMAL {
$$ = sin($2 * PI / 180);
}
| COS DECIMAL {
$$ = cos($2 * PI / 180);
}
| TAN DECIMAL {
$$ = tan($2 * PI / 180);
}
| SQRT DECIMAL {
$$ = sqrt($2);
}
| LOG DECIMAL{
$$ = log10($2);
}
| LN DECIMAL{
$$ = log($2);
}
number: DIGIT {
$$ = $1;
base = ($1 == 0) ? 8 : 10;
}
| number DIGIT {
$$ = base * $1 + $2;
};
%%
int main() {
return yyparse();
}
int yyerror(char *s) {
fprintf(stderr, "%s\n", s);
return 1;
}
int yywrap() {
return 1;
}
and if it helps, here's my lex code
%{
#include <stdio.h>
#include "y.tab.h"
int c;
extern YYSTYPE yylval;
%}
%%
" ";
[a-z] {
c = yytext[0];
yylval.a = c - 'a';
return(LETTER);
}
[0-9] {
c = yytext[0];
yylval.a = c - '0';
return(DIGIT);
}
[^a-z0-9\b] {
c = yytext[0];
return(c);
}
sin {
return SIN;
}
cos {
return COS;
}
tan {
return TAN;
}
sqrt {
return SQRT;
}
log {
return LOG;
}
ln {
return LN;
}
exit {
return EXIT;
}