51 std::locale ParserBase::s_locale = std::locale(std::locale::classic(),
new change_dec_sep<char_type>(
'.'));
53 bool ParserBase::g_DbgDumpCmdCode =
false;
54 bool ParserBase::g_DbgDumpStack =
false;
62 const char_type* ParserBase::c_DefaultOprt[] =
64 _T(
"<="),
_T(
">="),
_T(
"!="),
65 _T(
"=="),
_T(
"<"),
_T(
">"),
67 _T(
"/"),
_T(
"^"),
_T(
"&&"),
68 _T(
"||"),
_T(
"="),
_T(
"("),
69 _T(
")"),
_T(
"?"),
_T(
":"), 0
72 const int ParserBase::s_MaxNumOpenMPThreads = 16;
79 ParserBase::ParserBase()
198 char_type cThousandsSep = std::use_facet< change_dec_sep<char_type> >(
s_locale).thousands_sep();
212 char_type cDecSep = std::use_facet< change_dec_sep<char_type> >(
s_locale).decimal_point();
278 ss << std::dec <<
_T(
"; ") <<
sizeof(
void*)*8 <<
_T(
"BIT");
283 ss <<
_T(
"; RELEASE");
287 ss <<
_T(
"; UNICODE");
296 #ifdef MUP_USE_OPENMP 297 ss <<
_T(
"; OPENMP");
302 #if defined(MUP_MATH_EXCEPTIONS) 303 ss <<
_T(
"; MATHEXC");
361 CheckOprt(a_strName, a_Callback, a_szCharSet);
362 a_Storage[a_strName] = a_Callback;
375 if ( !a_sName.length() ||
376 (a_sName.find_first_not_of(a_szCharSet)!=string_type::npos) ||
377 (a_sName[0]>=
'0' && a_sName[0]<=
'9'))
396 if ( !a_sName.length() ||
397 (a_sName.find_first_not_of(a_szCharSet)!=string_type::npos) ||
398 (a_sName[0]>=
'0' && a_sName[0]<=
'9'))
632 case cmEND:
return -5;
753 const std::vector<token_type> &a_vArg)
const 755 if (a_vArg.back().GetCode()!=
cmSTRING)
769 case 2: valTok.
SetVal(1); a_vArg[2].
GetAsString(); a_vArg[1].GetVal(); a_vArg[0].GetVal();
break;
794 int a_iArgCount)
const 815 int iArgNumerical = iArgCount - ((funTok.
GetType()==
tpSTR) ? 1 : 0);
820 if (funTok.
GetArgCount()>=0 && iArgCount>iArgRequired)
831 std::vector<token_type> stArg;
832 for (
int i=0; i<iArgNumerical; ++i)
834 stArg.push_back( a_stVal.
pop() );
842 stArg.push_back(a_stVal.
pop());
894 a_stVal.
push( (vExpr.
GetVal()!=0) ? vVal1 : vVal2);
920 valTok2 = a_stVal.
pop(),
921 optTok = a_stOpt.
pop(),
924 if ( valTok1.GetType()!=valTok2.GetType() ||
925 (valTok1.GetType()==
tpSTR && valTok2.GetType()==
tpSTR) )
930 if (valTok2.GetCode()!=
cmVAR)
939 a_stVal.
push(resTok);
951 while (stOpt.
size() &&
1022 case cmLE: --sidx; Stack[sidx] = Stack[sidx] <= Stack[sidx+1];
continue;
1023 case cmGE: --sidx; Stack[sidx] = Stack[sidx] >= Stack[sidx+1];
continue;
1024 case cmNEQ: --sidx; Stack[sidx] = Stack[sidx] != Stack[sidx+1];
continue;
1025 case cmEQ: --sidx; Stack[sidx] = Stack[sidx] == Stack[sidx+1];
continue;
1026 case cmLT: --sidx; Stack[sidx] = Stack[sidx] < Stack[sidx+1];
continue;
1027 case cmGT: --sidx; Stack[sidx] = Stack[sidx] > Stack[sidx+1];
continue;
1028 case cmADD: --sidx; Stack[sidx] += Stack[1+sidx];
continue;
1029 case cmSUB: --sidx; Stack[sidx] -= Stack[1+sidx];
continue;
1030 case cmMUL: --sidx; Stack[sidx] *= Stack[1+sidx];
continue;
1033 #if defined(MUP_MATH_EXCEPTIONS) 1034 if (Stack[1+sidx]==0)
1037 Stack[sidx] /= Stack[1+sidx];
1044 case cmLAND: --sidx; Stack[sidx] = Stack[sidx] && Stack[sidx+1];
continue;
1045 case cmLOR: --sidx; Stack[sidx] = Stack[sidx] || Stack[sidx+1];
continue;
1051 --sidx; Stack[sidx] = *(pTok->Oprt.ptr + nOffset) = Stack[sidx + 1];
continue;
1061 if (Stack[sidx--]==0)
1062 pTok += pTok->Oprt.offset;
1066 pTok += pTok->Oprt.offset;
1077 case cmVAR: Stack[++sidx] = *(pTok->Val.ptr + nOffset);
continue;
1078 case cmVAL: Stack[++sidx] = pTok->Val.data2;
continue;
1080 case cmVARPOW2: buf = *(pTok->Val.ptr + nOffset);
1081 Stack[++sidx] = buf*buf;
1084 case cmVARPOW3: buf = *(pTok->Val.ptr + nOffset);
1085 Stack[++sidx] = buf*buf*buf;
1088 case cmVARPOW4: buf = *(pTok->Val.ptr + nOffset);
1089 Stack[++sidx] = buf*buf*buf*buf;
1092 case cmVARMUL: Stack[++sidx] = *(pTok->Val.ptr + nOffset) * pTok->Val.data + pTok->Val.data2;
1098 int iArgCount = pTok->Fun.argc;
1103 case 0: sidx += 1; Stack[sidx] = (*(
fun_type0)pTok->Fun.ptr)();
continue;
1104 case 1: Stack[sidx] = (*(
fun_type1)pTok->Fun.ptr)(Stack[sidx]);
continue;
1105 case 2: sidx -= 1; Stack[sidx] = (*(
fun_type2)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1]);
continue;
1106 case 3: sidx -= 2; Stack[sidx] = (*(
fun_type3)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2]);
continue;
1107 case 4: sidx -= 3; Stack[sidx] = (*(
fun_type4)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3]);
continue;
1108 case 5: sidx -= 4; Stack[sidx] = (*(
fun_type5)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4]);
continue;
1109 case 6: sidx -= 5; Stack[sidx] = (*(
fun_type6)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5]);
continue;
1110 case 7: sidx -= 6; Stack[sidx] = (*(
fun_type7)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6]);
continue;
1111 case 8: sidx -= 7; Stack[sidx] = (*(
fun_type8)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7]);
continue;
1112 case 9: sidx -= 8; Stack[sidx] = (*(
fun_type9)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8]);
continue;
1113 case 10:sidx -= 9; Stack[sidx] = (*(
fun_type10)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8], Stack[sidx+9]);
continue;
1118 sidx -= -iArgCount - 1;
1119 Stack[sidx] =(*(
multfun_type)pTok->Fun.ptr)(&Stack[sidx], -iArgCount);
1127 sidx -= pTok->Fun.argc -1;
1130 int iIdxStack = pTok->Fun.idx;
1133 switch(pTok->Fun.argc)
1137 case 2: Stack[sidx] = (*(
strfun_type3)pTok->Fun.ptr)(
m_vStringBuf[iIdxStack].c_str(), Stack[sidx], Stack[sidx+1]);
continue;
1145 int iArgCount = pTok->Fun.argc;
1150 case 0: sidx += 1; Stack[sidx] = (*(
bulkfun_type0 )pTok->Fun.ptr)(nOffset, nThreadID);
continue;
1151 case 1: Stack[sidx] = (*(
bulkfun_type1 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx]);
continue;
1152 case 2: sidx -= 1; Stack[sidx] = (*(
bulkfun_type2 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1]);
continue;
1153 case 3: sidx -= 2; Stack[sidx] = (*(
bulkfun_type3 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2]);
continue;
1154 case 4: sidx -= 3; Stack[sidx] = (*(
bulkfun_type4 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3]);
continue;
1155 case 5: sidx -= 4; Stack[sidx] = (*(
bulkfun_type5 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4]);
continue;
1156 case 6: sidx -= 5; Stack[sidx] = (*(
bulkfun_type6 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5]);
continue;
1157 case 7: sidx -= 6; Stack[sidx] = (*(
bulkfun_type7 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6]);
continue;
1158 case 8: sidx -= 7; Stack[sidx] = (*(
bulkfun_type8 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7]);
continue;
1159 case 9: sidx -= 8; Stack[sidx] = (*(
bulkfun_type9 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8]);
continue;
1160 case 10:sidx -= 9; Stack[sidx] = (*(
bulkfun_type10)pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8], Stack[sidx+9]);
continue;
1173 return Stack[m_nFinalResultIdx];
1177 void ParserBase::CreateRPN()
const 1179 if (!m_pTokenReader->GetExpr().length())
1195 opt = m_pTokenReader->ReadNextToken();
1203 opt.
SetIdx((
int)m_vStringBuf.size());
1210 m_vRPN.AddVar( static_cast<value_type*>(opt.
GetVar()) );
1215 m_vRPN.AddVal( opt.
GetVal() );
1220 if (m_nIfElseCounter<0)
1223 ApplyRemainingOprt(stOpt, stVal);
1224 m_vRPN.AddIfElse(
cmELSE);
1230 if (stArgCount.
empty())
1238 ApplyRemainingOprt(stOpt, stVal);
1250 ApplyRemainingOprt(stOpt, stVal);
1261 assert(stArgCount.
size());
1262 int iArgCount = stArgCount.
pop();
1266 if (iArgCount>1 && ( stOpt.
size()==0 ||
1277 stOpt.
top().GetFuncAddr()!=0)
1279 ApplyFunc(stOpt, stVal, iArgCount);
1313 while ( stOpt.
size() &&
1314 stOpt.
top().GetCode() !=
cmBO &&
1316 stOpt.
top().GetCode() !=
cmIF)
1318 int nPrec1 = GetOprtPrecedence(stOpt.
top()),
1319 nPrec2 = GetOprtPrecedence(opt);
1326 if ( (eOprtAsct==
oaRIGHT && (nPrec1 <= nPrec2)) ||
1327 (eOprtAsct==
oaLEFT && (nPrec1 < nPrec2)) )
1332 else if (nPrec1 < nPrec2)
1339 ApplyFunc(stOpt, stVal, 1);
1341 ApplyBinOprt(stOpt, stVal);
1345 m_vRPN.AddIfElse(opt.
GetCode());
1368 ApplyFunc(stOpt, stVal, 1);
1382 if (ParserBase::g_DbgDumpStack)
1384 StackDump(stVal, stOpt);
1389 if (ParserBase::g_DbgDumpCmdCode)
1392 if (m_nIfElseCounter>0)
1397 m_nFinalResultIdx = stArgCount.
top();
1398 if (m_nFinalResultIdx==0)
1401 if (stVal.
size()==0)
1407 m_vStackBuffer.resize(m_vRPN.GetMaxStackSize() * s_MaxNumOpenMPThreads);
1424 m_pParseFormula = &ParserBase::ParseCmdCode;
1425 return (this->*m_pParseFormula)();
1447 throw exception_type(a_iErrc, a_sTok, m_pTokenReader->GetExpr(), a_iPos);
1456 void ParserBase::ClearVar()
1470 varmap_type::iterator item = m_VarDef.find(a_strVarName);
1471 if (item!=m_VarDef.end())
1473 m_VarDef.erase(item);
1483 void ParserBase::ClearFun()
1496 void ParserBase::ClearConst()
1499 m_StrVarDef.clear();
1508 void ParserBase::ClearPostfixOprt()
1510 m_PostOprtDef.clear();
1519 void ParserBase::ClearOprt()
1530 void ParserBase::ClearInfixOprt()
1532 m_InfixOprtDef.clear();
1541 void ParserBase::EnableOptimizer(
bool a_bIsOn)
1543 m_vRPN.EnableOptimizer(a_bIsOn);
1554 void ParserBase::EnableDebugDump(
bool bDumpCmd,
bool bDumpStack)
1556 ParserBase::g_DbgDumpCmdCode = bDumpCmd;
1557 ParserBase::g_DbgDumpStack = bDumpStack;
1570 void ParserBase::EnableBuiltInOprt(
bool a_bIsOn)
1572 m_bBuiltInOp = a_bIsOn;
1581 bool ParserBase::HasBuiltInOprt()
const 1583 return m_bBuiltInOp;
1591 return m_pTokenReader->GetArgSep();
1600 m_pTokenReader->SetArgSep(
cArgSep);
1615 while ( !stVal.
empty() )
1625 while ( !stOprt.empty() )
1627 if (stOprt.top().GetCode()<=
cmASSIGN)
1630 << ParserBase::c_DefaultOprt[stOprt.top().GetCode()]
1635 switch(stOprt.top().GetCode())
1640 << stOprt.top().GetAsString()
1641 <<
_T(
"\"\n");
break;
1643 << stOprt.top().GetAsString()
1644 <<
_T(
"\"\n");
break;
1646 << stOprt.top().GetAsString()
1647 <<
_T(
"\"\n");
break;
1649 << stOprt.top().GetAsString()
1650 <<
_T(
"\"\n");
break;
1659 default:
mu::console() << stOprt.top().GetCode() <<
_T(
" ");
break;
1678 (this->*m_pParseFormula)();
1679 nStackSize = m_nFinalResultIdx;
1682 return &m_vStackBuffer[1];
1692 int ParserBase::GetNumResults()
const 1694 return m_nFinalResultIdx;
1715 return (this->*m_pParseFormula)();
1735 #ifdef MUP_USE_OPENMP 1737 #ifdef DEBUG_OMP_STUFF 1738 int *pThread =
new int[nBulkSize];
1739 int *pIdx =
new int[nBulkSize];
1742 int nMaxThreads =
std::min(omp_get_max_threads(), s_MaxNumOpenMPThreads);
1743 int nThreadID = 0, ct = 0;
1744 omp_set_num_threads(nMaxThreads);
1746 #pragma omp parallel for schedule(static, nBulkSize/nMaxThreads) private(nThreadID) 1747 for (i=0; i<nBulkSize; ++i)
1749 nThreadID = omp_get_thread_num();
1750 results[i] = ParseCmdCodeBulk(i, nThreadID);
1752 #ifdef DEBUG_OMP_STUFF 1753 #pragma omp critical 1755 pThread[ct] = nThreadID;
1762 #ifdef DEBUG_OMP_STUFF 1763 FILE *pFile = fopen(
"bulk_dbg.txt",
"w");
1764 for (i=0; i<nBulkSize; ++i)
1766 fprintf(pFile,
"idx: %d thread: %d \n", pIdx[i], pThread[i]);
1776 for (i=0; i<nBulkSize; ++i)
1778 results[i] = ParseCmdCodeBulk(i, 0);