added error checking to value expression parsing

This commit is contained in:
John Wiegley 2004-07-30 20:06:56 -04:00
parent abae9138e9
commit 5087a60dee
2 changed files with 39 additions and 13 deletions

14
error.h
View file

@ -18,6 +18,20 @@ class error : public std::exception
} }
}; };
class compute_error : public error
{
public:
compute_error(const std::string& reason) throw() : error(reason) {}
virtual ~compute_error() throw() {}
};
class expr_error : public error
{
public:
expr_error(const std::string& reason) throw() : error(reason) {}
virtual ~expr_error() throw() {}
};
class parse_error : public error class parse_error : public error
{ {
unsigned int line; unsigned int line;

38
expr.cc
View file

@ -1,4 +1,5 @@
#include "expr.h" #include "expr.h"
#include "error.h"
#include "textual.h" #include "textual.h"
namespace ledger { namespace ledger {
@ -87,7 +88,8 @@ balance_t node_t::compute(const item_t * item,
case DATE: moment = item->date; break; case DATE: moment = item->date; break;
case BEGIN_DATE: moment = begin; break; case BEGIN_DATE: moment = begin; break;
case END_DATE: moment = end; break; case END_DATE: moment = end; break;
default: assert(0); break; default:
throw compute_error("Invalid date passed to P(v,d)");
} }
} }
temp = temp.value(moment); temp = temp.value(moment);
@ -173,7 +175,7 @@ node_t * parse_term(std::istream& in, ledger_t * ledger)
if (c == '}') if (c == '}')
in.get(c); in.get(c);
else else
ident = "0"; throw expr_error("Missing '}'");
} else { } else {
while (! in.eof() && std::isdigit(c) || c == '.') { while (! in.eof() && std::isdigit(c) || c == '.') {
in.get(c); in.get(c);
@ -244,6 +246,8 @@ node_t * parse_term(std::istream& in, ledger_t * ledger)
} }
if (in.peek() == ')') if (in.peek() == ')')
in.get(c); in.get(c);
else
throw expr_error("Missing ')'");
} else { } else {
node->left = parse_term(in, ledger); node->left = parse_term(in, ledger);
} }
@ -266,7 +270,7 @@ node_t * parse_term(std::istream& in, ledger_t * ledger)
node = new node_t(F_REGEXP); node = new node_t(F_REGEXP);
node->mask = new mask_t(ident); node->mask = new mask_t(ident);
} else { } else {
assert(0); throw expr_error("Missing closing '/'");
} }
break; break;
} }
@ -276,7 +280,7 @@ node_t * parse_term(std::istream& in, ledger_t * ledger)
if (in.peek() == ')') if (in.peek() == ')')
in.get(c); in.get(c);
else else
assert(0); throw expr_error("Missing ')'");
break; break;
case '[': { case '[': {
@ -292,9 +296,9 @@ node_t * parse_term(std::istream& in, ledger_t * ledger)
in.get(c); in.get(c);
node = new node_t(CONSTANT_T); node = new node_t(CONSTANT_T);
if (! parse_date(ident.c_str(), &node->constant_t)) if (! parse_date(ident.c_str(), &node->constant_t))
assert(0); throw expr_error("Failed to parse date");
} else { } else {
assert(0); throw expr_error("Missing ']'");
} }
break; break;
} }
@ -427,9 +431,11 @@ node_t * parse_logic_expr(std::istream& in, ledger_t * ledger)
} }
default: default:
if (! in.eof()) if (! in.eof()) {
assert(0); std::ostringstream err;
break; err << "Unexpected character '" << c << "'";
throw expr_error(err.str());
}
} }
} }
} }
@ -472,16 +478,22 @@ node_t * parse_expr(std::istream& in, ledger_t * ledger)
node->right = choices; node->right = choices;
choices->left = parse_logic_expr(in, ledger); choices->left = parse_logic_expr(in, ledger);
c = in.peek(); c = in.peek();
assert(c == ':'); if (c != ':') {
std::ostringstream err;
err << "Unexpected character '" << c << "'";
throw expr_error(err.str());
}
in.get(c); in.get(c);
choices->right = parse_logic_expr(in, ledger); choices->right = parse_logic_expr(in, ledger);
break; break;
} }
default: default:
if (! in.eof()) if (! in.eof()) {
assert(0); std::ostringstream err;
break; err << "Unexpected character '" << c << "'";
throw expr_error(err.str());
}
} }
c = in.peek(); c = in.peek();
} }