More work toward getting my ledger data to parse.

This commit is contained in:
John Wiegley 2008-07-22 03:48:35 -04:00
parent 4bc29e1351
commit f0f2b34ea9
5 changed files with 64 additions and 74 deletions

View file

@ -695,7 +695,7 @@ int amount_t::sign() const
bool amount_t::is_zero() const bool amount_t::is_zero() const
{ {
if (! quantity) if (! quantity)
throw_(amount_error, "Cannot determine sign if an uninitialized amount is zero"); throw_(amount_error, "Cannot determine if an uninitialized amount is zero");
if (has_commodity()) { if (has_commodity()) {
if (quantity->prec <= commodity().precision()) if (quantity->prec <= commodity().precision())

View file

@ -140,7 +140,8 @@ bool entry_base_t::finalize()
balance += p; balance += p;
} }
assert((*x)->amount); assert(! (*x)->amount.is_null());
if ((*x)->cost && (*x)->amount.commodity().annotated) { if ((*x)->cost && (*x)->amount.commodity().annotated) {
annotated_commodity_t& annotated_commodity_t&
ann_comm(static_cast<annotated_commodity_t&> ann_comm(static_cast<annotated_commodity_t&>
@ -222,7 +223,7 @@ bool entry_base_t::finalize()
for (transactions_list::const_iterator x = transactions.begin(); for (transactions_list::const_iterator x = transactions.begin();
x != transactions.end(); x != transactions.end();
x++) { x++) {
if ((*x)->amount || if (! (*x)->amount.is_null() ||
((*x)->has_flags(TRANSACTION_VIRTUAL) && ((*x)->has_flags(TRANSACTION_VIRTUAL) &&
! (*x)->has_flags(TRANSACTION_BALANCE))) ! (*x)->has_flags(TRANSACTION_BALANCE)))
continue; continue;

View file

@ -194,29 +194,17 @@ private:
ptr_op_t parse_value_expr(std::istream& in, scope_t& scope, ptr_op_t parse_value_expr(std::istream& in, scope_t& scope,
const flags_t flags) const; const flags_t flags) const;
void parse_expr(std::istream& in, string& str, value_expr& parse_expr(std::istream& in, string& str,
scope_t& scope, const flags_t flags) { scope_t& scope, const flags_t flags) {
try { try {
ptr_op_t top_node = parse_value_expr(in, scope, flags); ptr_op_t top_node = parse_value_expr(in, scope, flags);
expr = value_expr(top_node, str); expr = value_expr(top_node, str);
#if 0
// jww (2008-07-20): This code should no longer be needed, since we
// can't re-use parser_t anymore.
if (use_lookahead) { if (use_lookahead) {
use_lookahead = false; use_lookahead = false;
#ifdef THREADSAFE
lookahead.rewind(in); lookahead.rewind(in);
#else
lookahead->rewind(in);
#endif
} }
#ifdef THREADSAFE
lookahead.clear(); lookahead.clear();
#else
lookahead->clear();
#endif
#endif
} }
catch (error * err) { catch (error * err) {
err->context.push_back err->context.push_back
@ -224,44 +212,37 @@ private:
"While parsing value expression:")); "While parsing value expression:"));
throw err; throw err;
} }
return expr;
} }
public: public:
parser_t(std::istream& in, const flags_t flags = EXPR_PARSE_RELAXED) parser_t() : use_lookahead(false) {}
: use_lookahead(false)
{
TRACE_CTOR(parser_t, "std::istream&, const flags_t");
parse_expr(in, empty_string, *global_scope, flags);
}
parser_t(std::istream& in, const flags_t flags = EXPR_PARSE_RELAXED, scope_t& scope)
: use_lookahead(false)
{
TRACE_CTOR(parser_t, "std::istream&, const flags_t, scope_t&");
parse_expr(in, empty_string, scope, flags);
}
parser_t(string& str, const flags_t flags = EXPR_PARSE_RELAXED)
: use_lookahead(false)
{
TRACE_CTOR(parser_t, "string&, const flags_t");
value_expr& parse(std::istream& in,
const flags_t flags = EXPR_PARSE_RELAXED)
{
return parse_expr(in, empty_string, *global_scope, flags);
}
value_expr& parse(std::istream& in,
const flags_t flags = EXPR_PARSE_RELAXED,
scope_t& scope)
{
return parse_expr(in, empty_string, scope, flags);
}
value_expr& parse(string& str, const flags_t flags = EXPR_PARSE_RELAXED)
{
std::istringstream stream(str); std::istringstream stream(str);
parse_expr(stream, str, *global_scope, flags); return parse_expr(stream, str, *global_scope, flags);
} }
parser_t(string& str, const flags_t flags = EXPR_PARSE_RELAXED, scope_t& scope)
: use_lookahead(false) value_expr& parse(string& str, const flags_t flags = EXPR_PARSE_RELAXED,
scope_t& scope)
{ {
TRACE_CTOR(parser_t, "string&, const flags_t, scope_t&");
std::istringstream stream(str); std::istringstream stream(str);
parse_expr(stream, str, scope, flags); return parse_expr(stream, str, scope, flags);
}
~parser_t() throw() {
TRACE_DTOR(parser_t);
}
operator value_expr() const {
return expr;
} }
}; };

View file

@ -40,44 +40,48 @@ struct time_entry_t {
}; };
#endif #endif
static value_expr parse_amount_expr(std::istream& in, amount_t& amount, namespace {
transaction_t * xact, expr::parser_t amount_parser;
unsigned short flags = 0)
{
value_expr expr(expr::parser_t(in, flags | EXPR_PARSE_RELAXED |
EXPR_PARSE_PARTIAL));
DEBUG("ledger.textual.parse", "line " << linenum << ": " << static value_expr parse_amount_expr(std::istream& in, amount_t& amount,
"Parsed an amount expression"); transaction_t * xact,
unsigned short flags = 0)
{
value_expr expr =
amount_parser.parse(in, flags | EXPR_PARSE_RELAXED | EXPR_PARSE_PARTIAL);
DEBUG("ledger.textual.parse", "line " << linenum << ": " <<
"Parsed an amount expression");
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
DEBUG_IF("ledger.textual.parse") { DEBUG_IF("ledger.textual.parse") {
if (_debug_stream) { if (_debug_stream) {
ledger::dump_value_expr(*_debug_stream, expr); ledger::dump_value_expr(*_debug_stream, expr);
*_debug_stream << std::endl; *_debug_stream << std::endl;
}
} }
}
#endif #endif
if (! expr::compute_amount(expr, amount, xact)) if (! expr::compute_amount(expr, amount, xact))
throw new parse_error("Amount expression failed to compute"); throw new parse_error("Amount expression failed to compute");
#if 0 #if 0
if (expr->kind == expr::node_t::VALUE) { if (expr->kind == expr::node_t::VALUE) {
expr = NULL; expr = NULL;
} else { } else {
DEBUG_IF("ledger.textual.parse") { DEBUG_IF("ledger.textual.parse") {
std::cout << "Value expression tree:" << std::endl; std::cout << "Value expression tree:" << std::endl;
ledger::dump_value_expr(std::cout, expr.get()); ledger::dump_value_expr(std::cout, expr.get());
}
} }
}
#else #else
expr = value_expr(); expr = value_expr();
#endif #endif
DEBUG("ledger.textual.parse", "line " << linenum << ": " << DEBUG("ledger.textual.parse", "line " << linenum << ": " <<
"The transaction amount is " << xact->amount); "The transaction amount is " << xact->amount);
return expr; return expr;
}
} }
transaction_t * parse_transaction(char * line, account_t * account, transaction_t * parse_transaction(char * line, account_t * account,

View file

@ -1083,12 +1083,16 @@ value_t op_t::calc(scope_t& scope)
} // namespace expr } // namespace expr
namespace {
expr::parser_t value_expr_parser;
}
value_expr::value_expr(const string& _expr_str) : expr_str(_expr_str) value_expr::value_expr(const string& _expr_str) : expr_str(_expr_str)
{ {
TRACE_CTOR(value_expr, "const string&"); TRACE_CTOR(value_expr, "const string&");
if (! _expr_str.empty()) if (! _expr_str.empty())
ptr = expr::parser_t(expr_str).expr.ptr; ptr = value_expr_parser.parse(expr_str).ptr;
} }
} // namespace ledger } // namespace ledger