Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 堆栈后缀符号求值与中缀计算器得到的值不同_C++_Flex Lexer - Fatal编程技术网

C++ 堆栈后缀符号求值与中缀计算器得到的值不同

C++ 堆栈后缀符号求值与中缀计算器得到的值不同,c++,flex-lexer,C++,Flex Lexer,我在用Flex开发一种简单的1文件语言时遇到了一个问题 中缀计算器表达式为:1+2*5-32,在计算器上等于-21 我的后缀计算器表达式是:12532-*+,我的计算器等于55 以下是我的Flex代码: %{ #include <cstdio> #include <cstdlib> #include <string> #include <iostream> #include <stack> using namespace std;

我在用Flex开发一种简单的1文件语言时遇到了一个问题

中缀计算器表达式为:
1+2*5-32
,在计算器上等于
-21

我的后缀计算器表达式是:
12532-*+
,我的计算器等于
55

以下是我的Flex代码:

%{
#include <cstdio>
#include <cstdlib>
#include <string>
#include <iostream>
#include <stack>

using namespace std;

stack<int> numberStack;
int a;
int b;

extern "C" int yywrap() { }
%}

%%

[ \t\n] ;
[0-9]+  numberStack.push(atoi(yytext));
"+" a = numberStack.top(); numberStack.pop(); b = numberStack.top(); numberStack.pop(); numberStack.push(a+b);
"-" a = numberStack.top(); numberStack.pop(); b = numberStack.top(); numberStack.pop(); numberStack.push(a-b);
"*" a = numberStack.top(); numberStack.pop(); b = numberStack.top(); numberStack.pop(); numberStack.push(a*b);
"/" a = numberStack.top(); numberStack.pop(); b = numberStack.top(); numberStack.pop(); numberStack.push(a/b);

%%

int main(int argc, char *argv[])
{
    yyin = fopen(argv[1], "r");
    yylex();
    fclose(yyin);
    cout << numberStack.top() << endl;
    numberStack.pop();
    return 0;
}
%{
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
堆栈编号;
INTA;
int b;
外部“C”int yywrap(){}
%}
%%
[\t\n];
[0-9]+numberStack.push(atoi(yytext));
“+”a=numberStack.top();numberStack.pop();b=numberStack.top();numberStack.pop();数字钉压(a+b);
“-”a=numberStack.top();numberStack.pop();b=numberStack.top();numberStack.pop();数字钉压(a-b);
“*”a=numberStack.top();numberStack.pop();b=numberStack.top();numberStack.pop();数字钉压(a*b);
“/”a=numberStack.top();numberStack.pop();b=numberStack.top();numberStack.pop();数字锁定按钮(a/b);
%%
int main(int argc,char*argv[])
{
yyin=fopen(argv[1],“r”);
yylex();
fclose(yyin);
cout您的代码的结果(几乎)没有问题

1+2*5-32
(根据运算符优先级的常规规则)到RPN的正确翻译是:
1 2 5*+32-
。RPN
1 2 5 32-*+
1+2*(5-32)

代码的一个问题是计算的函数与正确的函数相反。也就是说,
5 32-
返回27而不是-27(并且
32 5-
计算的是-27而不是27)。类似的问题在
/
中也会出现。(因为
+
*
是可交换的,所以问题不会被注意到)

因此,在所有的动作中,
a
b
应该颠倒

也不需要使用全局变量
a
b

"-"   { int right = numberStack.top();
        numberStack.pop();
        int left = numberStack.top();
        numberStack.pop();
        numberStack.push(left - right);
      }

显然,最好在调用
.top()之前检查堆栈是否为空

您应该使用调试器逐步检查代码。检查变量值,看看它与您想要的结果有何不同。您刚刚发现了RPN存在的原因。它明确说明了运算符绑定和顺序,而计算器需要(和)做“正确的事”。如果您做1+2*(32-5)在您的计算器中,C表示同意,将两个
int
s除以将返回一个
int
。如果您想处理浮点数,请使用一堆
double
s(并修复数字模式以识别带小数点的数字)