📄 simpleexpr.cpp
字号:
// 嵌入式表达式代码
// 作者: Janhail Luo
// 最后整理: 2003-03-03
//////////////////////////////////////////////////////////////////////
#include "ParseStr.h"
#include "SimpleExpr.h"
#include <stack>
using namespace std;
#define DEBUG_OUTPUT 1
#if DEBUG_OUTPUT==1
#include <list>
#include "stdio.h"
#endif
int SimpleExpression(char* lpExpr)
{
#if DEBUG_OUTPUT==1
list<char> listOpr;
list<int> listNum;
int iOprCnt = 1;
listOpr.push_back('#');
#endif
// 操作符堆栈,用于保存操作符
stack<char> stackOpr;
// 操作数堆栈,用于保存操作数
stack<int> stackNum;
char *pCur, *pOpr, cOpr;
int iOpr, iNum1, iNum2;
char szSymbol[30];
// 操作符列表
char* szOpr = "+-*/()#";
// 操作符优先级别
char PRI[7][7] = {
{'>','>','<','<','<','>','>'},
{'>','>','<','<','<','>','>'},
{'>','>','>','>','<','>','>'},
{'>','>','>','>','<','>','>'},
{'<','<','<','<','<','=','E'},
{'>','>','>','>','E','>','>'},
{'<','<','<','<','<','E','='}};
// 开始解析
pCur = lpExpr;
// 把表达式开始标志压入操作符堆栈
stackOpr.push('#');
while (1)
{
#if DEBUG_OUTPUT==1
list<char>::iterator itOpr;
list<int>::iterator itNum;
printf("%-3d ", iOprCnt ++);
szSymbol[0] = 0;
for (itOpr=listOpr.begin(); itOpr!=listOpr.end(); itOpr++)
{
sprintf(szSymbol+strlen(szSymbol), "%c ", *itOpr);
}
printf("%-15s ", szSymbol);
szSymbol[0] = 0;
for (itNum=listNum.begin(); itNum!=listNum.end(); itNum++)
{
sprintf(szSymbol+strlen(szSymbol), "%d ", *itNum);
}
printf("%-15s %15s#\n", szSymbol, pCur);
#endif
// 表达式结束并且操作符堆栈里面没有操作符的时候就结束分析
if (!(*pCur!=0 || stackOpr.top()!='#'))
break;
cOpr = *pCur;
// 程序中把字符串结束标志表示成表达式结束标志
if (cOpr==0) cOpr = '#';
// 查找是否在操作符列表中
pOpr = strchr(szOpr, cOpr);
// 如果不在列表中就表示是操作数
if (pOpr==0)
{
// 取得一个Symbol,在这个表达式里我们默认所有的操作数都是整数
pCur = GetSymbol(pCur, szSymbol);
// 把操作数压入堆栈
stackNum.push(atoi(szSymbol));
#if DEBUG_OUTPUT==1
listNum.push_back(atoi(szSymbol));
#endif
}else
{
switch(PRI[strchr(szOpr,
stackOpr.top())-szOpr][pOpr-szOpr])
{
case '<': // 小于
// 把操作符压入操作符堆栈
stackOpr.push(cOpr);
#if DEBUG_OUTPUT==1
listOpr.push_back(cOpr);
#endif
pCur ++;
break;
case '=': // 等于
// 操作符出堆
stackOpr.pop();
#if DEBUG_OUTPUT==1
listOpr.pop_back();
#endif
pCur ++;
break;
case '>': // 大于
// 从操作符堆栈中取出操作符
iOpr = stackOpr.top();
stackOpr.pop();
#if DEBUG_OUTPUT==1
listOpr.pop_back();
#endif
// 从操作数堆栈中取出第一个操作数
iNum1 = stackNum.top();
stackNum.pop();
#if DEBUG_OUTPUT==1
listNum.pop_back();
#endif
// 从操作数堆栈中取出第二个操作数
iNum2 = stackNum.top();
stackNum.pop();
#if DEBUG_OUTPUT==1
listNum.pop_back();
#endif
// 根据操作符计算结果
switch (iOpr)
{
case '+': iNum2 += iNum1;break;
case '-': iNum2 -= iNum1;break;
case '*': iNum2 *= iNum1;break;
case '/': iNum2 /= iNum1;break;
}
// 把计算出来的结果压入操作数堆栈
stackNum.push(iNum2);
#if DEBUG_OUTPUT==1
listNum.push_back(iNum2);
#endif
break;
case 'E':
return -1; // error
}
}
}
// 返回结果
return stackNum.top();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -