📄 expression.cpp
字号:
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 + -