added error checking to value expression parsing
This commit is contained in:
parent
abae9138e9
commit
5087a60dee
2 changed files with 39 additions and 13 deletions
14
error.h
14
error.h
|
|
@ -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
38
expr.cc
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue