From 62bedde23d2229f722d382075f32ce8a577bd627 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sat, 25 Nov 2017 01:07:56 -0800 Subject: [PATCH] [muparser] Clean up error handling in ParserTokenReader --- muparser-2.2.5/include/muParserTokenReader.h | 11 +++++++++-- muparser-2.2.5/src/muParserBase.cpp | 3 ++- muparser-2.2.5/src/muParserTokenReader.cpp | 17 +++++++++-------- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/muparser-2.2.5/include/muParserTokenReader.h b/muparser-2.2.5/include/muParserTokenReader.h index c9e46c81b..9277c06a5 100644 --- a/muparser-2.2.5/include/muParserTokenReader.h +++ b/muparser-2.2.5/include/muParserTokenReader.h @@ -68,6 +68,13 @@ class ParserTokenReader final { void ReInit(); token_type ReadNextToken(); + /// \return the first error (if any), clearing it. + OptionalError acquireFirstError() { + OptionalError ret = std::move(firstError_); + firstError_ = OptionalError{}; + return ret; + } + private: /** \brief Syntax codes. @@ -113,8 +120,7 @@ class ParserTokenReader final { bool IsStrVarTok(token_type &a_Tok); bool IsUndefVarTok(token_type &a_Tok); bool IsString(token_type &a_Tok); - void Error(EErrorCodes a_iErrc, int a_iPos = -1, - const string_type &a_sTok = string_type()) const; + bool Error(EErrorCodes a_iErrc, int a_iPos = -1, const string_type &a_sTok = string_type()); token_type &SaveBeforeReturn(const token_type &tok); @@ -124,6 +130,7 @@ class ParserTokenReader final { int m_iSynFlags = 0; bool m_bIgnoreUndefVar = false; + OptionalError firstError_; /// The first error reported during parsing. const funmap_type *m_pFunDef = nullptr; const funmap_type *m_pPostOprtDef = nullptr; const funmap_type *m_pInfixOprtDef = nullptr; diff --git a/muparser-2.2.5/src/muParserBase.cpp b/muparser-2.2.5/src/muParserBase.cpp index ba0a2c893..a617b0544 100644 --- a/muparser-2.2.5/src/muParserBase.cpp +++ b/muparser-2.2.5/src/muParserBase.cpp @@ -1040,8 +1040,9 @@ OptionalError ParserBase::CreateRPN() const { for (;;) { opt = m_pTokenReader->ReadNextToken(); + OptionalError oerr = m_pTokenReader->acquireFirstError(); + if (oerr.has_error()) return oerr; - OptionalError oerr; switch (opt.GetCode()) { // // Next three are different kind of value entries diff --git a/muparser-2.2.5/src/muParserTokenReader.cpp b/muparser-2.2.5/src/muParserTokenReader.cpp index 34c6cd1f6..67a1b0b37 100644 --- a/muparser-2.2.5/src/muParserTokenReader.cpp +++ b/muparser-2.2.5/src/muParserTokenReader.cpp @@ -162,14 +162,14 @@ ParserTokenReader::token_type ParserTokenReader::ReadNextToken() { // Check for unknown token // - // !!! From this point on there is no exit without an exception possible... + // !!! From this point on there is no exit without an error possible... // string_type strTok; int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos); if (iEnd != m_iPos) Error(ecUNASSIGNABLE_TOKEN, m_iPos, strTok); Error(ecUNASSIGNABLE_TOKEN, m_iPos, m_strFormula.substr(m_iPos)); - return token_type(); // never reached + return token_type(); } //--------------------------------------------------------------------------- @@ -723,17 +723,18 @@ bool ParserTokenReader::IsString(token_type &a_Tok) { } //--------------------------------------------------------------------------- -/** \brief Create an error containing the parse error position. - - This function will create an Parser Exception object containing the error text and its position. +/** \brief Create an error containing the parse error position. Store it in parseError_, if not + already set. \param a_iErrc [in] The error code of type #EErrorCodes. \param a_iPos [in] The position where the error was detected. \param a_strTok [in] The token string representation associated with the error. - \throw ParserException always throws thats the only purpose of this function. */ -void ParserTokenReader::Error(EErrorCodes a_iErrc, int a_iPos, const string_type &a_sTok) const { - m_pParser->Error(a_iErrc, a_iPos, a_sTok); +bool ParserTokenReader::Error(EErrorCodes a_iErrc, int a_iPos, const string_type &a_sTok) { + if (!firstError_.has_error()) { + firstError_ = m_pParser->Error(a_iErrc, a_iPos, a_sTok); + } + return false; } //---------------------------------------------------------------------------