C++ 堆栈后缀符号求值与中缀计算器得到的值不同
我在用Flex开发一种简单的1文件语言时遇到了一个问题 中缀计算器表达式为: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;
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-
。RPN1 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(并修复数字模式以识别带小数点的数字)