【问题标题】:lex/bison program to evaluate an expressionlex/bison 程序计算表达式
【发布时间】:2016-04-15 11:11:28
【问题描述】:

以下是yacc代码:

%{
#include<stdio.h>
#include<math.h>
%}
%token NUMBER
%left '-' '+'
%left '*' '/'
%nonassoc UMINUS
%%
statement:expression {printf("Answer=%g\n",$1);}
;
expression:expression'+'expression {$$=$1+$3;}
|expression'-'expression {$$=$1-$3;}
|expression'*'expression {$$=$1*$3;}
|expression'/'expression {if($3==0)
yyerror("Divide by Zero");
else
$$=$1/$3;
}
|'-'expression %prec UMINUS {$$= -$2;}
|'('expression')' {$$=$2;}
|NUMBER {$$=$1;}
;
%% 
int main(void)
{
printf("Enter the Expression");
yyparse();
printf("\n\n");
return 0;
}
int yyerror(char *error)
{
printf("%s\n",error);
return 0;
}

以下为法码:

%{
#include<stdio.h>
#include "y.tab.h"
#define YYSTYPE double
extern int yylval;
%}
%%
[0-9]+|[0-9]*\.[0-9]+   { yylval=atof(yytext); return NUM;}
'\n'                    { return 0;}
'\t'                    {}
.                       {return yytext[0]; }
%%
int yywrap()
{
    return 1;
}

我编译了 lex 和 yacc 代码。除了一些警告外,没有明显的错误。但是当我运行可执行文件时,它没有显示任何值,而是 0.000000。

【问题讨论】:

  • 为什么换行规则返回零?或者确实是什么?是空格。噪音。对解析器不重要。

标签: bison flex-lexer yacc lex


【解决方案1】:
#define YYSTYPE double
extern int yylval;

那么语义类型是int 还是double

由于您使用atofprintf("%g", $$),我想您的意图是语义类型是浮点数。但是您的声明并没有做到这一点:

  • 定义宏 YYSTYPE 仅在解析器中有效。扫描仪从不使用该宏。在解析器中,默认类型是int

  • yylval 在解析器中声明(类型为YYSTYPE,根据该文件中的定义)。所以它肯定是int,并且扫描器中的extern 声明是正确的,但不是我们想要的。

  • 使用格式代码%g 打印int 是未定义的行为。所有数字似乎都打印为 0.0 的事实并不奇怪,但是对于 UB,没有任何行为是令人惊讶的。如果您在编译解析器时甚至启用了编译器警告,这可能是您忽略的警告之一。您应该启用这些警告并认真对待它们;这个习惯会帮助你解决自己的问题。

【讨论】:

  • @abhilash:我不相信您在进行这些更改之前阅读了我的回答。顺便说一句,不鼓励在回答后更改您的问题,因为这可能会使答案错误或无关紧要。我更改了答案中的%lf 以匹配您的编辑,但请不要养成对您的问题进行此类更改的习惯。
猜你喜欢
  • 2020-04-16
  • 1970-01-01
  • 2013-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-24
相关资源
最近更新 更多