65 ParserTokenReader& ParserTokenReader::operator=(
const ParserTokenReader &a_Reader)
79 void ParserTokenReader::Assign(
const ParserTokenReader &a_Reader)
81 m_pParser = a_Reader.m_pParser;
82 m_strFormula = a_Reader.m_strFormula;
83 m_iPos = a_Reader.m_iPos;
84 m_iSynFlags = a_Reader.m_iSynFlags;
86 m_UsedVar = a_Reader.m_UsedVar;
87 m_pFunDef = a_Reader.m_pFunDef;
88 m_pConstDef = a_Reader.m_pConstDef;
89 m_pVarDef = a_Reader.m_pVarDef;
90 m_pStrVarDef = a_Reader.m_pStrVarDef;
91 m_pPostOprtDef = a_Reader.m_pPostOprtDef;
92 m_pInfixOprtDef = a_Reader.m_pInfixOprtDef;
93 m_pOprtDef = a_Reader.m_pOprtDef;
94 m_bIgnoreUndefVar = a_Reader.m_bIgnoreUndefVar;
95 m_vIdentFun = a_Reader.m_vIdentFun;
96 m_pFactory = a_Reader.m_pFactory;
97 m_pFactoryData = a_Reader.m_pFactoryData;
98 m_iBrackets = a_Reader.m_iBrackets;
99 m_cArgSep = a_Reader.m_cArgSep;
100 m_fZero = a_Reader.m_fZero;
101 m_lastTok = a_Reader.m_lastTok;
114 :m_pParser(a_pParent)
118 ,m_bIgnoreUndefVar(false)
120 ,m_pPostOprtDef(NULL)
121 ,m_pInfixOprtDef(NULL)
127 ,m_pFactoryData(NULL)
136 SetParent(m_pParser);
151 ptr->SetParent(a_pParent);
152 return ptr.release();
163 void ParserTokenReader::AddValIdent(
identfun_type a_pCallback)
171 m_vIdentFun.push_front(a_pCallback);
175 void ParserTokenReader::SetVarCreator(
facfun_type a_pFactory,
void *pUserData)
177 m_pFactory = a_pFactory;
178 m_pFactoryData = pUserData;
218 m_strFormula = a_strFormula;
233 m_bIgnoreUndefVar = bIgnore;
248 m_iSynFlags = sfSTART_OF_LINE;
260 const char_type *szFormula = m_strFormula.c_str();
264 while (szFormula[m_iPos]>0 && szFormula[m_iPos]<=0x20)
267 if ( IsEOF(tok) )
return SaveBeforeReturn(tok);
268 if ( IsOprt(tok) )
return SaveBeforeReturn(tok);
269 if ( IsFunTok(tok) )
return SaveBeforeReturn(tok);
270 if ( IsBuiltIn(tok) )
return SaveBeforeReturn(tok);
271 if ( IsArgSep(tok) )
return SaveBeforeReturn(tok);
272 if ( IsValTok(tok) )
return SaveBeforeReturn(tok);
273 if ( IsVarTok(tok) )
return SaveBeforeReturn(tok);
274 if ( IsStrVarTok(tok) )
return SaveBeforeReturn(tok);
275 if ( IsString(tok) )
return SaveBeforeReturn(tok);
276 if ( IsInfixOpTok(tok) )
return SaveBeforeReturn(tok);
277 if ( IsPostOpTok(tok) )
return SaveBeforeReturn(tok);
286 if ( (m_bIgnoreUndefVar || m_pFactory) && IsUndefVarTok(tok) )
287 return SaveBeforeReturn(tok);
294 int iEnd = ExtractToken(m_pParser->
ValidNameChars(), strTok, m_iPos);
303 void ParserTokenReader::SetParent(
ParserBase *a_pParent)
305 m_pParser = a_pParent;
306 m_pFunDef = &a_pParent->m_FunDef;
307 m_pOprtDef = &a_pParent->m_OprtDef;
308 m_pInfixOprtDef = &a_pParent->m_InfixOprtDef;
309 m_pPostOprtDef = &a_pParent->m_PostOprtDef;
310 m_pVarDef = &a_pParent->m_VarDef;
311 m_pStrVarDef = &a_pParent->m_StrVarDef;
312 m_pConstDef = &a_pParent->m_ConstDef;
324 int ParserTokenReader::ExtractToken(
const char_type *a_szCharSet,
328 int iEnd = (int)m_strFormula.find_first_not_of(a_szCharSet, a_iPos);
330 if (iEnd==(
int)string_type::npos)
331 iEnd = (int)m_strFormula.length();
335 a_sTok =
string_type( m_strFormula.begin()+a_iPos, m_strFormula.begin()+iEnd);
348 int ParserTokenReader::ExtractOperatorToken(
string_type &a_sTok,
352 int iEnd = (int)m_strFormula.find_first_not_of(m_pParser->
ValidOprtChars(), a_iPos);
353 if (iEnd==(
int)string_type::npos)
354 iEnd = (
int)m_strFormula.length();
359 a_sTok =
string_type( m_strFormula.begin() + a_iPos, m_strFormula.begin() + iEnd);
366 return ExtractToken(MUP_CHARS, a_sTok, a_iPos);
375 bool ParserTokenReader::IsBuiltIn(token_type &a_Tok)
378 *
const szFormula = m_strFormula.c_str();
382 for (
int i=0; pOprtDef[i]; i++)
384 std::size_t len( std::char_traits<char_type>::length(pOprtDef[i]) );
410 if (i==
cmASSIGN && m_iSynFlags & noASSIGN)
414 if (m_iSynFlags & noOPT)
419 if ( IsInfixOpTok(a_Tok) )
425 m_iSynFlags = noBC | noOPT | noARG_SEP | noPOSTOP | noASSIGN | noIF | noELSE | noEND;
429 if (m_iSynFlags & noBO)
433 m_iSynFlags = noOPT | noEND | noARG_SEP | noPOSTOP | noASSIGN | noIF | noELSE;
435 m_iSynFlags = noBC | noOPT | noEND | noARG_SEP | noPOSTOP | noASSIGN| noIF | noELSE;
441 if (m_iSynFlags & noBC)
444 m_iSynFlags = noBO | noVAR | noVAL | noFUN | noINFIXOP | noSTR | noASSIGN;
451 if (m_iSynFlags & noELSE)
452 Error(ecUNEXPECTED_CONDITIONAL, m_iPos, pOprtDef[i]);
454 m_iSynFlags = noBC | noPOSTOP | noEND | noOPT | noIF | noELSE;
458 if (m_iSynFlags & noIF)
459 Error(ecUNEXPECTED_CONDITIONAL, m_iPos, pOprtDef[i]);
461 m_iSynFlags = noBC | noPOSTOP | noEND | noOPT | noIF | noELSE;
469 a_Tok.Set( (
ECmdCode)i, pOprtDef[i] );
478 bool ParserTokenReader::IsArgSep(token_type &a_Tok)
480 const char_type* szFormula = m_strFormula.c_str();
482 if (szFormula[m_iPos]==m_cArgSep)
486 szSep[0] = m_cArgSep;
489 if (m_iSynFlags & noARG_SEP)
492 m_iSynFlags = noBC | noOPT | noEND | noARG_SEP | noPOSTOP | noASSIGN;
509 bool ParserTokenReader::IsEOF(token_type &a_Tok)
511 const char_type* szFormula = m_strFormula.c_str();
514 if ( !szFormula[m_iPos] )
516 if ( m_iSynFlags & noEND )
534 bool ParserTokenReader::IsInfixOpTok(token_type &a_Tok)
542 funmap_type::const_reverse_iterator it = m_pInfixOprtDef->rbegin();
543 for ( ; it!=m_pInfixOprtDef->rend(); ++it)
545 if (sTok.find(it->first)!=0)
548 a_Tok.Set(it->second, it->first);
549 m_iPos += (int)it->first.length();
551 if (m_iSynFlags & noINFIXOP)
554 m_iSynFlags = noPOSTOP | noINFIXOP | noOPT | noBC | noSTR | noASSIGN;
579 bool ParserTokenReader::IsFunTok(token_type &a_Tok)
582 int iEnd = ExtractToken(m_pParser->
ValidNameChars(), strTok, m_iPos);
586 funmap_type::const_iterator item = m_pFunDef->find(strTok);
587 if (item==m_pFunDef->end())
591 const char_type *szFormula = m_strFormula.c_str();
592 if (szFormula[iEnd]!=
'(')
595 a_Tok.Set(item->second, strTok);
598 if (m_iSynFlags & noFUN)
599 Error(
ecUNEXPECTED_FUN, m_iPos-(
int)a_Tok.GetAsString().length(), a_Tok.GetAsString());
601 m_iSynFlags = noANY ^ noBO;
610 bool ParserTokenReader::IsOprt(token_type &a_Tok)
612 const char_type *
const szExpr = m_strFormula.c_str();
615 int iEnd = ExtractOperatorToken(strTok, m_iPos);
633 funmap_type::const_reverse_iterator it = m_pOprtDef->rbegin();
634 for ( ; it!=m_pOprtDef->rend(); ++it)
637 if ( sID ==
string_type(szExpr + m_iPos, szExpr + m_iPos + sID.length()) )
639 a_Tok.Set(it->second, strTok);
642 if (m_iSynFlags & noOPT)
648 if ( IsInfixOpTok(a_Tok) )
659 m_iPos += (int)sID.length();
660 m_iSynFlags = noBC | noOPT | noARG_SEP | noPOSTOP | noEND | noASSIGN;
670 bool ParserTokenReader::IsPostOpTok(token_type &a_Tok)
679 if (m_iSynFlags & noPOSTOP)
693 int iEnd = ExtractToken(m_pParser->
ValidOprtChars(), sTok, m_iPos);
698 funmap_type::const_reverse_iterator it = m_pPostOprtDef->rbegin();
699 for ( ; it!=m_pPostOprtDef->rend(); ++it)
701 if (sTok.find(it->first)!=0)
704 a_Tok.Set(it->second, sTok);
705 m_iPos += (int)it->first.length();
707 m_iSynFlags = noVAL | noVAR | noFUN | noBO | noPOSTOP | noSTR | noASSIGN;
722 bool ParserTokenReader::IsValTok(token_type &a_Tok)
736 valmap_type::const_iterator item = m_pConstDef->find(strTok);
737 if (item!=m_pConstDef->end())
740 a_Tok.SetVal(item->second, strTok);
742 if (m_iSynFlags & noVAL)
745 m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR | noASSIGN;
752 std::list<identfun_type>::const_iterator item = m_vIdentFun.begin();
753 for (item = m_vIdentFun.begin(); item!=m_vIdentFun.end(); ++item)
756 if ( (*item)(m_strFormula.c_str() + m_iPos, &m_iPos, &fVal)==1 )
759 strTok.assign(m_strFormula.c_str(), iStart, m_iPos-iStart);
761 if (m_iSynFlags & noVAL)
764 a_Tok.SetVal(fVal, strTok);
765 m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR | noASSIGN;
778 bool ParserTokenReader::IsVarTok(token_type &a_Tok)
780 if (m_pVarDef->empty())
784 int iEnd = ExtractToken(m_pParser->
ValidNameChars(), strTok, m_iPos);
788 varmap_type::const_iterator item = m_pVarDef->find(strTok);
789 if (item==m_pVarDef->end())
792 if (m_iSynFlags & noVAR)
795 m_pParser->OnDetectVar(&m_strFormula, m_iPos, iEnd);
798 a_Tok.SetVar(item->second, strTok);
799 m_UsedVar[item->first] = item->second;
801 m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR;
809 bool ParserTokenReader::IsStrVarTok(token_type &a_Tok)
811 if (!m_pStrVarDef || m_pStrVarDef->empty())
815 int iEnd = ExtractToken(m_pParser->
ValidNameChars(), strTok, m_iPos);
819 strmap_type::const_iterator item = m_pStrVarDef->find(strTok);
820 if (item==m_pStrVarDef->end())
823 if (m_iSynFlags & noSTR)
827 if (!m_pParser->m_vStringVarBuf.size())
830 a_Tok.SetString(m_pParser->m_vStringVarBuf[item->second], m_pParser->m_vStringVarBuf.size() );
832 m_iSynFlags = noANY ^ ( noBC | noOPT | noEND | noARG_SEP);
844 bool ParserTokenReader::IsUndefVarTok(token_type &a_Tok)
847 int iEnd( ExtractToken(m_pParser->
ValidNameChars(), strTok, m_iPos) );
851 if (m_iSynFlags & noVAR)
857 Error(
ecUNEXPECTED_VAR, m_iPos - (
int)a_Tok.GetAsString().length(), strTok);
863 value_type *fVar = m_pFactory(strTok.c_str(), m_pFactoryData);
864 a_Tok.SetVar(fVar, strTok );
872 (*m_pVarDef)[strTok] = fVar;
873 m_UsedVar[strTok] = fVar;
878 m_UsedVar[strTok] = 0;
884 m_iSynFlags = noVAL | noVAR | noFUN | noBO | noPOSTOP | noINFIXOP | noSTR;
896 bool ParserTokenReader::IsString(token_type &a_Tok)
898 if (m_strFormula[m_iPos]!=
'"')
902 std::size_t iEnd(0), iSkip(0);
905 for(iEnd=(
int)strBuf.find(
_T(
"\"") ); iEnd!=0 && iEnd!=string_type::npos; iEnd=(int)strBuf.find(
_T(
"\""), iEnd))
907 if (strBuf[iEnd-1]!=
'\\')
break;
908 strBuf.replace(iEnd-1, 2,
_T(
"\"") );
912 if (iEnd==string_type::npos)
915 string_type strTok(strBuf.begin(), strBuf.begin()+iEnd);
917 if (m_iSynFlags & noSTR)
920 m_pParser->m_vStringBuf.push_back(strTok);
921 a_Tok.SetString(strTok, m_pParser->m_vStringBuf.size());
923 m_iPos += (int)strTok.length() + 2 + (int)iSkip;
924 m_iSynFlags = noANY ^ ( noARG_SEP | noBC | noOPT | noEND );
939 void ParserTokenReader::Error(
EErrorCodes a_iErrc,
943 m_pParser->
Error(a_iErrc, a_iPos, a_sTok);
947 void ParserTokenReader::SetArgSep(
char_type cArgSep)
953 char_type ParserTokenReader::GetArgSep()
const
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.
An unexpected comma has been found. (Example: "1,23")
Token cant 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.
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.
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.
int(* identfun_type)(const char_type *sExpr, int *nPos, value_type *fVal)
Callback used for functions that identify values in a string.
Operator item: less or equal.
Unexpected Parenthesis, opening or closing.
Operator item: greater or equal.
value_type *(* facfun_type)(const char_type *, void *)
Callback used for variable creation factory functions.
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.