[muparser] ApplyRemainingOprt to return explicit errors

This commit is contained in:
ridiculousfish 2017-11-24 15:54:00 -08:00
parent 60d9c9fa00
commit 234808bc32
2 changed files with 20 additions and 12 deletions

View file

@ -218,8 +218,8 @@ class ParserBase {
void AddCallback(const string_type &a_strName, const ParserCallback &a_Callback, void AddCallback(const string_type &a_strName, const ParserCallback &a_Callback,
funmap_type &a_Storage, const char_type *a_szCharSet); funmap_type &a_Storage, const char_type *a_szCharSet);
void ApplyRemainingOprt(ParserStack<token_type> &a_stOpt, OptionalError ApplyRemainingOprt(ParserStack<token_type> &a_stOpt,
ParserStack<token_type> &a_stVal) const; ParserStack<token_type> &a_stVal) const;
OptionalError ApplyBinOprt(ParserStack<token_type> &a_stOpt, OptionalError ApplyBinOprt(ParserStack<token_type> &a_stOpt,
ParserStack<token_type> &a_stVal) const; ParserStack<token_type> &a_stVal) const;

View file

@ -540,7 +540,8 @@ const varmap_type &ParserBase::GetUsedVar() const {
m_pTokenReader->IgnoreUndefVar(true); m_pTokenReader->IgnoreUndefVar(true);
// Try to create bytecode, but don't use it for any further calculations since it may // Try to create bytecode, but don't use it for any further calculations since it may
// contain references to nonexisting variables. // contain references to nonexisting variables.
OptionalError err = CreateRPN(); OptionalError oerr = CreateRPN();
if (oerr.has_error()) throw oerr.error();
m_pParseFormula = &ParserBase::ParseString; m_pParseFormula = &ParserBase::ParseString;
m_pTokenReader->IgnoreUndefVar(false); m_pTokenReader->IgnoreUndefVar(false);
} catch (exception_type & /*e*/) { } catch (exception_type & /*e*/) {
@ -772,9 +773,10 @@ OptionalError ParserBase::ApplyBinOprt(ParserStack<token_type> &a_stOpt,
\param a_stOpt The operator stack \param a_stOpt The operator stack
\param a_stVal The value stack \param a_stVal The value stack
*/ */
void ParserBase::ApplyRemainingOprt(ParserStack<token_type> &stOpt, OptionalError ParserBase::ApplyRemainingOprt(ParserStack<token_type> &stOpt,
ParserStack<token_type> &stVal) const { ParserStack<token_type> &stVal) const {
while (stOpt.size() && stOpt.top().GetCode() != cmBO && stOpt.top().GetCode() != cmIF) { while (stOpt.size() && stOpt.top().GetCode() != cmBO && stOpt.top().GetCode() != cmIF) {
OptionalError oerr;
token_type tok = stOpt.top(); token_type tok = stOpt.top();
switch (tok.GetCode()) { switch (tok.GetCode()) {
case cmOPRT_INFIX: case cmOPRT_INFIX:
@ -794,19 +796,21 @@ void ParserBase::ApplyRemainingOprt(ParserStack<token_type> &stOpt,
case cmLOR: case cmLOR:
case cmASSIGN: case cmASSIGN:
if (stOpt.top().GetCode() == cmOPRT_INFIX) if (stOpt.top().GetCode() == cmOPRT_INFIX)
ApplyFunc(stOpt, stVal, 1); oerr = ApplyFunc(stOpt, stVal, 1);
else else
ApplyBinOprt(stOpt, stVal); oerr = ApplyBinOprt(stOpt, stVal);
break; break;
case cmELSE: case cmELSE:
ApplyIfElse(stOpt, stVal); oerr = ApplyIfElse(stOpt, stVal);
break; break;
default: default:
assert(0 && "muParser internal error"); assert(0 && "muParser internal error");
} }
if (oerr.has_error()) return oerr.error();
} }
return {};
} }
/// Invoke the function \p func as the fun_typeN given argCount, passing in \p argCount arguments /// Invoke the function \p func as the fun_typeN given argCount, passing in \p argCount arguments
@ -1049,6 +1053,7 @@ OptionalError ParserBase::CreateRPN() const {
for (;;) { for (;;) {
opt = m_pTokenReader->ReadNextToken(); opt = m_pTokenReader->ReadNextToken();
OptionalError oerr;
switch (opt.GetCode()) { switch (opt.GetCode()) {
// //
@ -1068,7 +1073,7 @@ OptionalError ParserBase::CreateRPN() const {
case cmVAL: { case cmVAL: {
stVal.push(opt); stVal.push(opt);
ValueOrError optVal = opt.GetVal(); ValueOrError optVal = opt.GetVal();
if (optVal.has_error()) throw optVal.error(); if (optVal.has_error()) return optVal.error();
m_vRPN.AddVal(optVal.value()); m_vRPN.AddVal(optVal.value());
break; break;
} }
@ -1077,7 +1082,8 @@ OptionalError ParserBase::CreateRPN() const {
m_nIfElseCounter--; m_nIfElseCounter--;
if (m_nIfElseCounter < 0) Error(ecMISPLACED_COLON, m_pTokenReader->GetPos()); if (m_nIfElseCounter < 0) Error(ecMISPLACED_COLON, m_pTokenReader->GetPos());
ApplyRemainingOprt(stOpt, stVal); oerr = ApplyRemainingOprt(stOpt, stVal);
if (oerr.has_error()) return oerr.error();
m_vRPN.AddIfElse(cmELSE); m_vRPN.AddIfElse(cmELSE);
stOpt.push(opt); stOpt.push(opt);
break; break;
@ -1089,7 +1095,8 @@ OptionalError ParserBase::CreateRPN() const {
// fallthrough intentional (no break!) // fallthrough intentional (no break!)
case cmEND: case cmEND:
ApplyRemainingOprt(stOpt, stVal); oerr = ApplyRemainingOprt(stOpt, stVal);
if (oerr.has_error()) return oerr.error();
break; break;
case cmBC: { case cmBC: {
@ -1099,7 +1106,8 @@ OptionalError ParserBase::CreateRPN() const {
// was an opening bracket we know better... // was an opening bracket we know better...
if (opta.GetCode() == cmBO) --stArgCount.top(); if (opta.GetCode() == cmBO) --stArgCount.top();
ApplyRemainingOprt(stOpt, stVal); oerr = ApplyRemainingOprt(stOpt, stVal);
if (oerr.has_error()) return oerr.error();
// Check if the bracket content has been evaluated completely // Check if the bracket content has been evaluated completely
if (stOpt.size() && stOpt.top().GetCode() == cmBO) { if (stOpt.size() && stOpt.top().GetCode() == cmBO) {