40 #pragma warning(disable : 26812)
72 ParserTokenReader& ParserTokenReader::operator=(
const ParserTokenReader& a_Reader)
74 if (&a_Reader !=
this)
86 void ParserTokenReader::Assign(
const ParserTokenReader& a_Reader)
88 m_pParser = a_Reader.m_pParser;
89 m_strFormula = a_Reader.m_strFormula;
90 m_iPos = a_Reader.m_iPos;
91 m_iSynFlags = a_Reader.m_iSynFlags;
93 m_UsedVar = a_Reader.m_UsedVar;
94 m_pFunDef = a_Reader.m_pFunDef;
95 m_pConstDef = a_Reader.m_pConstDef;
96 m_pVarDef = a_Reader.m_pVarDef;
97 m_pStrVarDef = a_Reader.m_pStrVarDef;
98 m_pPostOprtDef = a_Reader.m_pPostOprtDef;
99 m_pInfixOprtDef = a_Reader.m_pInfixOprtDef;
100 m_pOprtDef = a_Reader.m_pOprtDef;
101 m_bIgnoreUndefVar = a_Reader.m_bIgnoreUndefVar;
102 m_vIdentFun = a_Reader.m_vIdentFun;
103 m_pFactory = a_Reader.m_pFactory;
104 m_pFactoryData = a_Reader.m_pFactoryData;
105 m_bracketStack = a_Reader.m_bracketStack;
106 m_cArgSep = a_Reader.m_cArgSep;
107 m_fZero = a_Reader.m_fZero;
108 m_lastTok = a_Reader.m_lastTok;
121 :m_pParser(a_pParent)
125 , m_bIgnoreUndefVar(false)
127 , m_pPostOprtDef(nullptr)
128 , m_pInfixOprtDef(nullptr)
129 , m_pOprtDef(nullptr)
130 , m_pConstDef(nullptr)
131 , m_pStrVarDef(nullptr)
133 , m_pFactory(nullptr)
134 , m_pFactoryData(nullptr)
143 SetParent(m_pParser);
158 ptr->SetParent(a_pParent);
159 return ptr.release();
170 void ParserTokenReader::AddValIdent(
identfun_type a_pCallback)
178 m_vIdentFun.push_front(a_pCallback);
182 void ParserTokenReader::SetVarCreator(
facfun_type a_pFactory,
void* pUserData)
184 m_pFactory = a_pFactory;
185 m_pFactoryData = pUserData;
225 m_strFormula = a_strFormula;
240 m_bIgnoreUndefVar = bIgnore;
255 m_iSynFlags = sfSTART_OF_LINE;
256 m_bracketStack = std::stack<int>();
267 const char_type* szFormula = m_strFormula.c_str();
271 while (szFormula[m_iPos] > 0 && szFormula[m_iPos] <= 0x20)
276 return SaveBeforeReturn(tok);
280 return SaveBeforeReturn(tok);
284 return SaveBeforeReturn(tok);
288 return SaveBeforeReturn(tok);
292 return SaveBeforeReturn(tok);
296 return SaveBeforeReturn(tok);
300 return SaveBeforeReturn(tok);
303 if (IsStrVarTok(tok))
304 return SaveBeforeReturn(tok);
308 return SaveBeforeReturn(tok);
311 if (IsInfixOpTok(tok))
312 return SaveBeforeReturn(tok);
315 if (IsPostOpTok(tok))
316 return SaveBeforeReturn(tok);
325 if ((m_bIgnoreUndefVar || m_pFactory) && IsUndefVarTok(tok))
326 return SaveBeforeReturn(tok);
333 auto iEnd = ExtractToken(m_pParser->
ValidNameChars(), strTok, (std::size_t)m_iPos);
342 void ParserTokenReader::SetParent(
ParserBase* a_pParent)
344 m_pParser = a_pParent;
345 m_pFunDef = &a_pParent->m_FunDef;
346 m_pOprtDef = &a_pParent->m_OprtDef;
347 m_pInfixOprtDef = &a_pParent->m_InfixOprtDef;
348 m_pPostOprtDef = &a_pParent->m_PostOprtDef;
349 m_pVarDef = &a_pParent->m_VarDef;
350 m_pStrVarDef = &a_pParent->m_StrVarDef;
351 m_pConstDef = &a_pParent->m_ConstDef;
363 int ParserTokenReader::ExtractToken(
const char_type* a_szCharSet,
string_type& a_sTok, std::size_t a_iPos)
const
365 auto iEnd = m_strFormula.find_first_not_of(a_szCharSet, a_iPos);
367 if (iEnd == string_type::npos)
368 iEnd = m_strFormula.length();
372 a_sTok =
string_type(m_strFormula.begin() + a_iPos, m_strFormula.begin() + iEnd);
385 int ParserTokenReader::ExtractOperatorToken(
string_type& a_sTok, std::size_t a_iPos)
const
388 auto iEnd = m_strFormula.find_first_not_of(m_pParser->
ValidOprtChars(), a_iPos);
389 if (iEnd == string_type::npos)
390 iEnd = m_strFormula.length();
395 a_sTok =
string_type(m_strFormula.begin() + a_iPos, m_strFormula.begin() + iEnd);
402 return ExtractToken(
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", a_sTok, (std::size_t)a_iPos);
411 bool ParserTokenReader::IsBuiltIn(token_type& a_Tok)
414 *
const szFormula = m_strFormula.c_str();
418 for (
int i = 0; pOprtDef[i]; i++)
420 std::size_t len(std::char_traits<char_type>::length(pOprtDef[i]));
443 if (i ==
cmASSIGN && m_iSynFlags & noASSIGN)
447 if (m_iSynFlags & noOPT)
452 if (IsInfixOpTok(a_Tok))
458 m_iSynFlags = noBC | noOPT | noARG_SEP | noPOSTOP | noASSIGN | noIF | noELSE | noEND;
462 if (m_iSynFlags & noBO)
466 m_iSynFlags = noOPT | noEND | noARG_SEP | noPOSTOP | noASSIGN | noIF | noELSE;
468 m_iSynFlags = noBC | noOPT | noEND | noARG_SEP | noPOSTOP | noASSIGN | noIF | noELSE;
470 m_bracketStack.push(
cmBO);
474 if (m_iSynFlags & noBC)
477 m_iSynFlags = noBO | noVAR | noVAL | noFUN | noINFIXOP | noSTR | noASSIGN;
479 if (!m_bracketStack.empty())
480 m_bracketStack.pop();
486 if (m_iSynFlags & noELSE)
487 Error(ecUNEXPECTED_CONDITIONAL, m_iPos, pOprtDef[i]);
489 m_iSynFlags = noBC | noPOSTOP | noEND | noOPT | noIF | noELSE | noSTR;
493 if (m_iSynFlags & noIF)
494 Error(ecUNEXPECTED_CONDITIONAL, m_iPos, pOprtDef[i]);
496 m_iSynFlags = noBC | noPOSTOP | noEND | noOPT | noIF | noELSE | noSTR;
504 a_Tok.Set((
ECmdCode)i, pOprtDef[i]);
513 bool ParserTokenReader::IsArgSep(token_type& a_Tok)
515 const char_type* szFormula = m_strFormula.c_str();
517 if (szFormula[m_iPos] == m_cArgSep)
521 szSep[0] = m_cArgSep;
524 if (m_iSynFlags & noARG_SEP)
527 m_iSynFlags = noBC | noOPT | noEND | noARG_SEP | noPOSTOP | noASSIGN;
544 bool ParserTokenReader::IsEOF(token_type& a_Tok)
546 const char_type* szFormula = m_strFormula.c_str();
549 if (!szFormula[m_iPos] )
551 if (m_iSynFlags & noEND)
554 if (!m_bracketStack.empty())
569 bool ParserTokenReader::IsInfixOpTok(token_type& a_Tok)
577 funmap_type::const_reverse_iterator it = m_pInfixOprtDef->rbegin();
578 for (; it != m_pInfixOprtDef->rend(); ++it)
580 if (sTok.find(it->first) != 0)
583 a_Tok.Set(it->second, it->first);
584 m_iPos += (int)it->first.length();
586 if (m_iSynFlags & noINFIXOP)
589 m_iSynFlags = noPOSTOP | noINFIXOP | noOPT | noBC | noSTR | noASSIGN | noARG_SEP;
614 bool ParserTokenReader::IsFunTok(token_type& a_Tok)
617 auto iEnd = ExtractToken(m_pParser->
ValidNameChars(), strTok, (std::size_t)m_iPos);
621 funmap_type::const_iterator item = m_pFunDef->find(strTok);
622 if (item == m_pFunDef->end())
626 const char_type* szFormula = m_strFormula.c_str();
627 if (szFormula[iEnd] !=
'(')
630 a_Tok.Set(item->second, strTok);
633 if (m_iSynFlags & noFUN)
634 Error(
ecUNEXPECTED_FUN, m_iPos - (
int)a_Tok.GetAsString().length(), a_Tok.GetAsString());
636 m_iSynFlags = noANY ^ noBO;
645 bool ParserTokenReader::IsOprt(token_type& a_Tok)
647 const char_type*
const szExpr = m_strFormula.c_str();
650 auto iEnd = ExtractOperatorToken(strTok, (std::size_t)m_iPos);
668 funmap_type::const_reverse_iterator it = m_pOprtDef->rbegin();
669 for (; it != m_pOprtDef->rend(); ++it)
672 if (sID ==
string_type(szExpr + m_iPos, szExpr + m_iPos + sID.length()))
674 a_Tok.Set(it->second, strTok);
677 if (m_iSynFlags & noOPT)
683 if (IsInfixOpTok(a_Tok))
694 m_iPos += (int)sID.length();
695 m_iSynFlags = noBC | noOPT | noARG_SEP | noPOSTOP | noEND | noASSIGN;
705 bool ParserTokenReader::IsPostOpTok(token_type& a_Tok)
714 if (m_iSynFlags & noPOSTOP)
728 auto iEnd = ExtractToken(m_pParser->
ValidOprtChars(), sTok, (std::size_t)m_iPos);
733 funmap_type::const_reverse_iterator it = m_pPostOprtDef->rbegin();
734 for (; it != m_pPostOprtDef->rend(); ++it)
736 if (sTok.find(it->first) != 0)
739 a_Tok.Set(it->second, sTok);
740 m_iPos += (int)it->first.length();
742 m_iSynFlags = noVAL | noVAR | noFUN | noBO | noPOSTOP | noSTR | noASSIGN;
757 bool ParserTokenReader::IsValTok(token_type& a_Tok)
767 auto iEnd = ExtractToken(m_pParser->
ValidNameChars(), strTok, (std::size_t)m_iPos);
770 valmap_type::const_iterator item = m_pConstDef->find(strTok);
771 if (item != m_pConstDef->end())
774 a_Tok.SetVal(item->second, strTok);
776 if (m_iSynFlags & noVAL)
779 m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR | noASSIGN;
786 std::list<identfun_type>::const_iterator item = m_vIdentFun.begin();
787 for (item = m_vIdentFun.begin(); item != m_vIdentFun.end(); ++item)
790 if ((*item)(m_strFormula.c_str() + m_iPos, &m_iPos, &fVal) == 1)
793 strTok.assign(m_strFormula.c_str(), iStart, (std::size_t)m_iPos - iStart);
795 if (m_iSynFlags & noVAL)
798 a_Tok.SetVal(fVal, strTok);
799 m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR | noASSIGN;
812 bool ParserTokenReader::IsVarTok(token_type& a_Tok)
814 if (m_pVarDef->empty())
818 auto iEnd = ExtractToken(m_pParser->
ValidNameChars(), strTok, (std::size_t)m_iPos);
822 varmap_type::const_iterator item = m_pVarDef->find(strTok);
823 if (item == m_pVarDef->end())
826 if (m_iSynFlags & noVAR)
829 m_pParser->OnDetectVar(&m_strFormula, m_iPos, iEnd);
832 a_Tok.SetVar(item->second, strTok);
833 m_UsedVar[item->first] = item->second;
835 m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR;
843 bool ParserTokenReader::IsStrVarTok(token_type& a_Tok)
845 if (!m_pStrVarDef || m_pStrVarDef->empty())
849 auto iEnd = ExtractToken(m_pParser->
ValidNameChars(), strTok, (std::size_t)m_iPos);
853 strmap_type::const_iterator item = m_pStrVarDef->find(strTok);
854 if (item == m_pStrVarDef->end())
857 if (m_iSynFlags & noSTR)
861 if (!m_pParser->m_vStringVarBuf.size())
864 a_Tok.SetString(m_pParser->m_vStringVarBuf[item->second], m_pParser->m_vStringVarBuf.size());
866 m_iSynFlags = noANY ^ (noBC | noOPT | noEND | noARG_SEP);
878 bool ParserTokenReader::IsUndefVarTok(token_type& a_Tok)
881 auto iEnd(ExtractToken(m_pParser->
ValidNameChars(), strTok, (std::size_t)m_iPos));
885 if (m_iSynFlags & noVAR)
891 Error(
ecUNEXPECTED_VAR, m_iPos - (
int)a_Tok.GetAsString().length(), strTok);
897 value_type* fVar = m_pFactory(strTok.c_str(), m_pFactoryData);
898 a_Tok.SetVar(fVar, strTok);
906 (*m_pVarDef)[strTok] = fVar;
907 m_UsedVar[strTok] = fVar;
912 m_UsedVar[strTok] = 0;
918 m_iSynFlags = noVAL | noVAR | noFUN | noBO | noPOSTOP | noINFIXOP | noSTR;
930 bool ParserTokenReader::IsString(token_type& a_Tok)
932 if (m_strFormula[m_iPos] !=
'"')
935 string_type strBuf(&m_strFormula[(std::size_t)m_iPos + 1]);
936 std::size_t iEnd(0), iSkip(0);
939 for (iEnd = (
int)strBuf.find(
_T(
'\"')); iEnd != 0 && iEnd != string_type::npos; iEnd = (int)strBuf.find(
_T(
'\"'), iEnd))
941 if (strBuf[iEnd - 1] !=
'\\')
break;
942 strBuf.replace(iEnd - 1, 2,
_T(
"\""));
946 if (iEnd == string_type::npos)
949 string_type strTok(strBuf.begin(), strBuf.begin() + iEnd);
951 if (m_iSynFlags & noSTR)
954 m_pParser->m_vStringBuf.push_back(strTok);
955 a_Tok.SetString(strTok, m_pParser->m_vStringBuf.size());
957 m_iPos += (int)strTok.length() + 2 + (int)iSkip;
958 m_iSynFlags = noANY ^ (noARG_SEP | noBC | noOPT | noEND);
975 m_pParser->
Error(a_iErrc, a_iPos, a_sTok);
979 void ParserTokenReader::SetArgSep(
char_type cArgSep)
985 char_type ParserTokenReader::GetArgSep()
const
991 #if defined(_MSC_VER)
Operator item: closing bracket.
void IgnoreUndefVar(bool bIgnore)
Set Flag that controls behaviour in case of undefined variables being found.
#define _T(x)
Activate this option in order to compile with OpenMP support.
value_type *(* facfun_type)(const char_type *, void *)
Callback used for variable creation factory functions.
An unexpected comma has been found. (Example: "1,23")
Token can't be identified.
std::map< string_type, value_type * > varmap_type
Type used for storing variables.
function argument separator
Operator item: y to the power of ...
Internal error of any kind.
unterminated string constant. (Example: "3*valueof("hello)")
Operator item: not equal.
For use in the ternary if-then-else operator.
const char_type * ValidInfixOprtChars() const
Virtual function that defines the characters allowed in infix operator definitions.
const char_type * ValidOprtChars() const
Virtual function that defines the characters allowed in operator definitions.
varmap_type & GetUsedVar()
Return a map containing the used variables only.
int GetPos() const
Return the current position of the token reader in the formula string.
Unexpected function found. (Example: "sin(8)cos(9)")
ParserTokenReader(ParserBase *a_pParent)
Constructor.
bool HasBuiltInOprt() const
Query status of built in variables.
void Error(EErrorCodes a_iErrc, int a_iPos=(int) mu::string_type::npos, const string_type &a_strTok=string_type()) const
Create an error containing the parse error position.
Code for a generic function item.
const char_type * ValidNameChars() const
Virtual function that defines the characters allowed in name identifiers.
An unexpected value token has been found.
This file contains the parser token reader definition.
For use in the ternary if-then-else operator.
An unexpected variable token has been found.
token_type ReadNextToken()
Read the next token from the string.
This file contains the class definition of the muparser engine.
void ReInit()
Reset the token reader to the start of the formula.
#define MUP_ASSERT(COND)
An assertion that does not kill the program.
MUP_BASETYPE value_type
The numeric datatype used by the parser.
void SetFormula(const string_type &a_strFormula)
Initialize the token Reader.
ECmdCode GetCode() const
Return the token type.
Namespace for mathematical applications.
Unexpected end of formula. (Example: "2+sin(")
Operator item: less than.
int(* identfun_type)(const char_type *sExpr, int *nPos, value_type *fVal)
Callback used for functions that identify values in a string.
Operator item: greater than.
const char_type ** GetOprtDef() const
Get the default symbols used for the built in operators.
string_type::value_type char_type
The character type used by the parser.
Token reader for the ParserBase class.
ParserTokenReader * Clone(ParserBase *a_pParent) const
Create instance of a ParserTokenReader identical with this and return its pointer.
Operator item: Assignment operator.
Unexpected binary operator found.
MUP_STRING_TYPE string_type
The stringtype used by the parser.
Operator item: less or equal.
Unexpected Parenthesis, opening or closing.
Operator item: greater or equal.
Missing parens. (Example: "3*sin(3")
const string_type & GetExpr() const
Return a reference to the formula.
A string has been found at an inapropriate position.
Mathematical expressions parser (base parser engine).
Operator item: opening bracket.