【问题标题】:flex and bison calculator abs valueflex 和 bison 计算器 abs 值
【发布时间】:2019-08-15 22:12:03
【问题描述】:

我想在 Flex 和 Bison 中实现 abs 运算符;到目前为止,我制作的程序如下:

野牛文件

%{
#include <stdio.h>
%}

/* declare tokens */
%token NUMBER
%token ADD SUB MUL DIV ABS
%token EOL

%%
calclist: /* nothing */
    | calclist exp EOL { 
                printf("= %d\n", $2); 
               }
;

exp: factor     
    | exp ADD factor { $$ = $1 + $3; }
    | exp SUB factor { $$ = $1 - $3; }
;

factor: term        
    | factor MUL term { $$ = $1 * $3; }
    | factor DIV term { $$ = $1 / $3; }
;

term: NUMBER        
    | ABS term {if ($2>=0) $$=$2;
            else $$= - $2;}
;
%%
main(int argc, char **argv)
{
    yyparse();
}
yyerror(char *s)
{
    fprintf(stderr, "error: %s\n", s);
}

弹性文件

%{
# include "f5.tab.h"
%}
/* recognize tokens for the calculator and print them out */

%%
"+" { return ADD; }
"-" { return SUB; }
"*" { return MUL; }
"/" { return DIV; }
"|" { return ABS; }
[0-9]+ { yylval = atoi(yytext); 
    return NUMBER; 
    }
\n  { return EOL; }
[ \t]   { /* ignore whitespace */ }
.   { 
        printf("Mystery character %c\n", *yytext); 
    }
%%
yywrap()
{
}

我编译它:

bison -d bisonfile.y
flex flexfile.l
gcc bisonfile.tab.c lex.yy.c -o test.exe

然后当我输入如下表达式时:

34+|3

它输出 37

但是当我输入类似的内容时:

34+|-3

它打印“语法错误”

这是为什么呢?任何帮助都会很有价值。

谢谢

【问题讨论】:

  • 您将其定义为NUMBER, ADD, ABS, SUB, NUMBER,您的解析规则无法处理。您可能还想将+- 视为可能的一元运算
  • @jenesaisquoi 你能给我一些解决方案吗?我已经尝试了所有方法,但似乎没有任何效果
  • 为什么不为一元表达式添加另一个规则,例如。 unary_expr: SUB ... | ...

标签: bison flex-lexer


【解决方案1】:

因为- 不是一个数字,而| 只能应用于一个数字(或另一个| 应用于一个数字):

term: NUMBER
    | ABS term

所以|- 是一个语法错误。

【讨论】:

  • 谢谢@melpomene,你能帮我解决这个问题吗?
【解决方案2】:

也可以在词法分析器文件中进行更改,我们可以在其中NUMBER 定义为一个或多个数字的字符串,可选前缀为 +- 符号

这将使词法分析器文件如下所示:(注意,在这种情况下,野牛文件不需要更改)

calc.lex

%{
    #include "calc.tab.h"
%}

%%

"+"                 { return ADD; }
"-"                 { return SUB; }
"*"                 { return MUL; }
"/"                 { return DIV; }
"|"                 { return ABS; }
("+"|"-")?[0-9]+    { yylval = atoi(yytext); return NUMBER; }
\n                  { return EOL; }
[ \t]               { /* ignore white spaces */ }
.                   { printf("Mystery character %s\n", yytext); }

%%

编辑:

  • NUMBER 的定义的一个重要含义是,现在当您想要加法或减法时,您需要编写 +- ,否则它会将带有数字的运算符附加到右侧。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-24
    相关资源
    最近更新 更多