⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 expression.cpp

📁 能计算如下表达式:x=3 y=4 z=x^2+sin(y)
💻 CPP
📖 第 1 页 / 共 2 页
字号:
					tokenStack.pop();
					currTok.type = E;
					break;
				}
			case 208://T -> T*F
				{				
					currTok = tokenStack.top();
					tokenStack.pop(); tokenStack.pop();
					t1 = tokenStack.top();
					tokenStack.pop();
					currTok.value = t1.value * currTok.value;
					currTok.type = T;
					break;
				}
			case 209://T -> T/F
				{				
					currTok = tokenStack.top();
					tokenStack.pop(); tokenStack.pop();
					t1 = tokenStack.top();
					tokenStack.pop();
					currTok.value = t1.value / currTok.value;
					currTok.type = T;
					break;
				}
			case 210://T -> F
				{				
					currTok = tokenStack.top();
					tokenStack.pop();
					currTok.type = T;
					break;
				}
			case 211://F -> (E)
				{	
					t1 = tokenStack.top();
					tokenStack.pop();
					currTok = tokenStack.top();
					tokenStack.pop();
					tokenStack.pop();
					currTok.position = t1.position;
					currTok.type = F;
					break;
				}
			case 212://F -> ID
				{	
					currTok = tokenStack.top();	
					tokenStack.pop();
					if(idMap.count(currTok.str) == 0)
					{
						ostringstream buf;
						buf <<"在表达式的第" <<currTok.position+1 <<"个字符处出现了没有定义的标识符:  "
							<<currTok.str.c_str();
						resultStr = buf.str();
						parseSucc = false;
					}
					else currTok.value = idMap[currTok.str];
					currTok.type = F;
					break;
				}
			case 213://F -> NUM
				{				
					currTok = tokenStack.top();
					tokenStack.pop();
					currTok.type = F;
					break;
				}
			case 214://F -> -F
				{				
					currTok = tokenStack.top();
					tokenStack.pop();
					tokenStack.pop();
					currTok.value = - currTok.value;
					currTok.type = F;
					break;
				}
			case 215://F -> FUNC(E)
				{
					t2 = tokenStack.top();
					tokenStack.pop();
					currTok = tokenStack.top();
					tokenStack.pop();
					tokenStack.pop();
					t1 = tokenStack.top();
					tokenStack.pop();
					if( t1.str == "abs") currTok.value = fabs(currTok.value);
					else if (t1.str == "sin")
						currTok.value = sin(currTok.value);
					else if (t1.str == "cos")
						currTok.value = cos(currTok.value);
					else if (t1.str == "tan")
						currTok.value = tan(currTok.value);
					else if (t1.str == "sinh")
						currTok.value = sinh(currTok.value);
					else if (t1.str == "cosh")
						currTok.value = cosh(currTok.value);
					else if (t1.str == "tanh")
						currTok.value = tanh(currTok.value);
					else if (t1.str == "asin" || t1.str == "acos")
					{
						if(currTok.value>1 || currTok.value<-1)
						{
							ostringstream buf;
							buf <<"在表达式的第" <<currTok.position+1 
								<<"个字符处出现数学错误:asin和acos的定义域为[-1,1]!";
							resultStr = buf.str();
							parseSucc = false;
						}
						else if(t1.str == "asin") currTok.value = asin(currTok.value);
						else currTok.value = tan(currTok.value);
					}
					else if (t1.str == "atan")
						currTok.value = atan(currTok.value);
					else if (t1.str == "exp")
					{
						if ((currTok.value < -ExpLimit) || (currTok.value > ExpLimit))
						{
							ostringstream buf;
							buf <<"在表达式的第" <<currTok.position+1 
								<<"个字符处出现数学错误:指数超过范围[-11356,11356]";
							resultStr = buf.str();						
							parseSucc = false;
						}
						else	currTok.value = exp(currTok.value);
					}
					else if (t1.str=="ln" || t1.str=="log")
					{
						if (currTok.value <= 0)
						{
							ostringstream buf;
							buf <<"在表达式的第" <<currTok.position+1 
								<<"个字符处出现数学错误:幂小于0!";
							resultStr = buf.str();	
							parseSucc = false;
						}
						else
							currTok.value = log(currTok.value);
					}
					else if (t1.str=="log10" || t1.str=="lg")
					{
						if (currTok.value <= 0)
						{
							ostringstream buf;
							buf <<"在表达式的第" <<currTok.position+1 
								<<"个字符处出现数学错误:幂小于0";
							resultStr = buf.str();	
							parseSucc = false;
						}
						else
							currTok.value = log10(currTok.value);
					}				
					else if (t1.str == "sqr")
					{
						if ((currTok.value < 0))// then
						{
							ostringstream buf;
							buf <<"在表达式的第" <<currTok.position+1 <<"个字符处出现数学错误:对负数开方!";
							resultStr = buf.str();	
							parseSucc = false;
						}
						else
							currTok.value = sqrt(currTok.value);
					}
					else if (t1.str == "trunc")	currTok.value = (int)(currTok.value);
					currTok.position = t2.position;
					currTok.type = F;
					break;
				}
			case 216://F -> F^F
				{
					t2 = tokenStack.top();
					tokenStack.pop(); tokenStack.pop();
					t1 = tokenStack.top();
					tokenStack.pop();
					if (t1.value < 0.0)
					{
						t2.value = (int) t2.value;
						if(t2.value/2) currTok.value = -exp(t2.value * log(-t1.value));
						else currTok.value = exp(t2.value * log(-t1.value));
					}
					else if ((t2.value * log(t1.value) < -ExpLimit) || 
						(t2.value * log(t1.value) > ExpLimit))
					{
						ostringstream buf;
						buf <<"在表达式的第" <<currTok.position+1 
							<<"个字符处出现数学错误:指数超过范围[-11356,11356]";
						resultStr = buf.str();	
						parseSucc = false;
					}
					else currTok.value = exp(t2.value * log(t1.value));
					currTok.type = F;
					break;
				}


			}

			currTok.state =action[tokenStack.top().state][currTok.type];
			if(currTok.state == -1)
			{//语法错误	
				ostringstream buf;
			if(currTok.type == EOL) buf<<"表达式非法结束,可能缺少括号 ),或以操作符+,*,^,(等结尾.";
			else buf <<"在表达式的第" <<currTok.position+1 <<"个字符处出现了不合语法的符号:  "
						<<typetable[currTokTypes];
				resultStr = buf.str();
				parseSucc = false;
			}
			tokenStack.push(currTok);
			if(parseSucc)
			{	
				currTok = tokenQue.front();
				currTokTypes = currTok.type;
				}
		}

		if(lr == -10)
		{//分析完成
			accepted = false;
			ostringstream buf;
			buf <<tokenStack.top().str.c_str() <<" = " <<tokenStack.top().value;
			resultStr = buf.str();
		}
	}
	
	//清除单词流队列和标识符map
	if(!tokenQue.empty()) tokenQue.clear();
}

double Expression::getId(string idStr)
{
	return idMap[idStr];
}

string Expression::getResult()
{
	string res;
	if(!parseSucc)
	{
		res = "错误! ";
		res = res +resultStr;
	}
	else
	{
		res = resultStr;
	}
	return res;
}

 int Expression::action[32][18]={//LR分析表;表示在状态i时遇到各种符号时所采取的动作
	//状态\符号 PLU MIN TIM DIV EXP OPA CPA	SEM EQU NUM FUN ID EOL  S   A   E   T   F
	/*0*/  {	-1,111,	-1,	-1,	-1,116, -1,	-1,	-1,108,109,105, -1,  1,	4,	31,	12,	21},
	/*1*/  {	-1,	-1,	-1,	-1,	-1,	-1,	-1,102, -1,	-1,	-1,	-1,-10, -1,	-1,	-1,	-1,	-1},
	/*2*/  {	-1,111,	-1,	-1,	-1,116,	-1,	-1,	-1,108,109,105, -1,	-1,	 3,	31,	12,	21},
	/*3*/  {	-1,	-1,	-1,	-1,	-1,	-1,	-1,202, -1,	-1,	-1,	-1,202, -1,	-1,	-1,	-1,	-1},
	/*4*/  {	-1,	-1,	-1,	-1,	-1,	-1,	-1,203, -1,	-1,	-1,	-1,203, -1,	-1,	-1,	-1,	-1},
	/*5*/  {   212,212,212,212,212,	-1,212,212,106, -1,	-1,	-1,212, -1,	-1,	-1,	-1,	-1},
	/*6*/  {	-1,111, -1,	-1,	-1,116, -1,	-1,	-1,108,109,107, -1,	-1,	-1,	13,	12,	21},
	/*7*/  {   212,212,212,212,212, -1,212,212, -1,	-1,	-1,	-1,212, -1,	-1,	-1,	-1,	-1},
	/*8*/  {   213,213,213,213,213, -1,213,213, -1,	-1,	-1,	-1,213, -1,	-1,	-1,	-1,	-1},
	/*9*/  {	-1,	-1,	-1,	-1,	-1,110, -1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1},
	/*10*/ {	-1,111, -1,	-1,	-1,116, -1,	-1,	-1,108,109,107,-1,	-1,	-1,	29,	12,	21},
	/*11*/ {	-1,111, -1,	-1,	-1,116, -1,	-1,	-1,108,109,107,-1,	-1,	-1,	-1,	-1,	19},
	/*12*/ {   207,207,123,124, -1,	-1,207,207, -1,	-1,	-1,	-1,207, -1,	-1,	-1,	-1,	-1},
	/*13*/ {   114,115, -1,	-1,	-1,	-1,	-1,204, -1,	-1,	-1,	-1,204, -1,	-1,	-1,	-1,	-1},
	/*14*/ {	-1,111, -1,	-1,	-1,116, -1,	-1,	-1,108,109,107, -1,	-1,	-1,	-1,	22,	21},
	/*15*/ {	-1,111, -1,	-1,	-1,116, -1,	-1,	-1,108,109,107, -1,	-1,	-1,	-1,	25,	21},
	/*16*/ {	-1,111, -1,	-1,	-1,116, -1,	-1,	-1,108,109,107, -1,	-1,	-1,	17,	12,	21},
	/*17*/ {   114,115, -1,	-1,	-1,	-1,118, -1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1},
	/*18*/ {   211,211,211,211,211, -1,211,211, -1,	-1,	-1,	-1,211, -1,	-1,	-1,	-1,	-1},
	/*19*/ {   214,214,214,214,120, -1,214,214, -1,	-1,	-1,	-1,214, -1,	-1,	-1,	-1,	-1},
	/*20*/ {	-1,111, -1,	-1,	-1,116, -1,	-1, -1,108,109,107, -1,	-1,	-1,	-1,	-1,	28},
	/*21*/ {   210,210,210,210,120, -1,210,210, -1,	-1,	-1,	-1,210, -1,	-1,	-1,	-1,	-1},
	/*22*/ {   205,205,123,124, -1,	-1,205,205, -1,	-1,	-1,	-1,205, -1,	-1,	-1,	-1,	-1},
	/*23*/ {	-1,111, -1,	-1,	-1,116, -1,	-1,	-1,108,109,107, -1,	-1,	-1,	-1,	-1,	26},
	/*24*/ {	-1,111, -1,	-1,	-1,116, -1,	-1,	-1,108,109,107, -1,	-1,	-1,	-1,	-1,	27},
	/*25*/ {   206,206,123,124, -1,	-1,206,206, -1,	-1,	-1,	-1,206, -1,	-1,	-1,	-1,	-1},
	/*26*/ {   208,208,208,208,120, -1,208,208, -1,	-1,	-1,	-1,208, -1,	-1,	-1,	-1,	-1},
	/*27*/ {   209,209,209,209,120, -1,209,209, -1,	-1,	-1,	-1,209, -1,	-1,	-1,	-1,	-1},
	/*28*/ {   216,216,216,216,216, -1,216,216, -1,	-1,	-1,	-1,216, -1,	-1,	-1,	-1,	-1},
	/*29*/ {   114,115, -1,	-1,	-1,	-1,130, -1,	-1,	-1,	-1,	-1,	-1, -1,	-1,	-1,	-1,	-1},
	/*30*/ {   215,215,215,215,215, -1,215,215, -1,	-1,	-1,	-1,215, -1,	-1,	-1,	-1,	-1},
	/*31*/ {   114,115, -1, -1, -1,	-1, -1,200, -1,	-1,	-1,	-1,200, -1,	-1,	-1,	-1,	-1}};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -