我对这个Bison计划有疑问。我不知道为什么重用不起作用。对于带负数的操作,我只使用相同的行来获取第一个数字并使用更多操作。我只是将第一个数字改为负数。
anychart-range-picker
anychart-range-selector
anychart-button
anychart-label-input
anychart-input-label
calc.y
%{
#include <stdio.h>
#include <stdlib.h>
extern int yylex();
extern int yyparse();
extern FILE* yyin;
void yyerror(const char* s);
%}
%union {
int ival;
float fval;
}
%token<ival> T_INT
%token<fval> T_FLOAT
%token T_PLUS T_MINUS T_MULTIPLY T_DIVIDE T_LEFT T_RIGHT
%token T_NEWLINE T_QUIT
%left T_PLUS T_MINUS
%left T_MULTIPLY T_DIVIDE
%type<ival> expression
%type<fval> mixed_expression
%start calculation
%%
calculation:
| calculation line
;
line: T_NEWLINE
| mixed_expression T_NEWLINE { printf("\tResult: %f\n", $1);}
| expression T_NEWLINE { printf("\tResult: %i\n", $1); }
| T_QUIT T_NEWLINE { printf("bye!\n"); exit(0); }
;
mixed_expression: T_FLOAT { $$ = $1; }
| T_MINUS T_FLOAT { $$ = -$2; }
| mixed_expression T_PLUS mixed_expression { $$ = $1 + $3; }
| mixed_expression T_MINUS mixed_expression { $$ = $1 - $3; }
| mixed_expression T_MULTIPLY mixed_expression { $$ = $1 * $3; }
| mixed_expression T_DIVIDE mixed_expression { $$ = $1 / $3; }
| T_LEFT mixed_expression T_RIGHT { $$ = $2; }
| T_MINUS mixed_expression T_RIGHT { $$ = -$2; }
| expression T_PLUS mixed_expression { $$ = $1 + $3; }
| expression T_MINUS mixed_expression { $$ = $1 - $3; }
| expression T_MULTIPLY mixed_expression { $$ = $1 * $3; }
| expression T_DIVIDE mixed_expression { $$ = $1 / $3; }
| mixed_expression T_PLUS expression { $$ = $1 + $3; }
| mixed_expression T_MINUS expression { $$ = $1 - $3; }
| mixed_expression T_MULTIPLY expression { $$ = $1 * $3; }
| mixed_expression T_DIVIDE expression { $$ = $1 / $3; }
| expression T_DIVIDE expression { $$ = $1 / (float)$3; }
;
expression: T_INT { $$ = $1; }
| expression T_PLUS expression { $$ = $1 + $3; }
| expression T_MINUS expression { $$ = $1 - $3; }
| expression T_MULTIPLY expression { $$ = $1 * $3; }
| T_LEFT expression T_RIGHT { $$ = $2; }
| T_MINUS T_INT { $$ = -$2; }
;
%%
int main() {
yyin = stdin;
do {
yyparse();
} while(!feof(yyin));
return 0;
}
void yyerror(const char* s) {
fprintf(stderr, "Parse error: %s\n", s);
exit(1);
}
calclex.l
答案 0 :(得分:2)
正如我在评论中所说,问题被称为&#34;一元减去&#34;它描述了将正常减法运算a - b
与否定运算0 - a
区分开来的问题,如果它缩写为-a
。常见的解决方案是添加一些代码,使负号作为两个不同的运算符,具体取决于位置。它是在Bison中通过为不存在的符号(此处为NEG
)实现优先级并将该优先级绑定到案例-a
来完成的。
您需要在代码中执行两次,一次用于T_FLOAT
,第二次用于T_INT
。我也删除了一条毫无意义的行,至少对我而言。
calc.y
:
%{
#include <stdio.h>
#include <stdlib.h>
extern int yylex();
extern int yyparse();
extern FILE* yyin;
void yyerror(const char* s);
%}
%union {
int ival;
float fval;
}
%token<ival> T_INT
%token<fval> T_FLOAT
%token T_PLUS T_MINUS T_MULTIPLY T_DIVIDE T_LEFT T_RIGHT
%token T_NEWLINE T_QUIT
%left T_PLUS T_MINUS
%left T_MULTIPLY T_DIVIDE
%precedence NEG /* unary minus */
%type<ival> expression
%type<fval> mixed_expression
%start calculation
%%
calculation:
| calculation line
;
line: T_NEWLINE
| mixed_expression T_NEWLINE { printf("\tResult: %f\n", $1);}
| expression T_NEWLINE { printf("\tResult: %i\n", $1); }
| T_QUIT T_NEWLINE { printf("bye!\n"); exit(0); }
;
mixed_expression: T_FLOAT { $$ = $1; }
| T_MINUS mixed_expression %prec NEG { $$ = -$2; }
| mixed_expression T_PLUS mixed_expression { $$ = $1 + $3; }
| mixed_expression T_MINUS mixed_expression { $$ = $1 - $3; }
| mixed_expression T_MULTIPLY mixed_expression { $$ = $1 * $3; }
| mixed_expression T_DIVIDE mixed_expression { $$ = $1 / $3; }
| T_LEFT mixed_expression T_RIGHT { $$ = $2; }
/* | T_MINUS mixed_expression T_RIGHT { $$ = -$2; } */
| expression T_PLUS mixed_expression { $$ = $1 + $3; }
| expression T_MINUS mixed_expression { $$ = $1 - $3; }
| expression T_MULTIPLY mixed_expression { $$ = $1 * $3; }
| expression T_DIVIDE mixed_expression { $$ = $1 / $3; }
| mixed_expression T_PLUS expression { $$ = $1 + $3; }
| mixed_expression T_MINUS expression { $$ = $1 - $3; }
| mixed_expression T_MULTIPLY expression { $$ = $1 * $3; }
| mixed_expression T_DIVIDE expression { $$ = $1 / $3; }
| expression T_DIVIDE expression { $$ = $1 / (float)$3; }
;
expression: T_INT { $$ = $1; }
| expression T_PLUS expression { $$ = $1 + $3; }
| expression T_MINUS expression { $$ = $1 - $3; }
| expression T_MULTIPLY expression { $$ = $1 * $3; }
| T_LEFT expression T_RIGHT { $$ = $2; }
| T_MINUS expression %prec NEG { $$ = -$2; }
;
%%
int main() {
yyin = stdin;
do {
yyparse();
} while(!feof(yyin));
return 0;
}
void yyerror(const char* s) {
fprintf(stderr, "Parse error: %s\n", s);
exit(1);
}
文件calclex.l
可以保持不变(尽管浮点数有点复杂)。