逆波兰式的产生及计算
本实验属选做实验,采用c++实现,利用Windows API制作了简易的UI界面。
本实验属于所有编译原理实验中最容易实现的一个,利用STL数据结构和函数可以快速完成该实验。
项目说明:
利用菜单中新建文件、打开文件、保存文件、关闭文件实现基本的待分析文本的读入和保存。
计算和逆波兰式的转换均使用 产生逆波兰式 菜单选项即可。
如需自定义算术符号优先级,请首先选择菜单中的设置优先级选项,之后请按照每行符号优先级相同,不同行从上到下优先级递减的格式进行输入,如本程序初始默认优先级格式为:
*/
±
()
其余功能、示例截图、代码下载请见GitHub页面:逆波兰式的产生及计算
部分核心代码:
void makeRPNclass::makeRPN() {
indexlevel = 0;
SendMessage(Output_Bind_RichTextDialogclass, LVM_DELETEALLITEMS, 0, 0);
string outputstring = "";//分析得到的结果串
string loutputstring = "";//分析得到的结果串
string reststring = "";
deque<int> numstack; //算术运算栈
int tmpnum = 0;
deque<char> symbolstack;
symbolstack.push_back('#');
for (int i = 0; i < Input_Bind_RichTextDialogclass.RichTextDialog_GetLength(); i++) {
reststring += string{ Input_Bind_RichTextDialogclass.RichTextDialog_GetChar(i) };
}
reststring += "#";
//outputaline(*reststring.begin(), reststring.substr(1), symbolstack, outputstring);
short lastflag = -1;
while (reststring.length()>1) {
auto i = reststring.begin();
if (Symbolset.find(*i)!=Symbolset.end()) {
if (lastflag == 3) {
numstack.push_back(tmpnum);
_itoa_s(tmpnum, numbertmpbuffer, 10);
outputstring += string{ numbertmpbuffer };
outputstring += " ";
tmpnum = 0;
}
if (privilegemap[make_pair(*i, symbolstack.back())] == RPN_RELATION_HIGH) {
outputaline(*i, reststring.substr(1), symbolstack, loutputstring);
loutputstring = outputstring;
symbolstack.push_back(*i);
reststring.erase(i);
lastflag = 1;
}
else if (privilegemap[make_pair(*i, symbolstack.back())] == RPN_RELATION_EQUAL) { //相等则互相抵消
outputaline(*i, reststring.substr(1), symbolstack, loutputstring);
loutputstring = outputstring;
symbolstack.pop_back();
reststring.erase(i);
lastflag = 2;
}
else {//== RPN_RELATION_LOW
outputaline(*i, reststring.substr(1), symbolstack, loutputstring);
loutputstring = outputstring;
outputstring += symbolstack.back();
if (numstack.size() > 1) {
int tmp2 = numstack.back();
numstack.pop_back();
int tmp1 = numstack.back();
numstack.pop_back();
int tmpresult;
if (symbolstack.back() == '+')
tmpresult = tmp1 + tmp2;
else if (symbolstack.back() == '-')
tmpresult = tmp1 - tmp2;
else if (symbolstack.back() == '*')
tmpresult = tmp1 * tmp2;
else if (symbolstack.back() == '/')
tmpresult = tmp1 / tmp2;
numstack.push_back(tmpresult);
int deletelength = (int)log10(tmp2) + 2 + (int)log10(tmp1) + 2 + 1/*strlen(symbolstack.back())*/;
while(deletelength--)
outputstring.erase(outputstring.length() - 1, outputstring.length());
_itoa_s(tmpresult, numbertmpbuffer, 10);
outputstring += string{ numbertmpbuffer };
outputstring += " ";
}
symbolstack.pop_back();
lastflag = 4;
//symbolstack.push_back(*i);
}
}
else {
if (*i <= '9' && *i >= '0') {
if (lastflag == 3) {
tmpnum = 10 * tmpnum + (*i - '0');
}
else {
tmpnum = *i - '0';
}
lastflag = 3;
reststring.erase(i);
}
else {
if (lastflag == 3) {
numstack.push_back(tmpnum);
_itoa_s(tmpnum, numbertmpbuffer, 10);
outputstring += string{ numbertmpbuffer };
outputstring += " ";
tmpnum = 0;
}
outputstring += *i;
outputaline(*i, reststring.substr(1), symbolstack, loutputstring);
loutputstring = outputstring;
reststring.erase(i);
}
}
}
//outputaline(' ', " ", symbolstack, loutputstring);
//loutputstring.substr(0, loutputstring.length() - 1);
while(symbolstack.size()>1){
auto i = symbolstack.back();
loutputstring = outputstring;
outputstring += i;
if (lastflag == 3) {
numstack.push_back(tmpnum);
_itoa_s(tmpnum, numbertmpbuffer, 10);
outputstring += string{ numbertmpbuffer };
outputstring += " ";
tmpnum = 0;
}
lastflag = -1;
if (numstack.size() > 1) {
int tmp2 = numstack.back();
numstack.pop_back();
int tmp1 = numstack.back();
numstack.pop_back();
int tmpresult;
if (symbolstack.back() == '+')
tmpresult = tmp1 + tmp2;
else if (symbolstack.back() == '-')
tmpresult = tmp1 - tmp2;
else if (symbolstack.back() == '*')
tmpresult = tmp1 * tmp2;
else if (symbolstack.back() == '/')
tmpresult = tmp1 / tmp2;
numstack.push_back(tmpresult);
int deletelength = (int)log10(tmp2) + 2 + (int)log10(tmp1) + 2 + 1/*strlen(symbolstack.back())*/;
while (deletelength--)
outputstring.erase(outputstring.length() - 1, outputstring.length());
_itoa_s(tmpresult, numbertmpbuffer, 10);
outputstring += string{ numbertmpbuffer };
outputstring += " ";
}
outputaline(' ', " ", symbolstack, loutputstring);
symbolstack.pop_back();
}
loutputstring = outputstring;
outputaline(' ', " ", symbolstack, loutputstring);
}