У меня есть следующий код бизона, и следующие операторы работают нормально.
1 + 1
1.0 + 1.0
Но я хочу, чтобы следующее утверждение сработало
1.0 + 1
Я понимаю, что приведенный ниже код неоптимален, но меня попросили сохранить его в этом формате.
%{
#include <stdio.h>
#include <math.h>
#include <ctype.h>
#include <string.h>
#include <errno.h>
/* Prototypes */
int yylex(void);
void yyerror(char *);
int isFloat = 0;
%}
%union {
int iVal;
double fVal;
}
%token <iVal> INTEGER
%token <fVal> FLOAT
%type <iVal> expri termi utermi factori parti
%type <fVal> exprf termf utermf factorf partf
%%
command : expri {printf("%d\n", $1); return;}
| exprf {printf("%f\n", $1); return;}
;
expri : expri '+' termi {$$ = $1 + $3;}
| expri '-' termi {$$ = $1 - $3;}
| utermi {$$ = $1;}
;
termi : termi '*' factori {$$ = $1 * $3;}
| termi '/' factori {$$ = $1 / $3;}
| termi '%' factori {$$ = $1 % $3;}
| factori {$$ = $1;}
;
utermi : utermi '*' factori {$$ = $1 * $3;}
| utermi '/' factori {$$ = $1 / $3;}
| utermi '%' factori {$$ = $1 % $3;}
| '-' factori {$$ = -$2;}
| factori {$$ = $1;}
;
factori : factori '^' parti {$$ = pow($1, $3);}
| parti {$$ = $1;}
;
parti : '(' expri ')' {$$ = $2;}
| INTEGER {$$ = $1;}
;
/* FLOAT RULES */
exprf : exprf '+' termf {$$ = $1 + $3;}
| exprf '-' termf {$$ = $1 - $3;}
| utermf {$$ = $1;}
;
termf : termf '*' factorf {$$ = $1 * $3;}
| termf '/' factorf {$$ = $1 / $3;}
| termf '%' factorf {$$ = fmodf($1, $3);}
| factorf {$$ = $1;}
;
utermf : utermf '*' factorf {$$ = $1 * $3;}
| utermf '/' factorf {$$ = $1 / $3;}
| utermf '%' factorf {$$ = fmodf($1,$3);}
| '-' factorf {$$ = -$2;}
| factorf {$$ = $1;}
;
factorf : factorf '^' partf {$$ = pow($1, $3);}
| partf {$$ = $1;}
;
partf : '(' exprf ')' {$$ = $2;}
| FLOAT {$$ = $1;}
;
%%
Хотя оба типа отлично работают в своих собственных ветвях, структура (очевидно) очень неоптимальна с сильным дублированием, но я не знаю обходной путь и не знаю, как распределять между ними.