summaryrefslogtreecommitdiff
path: root/valexpr.cc
diff options
context:
space:
mode:
Diffstat (limited to 'valexpr.cc')
-rw-r--r--valexpr.cc305
1 files changed, 134 insertions, 171 deletions
diff --git a/valexpr.cc b/valexpr.cc
index 4180b176..487909fa 100644
--- a/valexpr.cc
+++ b/valexpr.cc
@@ -56,45 +56,8 @@ mask_t::~mask_t() {
pcre_free((pcre *)regexp);
}
-#if 1
-bool matches(const masks_list& regexps, const std::string& str,
- bool * by_exclusion)
-{
- if (regexps.empty())
- return false;
-
- bool match = false;
- bool definite = false;
-
- for (masks_list::const_iterator r = regexps.begin();
- r != regexps.end();
- r++) {
- static int ovec[30];
- int result = pcre_exec((pcre *)(*r).regexp, NULL,
- str.c_str(), str.length(), 0, 0, ovec, 30);
- if (result >= 0) {
- match = ! (*r).exclude;
- definite = true;
- }
- else if ((*r).exclude) {
- if (! match)
- match = ! definite;
- }
- else {
- definite = true;
- }
- }
-
- if (by_exclusion)
- *by_exclusion = match && ! definite && by_exclusion;
-
- return match;
-}
-
-#endif
-
-void node_t::compute(balance_t& result, const details_t& details) const
+void value_expr_t::compute(balance_t& result, const details_t& details) const
{
switch (type) {
case CONSTANT_A:
@@ -351,16 +314,16 @@ inline char peek_next_nonws(std::istream& in)
return c;
}
-node_t * parse_term(std::istream& in);
+value_expr_t * parse_value_term(std::istream& in);
-inline node_t * parse_term(const char * p) {
+inline value_expr_t * parse_value_term(const char * p) {
std::istringstream stream(p);
- return parse_term(stream);
+ return parse_value_term(stream);
}
-node_t * parse_term(std::istream& in)
+value_expr_t * parse_value_term(std::istream& in)
{
- node_t * node = NULL;
+ value_expr_t * node = NULL;
char c = peek_next_nonws(in);
if (std::isdigit(c) || c == '.' || c == '{') {
@@ -387,7 +350,7 @@ node_t * parse_term(std::istream& in)
}
if (! ident.empty()) {
- node = new node_t(node_t::CONSTANT_A);
+ node = new value_expr_t(value_expr_t::CONSTANT_A);
node->constant_a.parse(ident);
}
return node;
@@ -396,62 +359,62 @@ node_t * parse_term(std::istream& in)
in.get(c);
switch (c) {
// Basic terms
- case 'a': node = new node_t(node_t::AMOUNT); break;
- case 'c': node = new node_t(node_t::COST); break;
- case 'd': node = new node_t(node_t::DATE); break;
- case 'X': node = new node_t(node_t::CLEARED); break;
- case 'R': node = new node_t(node_t::REAL); break;
- case 'n': node = new node_t(node_t::INDEX); break;
- case 'B': node = new node_t(node_t::BALANCE); break;
- case 'T': node = new node_t(node_t::TOTAL); break;
- case 'C': node = new node_t(node_t::COST_TOTAL); break;
+ case 'a': node = new value_expr_t(value_expr_t::AMOUNT); break;
+ case 'c': node = new value_expr_t(value_expr_t::COST); break;
+ case 'd': node = new value_expr_t(value_expr_t::DATE); break;
+ case 'X': node = new value_expr_t(value_expr_t::CLEARED); break;
+ case 'R': node = new value_expr_t(value_expr_t::REAL); break;
+ case 'n': node = new value_expr_t(value_expr_t::INDEX); break;
+ case 'B': node = new value_expr_t(value_expr_t::BALANCE); break;
+ case 'T': node = new value_expr_t(value_expr_t::TOTAL); break;
+ case 'C': node = new value_expr_t(value_expr_t::COST_TOTAL); break;
// Compound terms
- case 'v': node = parse_expr("P(a,d)"); break;
- case 'V': node = parse_term("P(T,d)"); break;
- case 'g': node = parse_expr("v-c"); break;
- case 'G': node = parse_expr("V-C"); break;
- case 'o': node = parse_expr("d-b"); break;
- case 'w': node = parse_expr("e-d"); break;
+ case 'v': node = parse_value_expr("P(a,d)"); break;
+ case 'V': node = parse_value_term("P(T,d)"); break;
+ case 'g': node = parse_value_expr("v-c"); break;
+ case 'G': node = parse_value_expr("V-C"); break;
+ case 'o': node = parse_value_expr("d-b"); break;
+ case 'w': node = parse_value_expr("e-d"); break;
// Functions
case '-':
- node = new node_t(node_t::F_NEG);
- node->left = parse_term(in);
+ node = new value_expr_t(value_expr_t::F_NEG);
+ node->left = parse_value_term(in);
break;
case 'A':
- node = new node_t(node_t::F_ABS);
- node->left = parse_term(in);
+ node = new value_expr_t(value_expr_t::F_ABS);
+ node->left = parse_value_term(in);
break;
case 'M':
- node = new node_t(node_t::F_ARITH_MEAN);
- node->left = parse_term(in);
+ node = new value_expr_t(value_expr_t::F_ARITH_MEAN);
+ node->left = parse_value_term(in);
break;
case 'D': {
- node = new node_t(node_t::O_SUB);
- node->left = parse_term("a");
- node->right = parse_term(in);
+ node = new value_expr_t(value_expr_t::O_SUB);
+ node->left = parse_value_term("a");
+ node->right = parse_value_term(in);
break;
}
case 'P':
- node = new node_t(node_t::F_VALUE);
+ node = new value_expr_t(value_expr_t::F_VALUE);
if (peek_next_nonws(in) == '(') {
in.get(c);
- node->left = parse_expr(in);
+ node->left = parse_value_expr(in);
if (peek_next_nonws(in) == ',') {
in.get(c);
- node->right = parse_expr(in);
+ node->right = parse_value_expr(in);
}
if (peek_next_nonws(in) == ')')
in.get(c);
else
throw expr_error("Missing ')'");
} else {
- node->left = parse_term(in);
+ node->left = parse_value_term(in);
}
break;
@@ -477,8 +440,8 @@ node_t * parse_term(std::istream& in)
if (c == '/') {
in.get(c);
- node = new node_t(payee_mask ?
- node_t::F_PAYEE_MASK : node_t::F_ACCOUNT_MASK);
+ node = new value_expr_t(payee_mask ?
+ value_expr_t::F_PAYEE_MASK : value_expr_t::F_ACCOUNT_MASK);
node->mask = new mask_t(ident);
} else {
throw expr_error("Missing closing '/'");
@@ -487,7 +450,7 @@ node_t * parse_term(std::istream& in)
}
case '(':
- node = parse_expr(in);
+ node = parse_value_expr(in);
if (peek_next_nonws(in) == ')')
in.get(c);
else
@@ -505,7 +468,7 @@ node_t * parse_term(std::istream& in)
}
if (c == ']') {
in.get(c);
- node = new node_t(node_t::CONSTANT_T);
+ node = new value_expr_t(value_expr_t::CONSTANT_T);
if (! parse_date(ident.c_str(), &node->constant_t))
throw expr_error("Failed to parse date");
} else {
@@ -522,11 +485,11 @@ node_t * parse_term(std::istream& in)
return node;
}
-node_t * parse_mul_expr(std::istream& in)
+value_expr_t * parse_mul_expr(std::istream& in)
{
- node_t * node = NULL;
+ value_expr_t * node = NULL;
- node = parse_term(in);
+ node = parse_value_term(in);
if (node && ! in.eof()) {
char c = peek_next_nonws(in);
@@ -534,18 +497,18 @@ node_t * parse_mul_expr(std::istream& in)
in.get(c);
switch (c) {
case '*': {
- node_t * prev = node;
- node = new node_t(node_t::O_MUL);
+ value_expr_t * prev = node;
+ node = new value_expr_t(value_expr_t::O_MUL);
node->left = prev;
- node->right = parse_term(in);
+ node->right = parse_value_term(in);
break;
}
case '/': {
- node_t * prev = node;
- node = new node_t(node_t::O_DIV);
+ value_expr_t * prev = node;
+ node = new value_expr_t(value_expr_t::O_DIV);
node->left = prev;
- node->right = parse_term(in);
+ node->right = parse_value_term(in);
break;
}
}
@@ -556,9 +519,9 @@ node_t * parse_mul_expr(std::istream& in)
return node;
}
-node_t * parse_add_expr(std::istream& in)
+value_expr_t * parse_add_expr(std::istream& in)
{
- node_t * node = NULL;
+ value_expr_t * node = NULL;
node = parse_mul_expr(in);
@@ -568,16 +531,16 @@ node_t * parse_add_expr(std::istream& in)
in.get(c);
switch (c) {
case '+': {
- node_t * prev = node;
- node = new node_t(node_t::O_ADD);
+ value_expr_t * prev = node;
+ node = new value_expr_t(value_expr_t::O_ADD);
node->left = prev;
node->right = parse_mul_expr(in);
break;
}
case '-': {
- node_t * prev = node;
- node = new node_t(node_t::O_SUB);
+ value_expr_t * prev = node;
+ node = new value_expr_t(value_expr_t::O_SUB);
node->left = prev;
node->right = parse_mul_expr(in);
break;
@@ -590,14 +553,14 @@ node_t * parse_add_expr(std::istream& in)
return node;
}
-node_t * parse_logic_expr(std::istream& in)
+value_expr_t * parse_logic_expr(std::istream& in)
{
- node_t * node = NULL;
+ value_expr_t * node = NULL;
if (peek_next_nonws(in) == '!') {
char c;
in.get(c);
- node = new node_t(node_t::O_NOT);
+ node = new value_expr_t(value_expr_t::O_NOT);
node->left = parse_logic_expr(in);
return node;
}
@@ -610,19 +573,19 @@ node_t * parse_logic_expr(std::istream& in)
in.get(c);
switch (c) {
case '=': {
- node_t * prev = node;
- node = new node_t(node_t::O_EQ);
+ value_expr_t * prev = node;
+ node = new value_expr_t(value_expr_t::O_EQ);
node->left = prev;
node->right = parse_add_expr(in);
break;
}
case '<': {
- node_t * prev = node;
- node = new node_t(node_t::O_LT);
+ value_expr_t * prev = node;
+ node = new value_expr_t(value_expr_t::O_LT);
if (peek_next_nonws(in) == '=') {
in.get(c);
- node->type = node_t::O_LTE;
+ node->type = value_expr_t::O_LTE;
}
node->left = prev;
node->right = parse_add_expr(in);
@@ -630,11 +593,11 @@ node_t * parse_logic_expr(std::istream& in)
}
case '>': {
- node_t * prev = node;
- node = new node_t(node_t::O_GT);
+ value_expr_t * prev = node;
+ node = new value_expr_t(value_expr_t::O_GT);
if (peek_next_nonws(in) == '=') {
in.get(c);
- node->type = node_t::O_GTE;
+ node->type = value_expr_t::O_GTE;
}
node->left = prev;
node->right = parse_add_expr(in);
@@ -654,9 +617,9 @@ node_t * parse_logic_expr(std::istream& in)
return node;
}
-node_t * parse_expr(std::istream& in)
+value_expr_t * parse_value_expr(std::istream& in)
{
- node_t * node = NULL;
+ value_expr_t * node = NULL;
node = parse_logic_expr(in);
@@ -666,26 +629,26 @@ node_t * parse_expr(std::istream& in)
in.get(c);
switch (c) {
case '&': {
- node_t * prev = node;
- node = new node_t(node_t::O_AND);
+ value_expr_t * prev = node;
+ node = new value_expr_t(value_expr_t::O_AND);
node->left = prev;
node->right = parse_logic_expr(in);
break;
}
case '|': {
- node_t * prev = node;
- node = new node_t(node_t::O_OR);
+ value_expr_t * prev = node;
+ node = new value_expr_t(value_expr_t::O_OR);
node->left = prev;
node->right = parse_logic_expr(in);
break;
}
case '?': {
- node_t * prev = node;
- node = new node_t(node_t::O_QUES);
+ value_expr_t * prev = node;
+ node = new value_expr_t(value_expr_t::O_QUES);
node->left = prev;
- node_t * choices = new node_t(node_t::O_COL);
+ value_expr_t * choices = new value_expr_t(value_expr_t::O_COL);
node->right = choices;
choices->left = parse_logic_expr(in);
c = peek_next_nonws(in);
@@ -756,128 +719,128 @@ std::string regexps_to_predicate(std::list<std::string>::const_iterator begin,
#ifdef DEBUG_ENABLED
-void dump_tree(std::ostream& out, const node_t * node)
+void dump_value_expr(std::ostream& out, const value_expr_t * node)
{
switch (node->type) {
- case node_t::CONSTANT_A:
+ case value_expr_t::CONSTANT_A:
out << "CONST[" << node->constant_a << "]";
break;
- case node_t::CONSTANT_T:
+ case value_expr_t::CONSTANT_T:
out << "DATE/TIME[" << node->constant_t << "]";
break;
- case node_t::AMOUNT: out << "AMOUNT"; break;
- case node_t::COST: out << "COST"; break;
- case node_t::DATE: out << "DATE"; break;
- case node_t::CLEARED: out << "CLEARED"; break;
- case node_t::REAL: out << "REAL"; break;
- case node_t::INDEX: out << "INDEX"; break;
- case node_t::BALANCE: out << "BALANCE"; break;
- case node_t::COST_BALANCE: out << "COST_BALANCE"; break;
- case node_t::TOTAL: out << "TOTAL"; break;
- case node_t::COST_TOTAL: out << "COST_TOTAL"; break;
+ case value_expr_t::AMOUNT: out << "AMOUNT"; break;
+ case value_expr_t::COST: out << "COST"; break;
+ case value_expr_t::DATE: out << "DATE"; break;
+ case value_expr_t::CLEARED: out << "CLEARED"; break;
+ case value_expr_t::REAL: out << "REAL"; break;
+ case value_expr_t::INDEX: out << "INDEX"; break;
+ case value_expr_t::BALANCE: out << "BALANCE"; break;
+ case value_expr_t::COST_BALANCE: out << "COST_BALANCE"; break;
+ case value_expr_t::TOTAL: out << "TOTAL"; break;
+ case value_expr_t::COST_TOTAL: out << "COST_TOTAL"; break;
- case node_t::F_ARITH_MEAN:
+ case value_expr_t::F_ARITH_MEAN:
out << "MEAN(";
- dump_tree(out, node->left);
+ dump_value_expr(out, node->left);
out << ")";
break;
- case node_t::F_NEG:
+ case value_expr_t::F_NEG:
out << "ABS(";
- dump_tree(out, node->left);
+ dump_value_expr(out, node->left);
out << ")";
break;
- case node_t::F_ABS:
+ case value_expr_t::F_ABS:
out << "ABS(";
- dump_tree(out, node->left);
+ dump_value_expr(out, node->left);
out << ")";
break;
- case node_t::F_PAYEE_MASK:
+ case value_expr_t::F_PAYEE_MASK:
assert(node->mask);
out << "P_MASK(" << node->mask->pattern << ")";
break;
- case node_t::F_ACCOUNT_MASK:
+ case value_expr_t::F_ACCOUNT_MASK:
assert(node->mask);
out << "A_MASK(" << node->mask->pattern << ")";
break;
- case node_t::F_VALUE:
+ case value_expr_t::F_VALUE:
out << "VALUE(";
- dump_tree(out, node->left);
+ dump_value_expr(out, node->left);
if (node->right) {
out << ", ";
- dump_tree(out, node->right);
+ dump_value_expr(out, node->right);
}
out << ")";
break;
- case node_t::O_NOT:
+ case value_expr_t::O_NOT:
out << "!";
- dump_tree(out, node->left);
+ dump_value_expr(out, node->left);
break;
- case node_t::O_QUES:
- dump_tree(out, node->left);
+ case value_expr_t::O_QUES:
+ dump_value_expr(out, node->left);
out << "?";
- dump_tree(out, node->right->left);
+ dump_value_expr(out, node->right->left);
out << ":";
- dump_tree(out, node->right->right);
+ dump_value_expr(out, node->right->right);
break;
- case node_t::O_AND:
- case node_t::O_OR:
+ case value_expr_t::O_AND:
+ case value_expr_t::O_OR:
out << "(";
- dump_tree(out, node->left);
+ dump_value_expr(out, node->left);
switch (node->type) {
- case node_t::O_AND: out << " & "; break;
- case node_t::O_OR: out << " | "; break;
+ case value_expr_t::O_AND: out << " & "; break;
+ case value_expr_t::O_OR: out << " | "; break;
default: assert(0); break;
}
- dump_tree(out, node->right);
+ dump_value_expr(out, node->right);
out << ")";
break;
- case node_t::O_EQ:
- case node_t::O_LT:
- case node_t::O_LTE:
- case node_t::O_GT:
- case node_t::O_GTE:
+ case value_expr_t::O_EQ:
+ case value_expr_t::O_LT:
+ case value_expr_t::O_LTE:
+ case value_expr_t::O_GT:
+ case value_expr_t::O_GTE:
out << "(";
- dump_tree(out, node->left);
+ dump_value_expr(out, node->left);
switch (node->type) {
- case node_t::O_EQ: out << "="; break;
- case node_t::O_LT: out << "<"; break;
- case node_t::O_LTE: out << "<="; break;
- case node_t::O_GT: out << ">"; break;
- case node_t::O_GTE: out << ">="; break;
+ case value_expr_t::O_EQ: out << "="; break;
+ case value_expr_t::O_LT: out << "<"; break;
+ case value_expr_t::O_LTE: out << "<="; break;
+ case value_expr_t::O_GT: out << ">"; break;
+ case value_expr_t::O_GTE: out << ">="; break;
default: assert(0); break;
}
- dump_tree(out, node->right);
+ dump_value_expr(out, node->right);
out << ")";
break;
- case node_t::O_ADD:
- case node_t::O_SUB:
- case node_t::O_MUL:
- case node_t::O_DIV:
+ case value_expr_t::O_ADD:
+ case value_expr_t::O_SUB:
+ case value_expr_t::O_MUL:
+ case value_expr_t::O_DIV:
out << "(";
- dump_tree(out, node->left);
+ dump_value_expr(out, node->left);
switch (node->type) {
- case node_t::O_ADD: out << "+"; break;
- case node_t::O_SUB: out << "-"; break;
- case node_t::O_MUL: out << "*"; break;
- case node_t::O_DIV: out << "/"; break;
+ case value_expr_t::O_ADD: out << "+"; break;
+ case value_expr_t::O_SUB: out << "-"; break;
+ case value_expr_t::O_MUL: out << "*"; break;
+ case value_expr_t::O_DIV: out << "/"; break;
default: assert(0); break;
}
- dump_tree(out, node->right);
+ dump_value_expr(out, node->right);
out << ")";
break;
- case node_t::LAST:
+ case value_expr_t::LAST:
default:
assert(0);
break;
@@ -892,7 +855,7 @@ void dump_tree(std::ostream& out, const node_t * node)
int main(int argc, char *argv[])
{
- ledger::dump_tree(std::cout, ledger::parse_expr(argv[1]));
+ ledger::dump_value_exp(std::cout, ledger::parse_value_expr(argv[1]));
std::cout << std::endl;
}