Implemented a text parsing optimization.

Amounts, costs and assigned amounts are now parsed as regular amounts.  To
have a full value expression at any of those positions, surround it with
parentheses.  The reason for this is that the amount parser is far simpler and
quicker -- and by far the common case -- compared to the full expression
parser.
This commit is contained in:
John Wiegley 2009-02-03 17:47:02 -04:00
parent dfe04b9943
commit 6bd82c6bcd

View file

@ -756,12 +756,15 @@ xact_t * textual_parser_t::instance_t::parse_xact(char * line,
goto parse_assign;
beg = in.tellg();
saw_amount = true;
if (p != '(') { // indicates a value expression
xact->amount.parse(in, amount_t::PARSE_NO_REDUCE);
} else {
xact->amount_expr =
parse_amount_expr(in, xact->amount, xact.get(),
static_cast<uint_least8_t>(expr_t::PARSE_NO_REDUCE) |
static_cast<uint_least8_t>(expr_t::PARSE_NO_ASSIGN));
saw_amount = true;
if (! xact->amount.is_null()) {
xact->amount.reduce();
@ -779,6 +782,7 @@ xact_t * textual_parser_t::instance_t::parse_xact(char * line,
xact->amount_expr->set_text(string(line, long(beg), long(end - beg)));
}
}
}
// Parse the optional cost (@ PER-UNIT-COST, @@ TOTAL-COST)
@ -786,8 +790,7 @@ xact_t * textual_parser_t::instance_t::parse_xact(char * line,
p = peek_next_nonws(in);
if (p == '@') {
if (! saw_amount)
throw parse_error
("Transaction cannot have a cost expression with an amount");
throw parse_error("Transaction cannot have a cost without an amount");
DEBUG("textual.parse", "line " << linenum << ": " <<
"Found a price indicator");
@ -805,6 +808,9 @@ xact_t * textual_parser_t::instance_t::parse_xact(char * line,
beg = in.tellg();
if (p != '(') { // indicates a value expression
xact->cost->parse(in, amount_t::PARSE_NO_MIGRATE);
} else {
xact->cost_expr =
parse_amount_expr(in, *xact->cost, xact.get(),
static_cast<uint_least8_t>(expr_t::PARSE_NO_MIGRATE) |
@ -819,6 +825,7 @@ xact_t * textual_parser_t::instance_t::parse_xact(char * line,
xact->cost_expr->set_text(string("@@") +
string(line, long(beg), long(end - beg)));
}
}
if (xact->cost->sign() < 0)
throw parse_error("A transaction's cost may not be negative");
@ -857,6 +864,9 @@ xact_t * textual_parser_t::instance_t::parse_xact(char * line,
beg = in.tellg();
if (p != '(') { // indicates a value expression
xact->assigned_amount->parse(in, amount_t::PARSE_NO_MIGRATE);
} else {
xact->assigned_amount_expr =
parse_amount_expr(in, *xact->assigned_amount, xact.get(),
static_cast<uint_least8_t>(expr_t::PARSE_NO_MIGRATE));
@ -873,6 +883,7 @@ xact_t * textual_parser_t::instance_t::parse_xact(char * line,
xact->assigned_amount_expr->set_text
(string("=") + string(line, long(beg), long(end - beg)));
}
}
account_t::xdata_t& xdata(xact->account->xdata());
amount_t& amt(*xact->assigned_amount);