与野牛和弯曲的钙不起作用操作负面

时间:2017-05-18 02:33:42

标签: c compiler-construction bison flex-lexer

我对这个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

1 个答案:

答案 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可以保持不变(尽管浮点数有点复杂)。