00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef MU_PARSER_TOKEN_H
00027 #define MU_PARSER_TOKEN_H
00028
00029 #include <cassert>
00030 #include <string>
00031 #include <stack>
00032 #include <vector>
00033 #include <memory>
00034
00035 #include "muParserError.h"
00036 #include "muParserCallback.h"
00037
00042 namespace mu
00043 {
00060 template<typename TBase, typename TString>
00061 class ParserToken
00062 {
00063 public:
00064
00066 enum ETokFlags
00067 {
00068 flVOLATILE = 1
00069 };
00070
00071 private:
00072
00073 ECmdCode m_iCode;
00074 ETypeCode m_iType;
00075 void *m_pTok;
00076 int m_iFlags;
00077 int m_iIdx;
00078 TString m_strTok;
00079 TString m_strVal;
00080 value_type m_fVal;
00081 std::auto_ptr<ParserCallback> m_pCallback;
00082
00083 public:
00084
00085
00092 ParserToken()
00093 :m_iCode(cmUNKNOWN)
00094 ,m_iType(tpVOID)
00095 ,m_pTok(0)
00096 ,m_iFlags(0)
00097 ,m_iIdx(-1)
00098 ,m_strTok()
00099 ,m_pCallback()
00100 {}
00101
00102
00110 ParserToken(const ParserToken &a_Tok)
00111 {
00112 Assign(a_Tok);
00113 }
00114
00115
00122 ParserToken& operator=(const ParserToken &a_Tok)
00123 {
00124 Assign(a_Tok);
00125 return *this;
00126 }
00127
00128
00133 void Assign(const ParserToken &a_Tok)
00134 {
00135 m_iCode = a_Tok.m_iCode;
00136 m_pTok = a_Tok.m_pTok;
00137 m_iFlags = a_Tok.m_iFlags;
00138 m_strTok = a_Tok.m_strTok;
00139 m_iIdx = a_Tok.m_iIdx;
00140 m_strVal = a_Tok.m_strVal;
00141 m_iType = a_Tok.m_iType;
00142 m_fVal = a_Tok.m_fVal;
00143
00144 m_pCallback.reset(a_Tok.m_pCallback.get() ? a_Tok.m_pCallback->Clone() : 0);
00145 }
00146
00147
00153 void AddFlags(int a_iFlags)
00154 {
00155 m_iFlags |= a_iFlags;
00156 }
00157
00158
00163 bool IsFlagSet(int a_iFlags) const
00164 {
00165 #if defined(_MSC_VER)
00166 #pragma warning( disable : 4800 )
00167 #endif
00168
00169 return (bool)(m_iFlags & a_iFlags);
00170
00171 #if defined(_MSC_VER)
00172 #pragma warning( default : 4800 ) // int: Variable set to boolean value (may degrade performance)
00173 #endif
00174 }
00175
00176
00187 ParserToken& Set(ECmdCode a_iType, const TString &a_strTok=TString())
00188 {
00189
00190 assert(a_iType!=cmVAR);
00191 assert(a_iType!=cmVAL);
00192 assert(a_iType!=cmFUNC);
00193
00194 m_iCode = a_iType;
00195 m_iType = tpVOID;
00196 m_pTok = 0;
00197 m_iFlags = 0;
00198 m_strTok = a_strTok;
00199 m_iIdx = -1;
00200
00201 return *this;
00202 }
00203
00204
00206 ParserToken& Set(const ParserCallback &a_pCallback, const TString &a_sTok)
00207 {
00208 assert(a_pCallback.GetAddr());
00209
00210 m_iCode = a_pCallback.GetCode();
00211 m_iType = tpVOID;
00212 m_strTok = a_sTok;
00213 m_pCallback.reset(new ParserCallback(a_pCallback));
00214
00215 m_pTok = 0;
00216 m_iFlags = 0;
00217 m_iIdx = -1;
00218
00219 if (!m_pCallback->IsOptimizable())
00220 AddFlags(flVOLATILE);
00221
00222 return *this;
00223 }
00224
00225
00231 ParserToken& SetVal(TBase a_fVal, const TString &a_strTok=TString())
00232 {
00233 m_iCode = cmVAL;
00234 m_iType = tpDBL;
00235 m_fVal = a_fVal;
00236 m_iFlags = 0;
00237 m_strTok = a_strTok;
00238 m_iIdx = -1;
00239
00240 m_pTok = 0;
00241 m_pCallback.reset(0);
00242
00243 return *this;
00244 }
00245
00246
00252 ParserToken& SetVar(TBase *a_pVar, const TString &a_strTok)
00253 {
00254 m_iCode = cmVAR;
00255 m_iType = tpDBL;
00256 m_iFlags = 0;
00257 m_strTok = a_strTok;
00258 m_iIdx = -1;
00259 m_pTok = (void*)a_pVar;
00260 m_pCallback.reset(0);
00261
00262 AddFlags(ParserToken::flVOLATILE);
00263 return *this;
00264 }
00265
00266
00272 ParserToken& SetString(const TString &a_strTok, std::size_t a_iSize)
00273 {
00274 m_iCode = cmSTRING;
00275 m_iType = tpSTR;
00276 m_iFlags = 0;
00277 m_strTok = a_strTok;
00278 m_iIdx = static_cast<int>(a_iSize);
00279
00280 m_pTok = 0;
00281 m_pCallback.reset(0);
00282
00283 AddFlags(ParserToken::flVOLATILE);
00284 return *this;
00285 }
00286
00287
00294 void SetIdx(int a_iIdx)
00295 {
00296 if (m_iCode!=cmSTRING || a_iIdx<0)
00297 throw ParserError(ecINTERNAL_ERROR);
00298
00299 m_iIdx = a_iIdx;
00300 }
00301
00302
00310 int GetIdx() const
00311 {
00312 if (m_iIdx<0 || m_iCode!=cmSTRING )
00313 throw ParserError(ecINTERNAL_ERROR);
00314
00315 return m_iIdx;
00316 }
00317
00318
00324 ECmdCode GetCode() const
00325 {
00326 if (m_pCallback.get())
00327 {
00328 return m_pCallback->GetCode();
00329 }
00330 else
00331 {
00332 return m_iCode;
00333 }
00334 }
00335
00336
00337 ETypeCode GetType() const
00338 {
00339 if (m_pCallback.get())
00340 {
00341 return m_pCallback->GetType();
00342 }
00343 else
00344 {
00345 return m_iType;
00346 }
00347 }
00348
00349
00350 int GetPri() const
00351 {
00352 if ( !m_pCallback.get())
00353 throw ParserError(ecINTERNAL_ERROR);
00354
00355 if ( m_pCallback->GetCode()!=cmOPRT_BIN && m_pCallback->GetCode()!=cmOPRT_INFIX)
00356 throw ParserError(ecINTERNAL_ERROR);
00357
00358 return m_pCallback->GetPri();
00359 }
00360
00361
00376 void* GetFuncAddr() const
00377 {
00378 return (m_pCallback.get()) ? m_pCallback->GetAddr() : 0;
00379 }
00380
00381
00387 TBase GetVal() const
00388 {
00389 switch (m_iCode)
00390 {
00391 case cmVAL: return m_fVal;
00392 case cmVAR: return *((TBase*)m_pTok);
00393 default: throw ParserError(ecVAL_EXPECTED);
00394 }
00395 }
00396
00397
00403 TBase* GetVar() const
00404 {
00405 if (m_iCode!=cmVAR)
00406 throw ParserError(ecINTERNAL_ERROR);
00407
00408 return (TBase*)m_pTok;
00409 }
00410
00411
00416 int GetArgCount() const
00417 {
00418 assert(m_pCallback.get());
00419
00420 if (!m_pCallback->GetAddr())
00421 throw ParserError(ecINTERNAL_ERROR);
00422
00423 return m_pCallback->GetArgc();
00424 }
00425
00426
00435 const TString& GetAsString() const
00436 {
00437 return m_strTok;
00438 }
00439 };
00440 }
00441
00442 #endif