[muparser] Clean up error handling in ParserTokenReader

This commit is contained in:
ridiculousfish 2017-11-25 01:07:56 -08:00
parent 91c28449aa
commit 62bedde23d
3 changed files with 20 additions and 11 deletions

View file

@ -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;

View file

@ -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

View file

@ -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;
}
//---------------------------------------------------------------------------