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:
parent
dfe04b9943
commit
6bd82c6bcd
1 changed files with 54 additions and 43 deletions
|
|
@ -756,27 +756,31 @@ xact_t * textual_parser_t::instance_t::parse_xact(char * line,
|
||||||
goto parse_assign;
|
goto parse_assign;
|
||||||
|
|
||||||
beg = in.tellg();
|
beg = in.tellg();
|
||||||
|
|
||||||
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;
|
saw_amount = true;
|
||||||
|
|
||||||
if (! xact->amount.is_null()) {
|
if (p != '(') { // indicates a value expression
|
||||||
xact->amount.reduce();
|
xact->amount.parse(in, amount_t::PARSE_NO_REDUCE);
|
||||||
DEBUG("textual.parse", "line " << linenum << ": " <<
|
} else {
|
||||||
"Reduced amount is " << xact->amount);
|
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));
|
||||||
|
|
||||||
// We don't need to store the actual expression that resulted in the
|
if (! xact->amount.is_null()) {
|
||||||
// amount if it's constant
|
xact->amount.reduce();
|
||||||
if (xact->amount_expr) {
|
DEBUG("textual.parse", "line " << linenum << ": " <<
|
||||||
if (xact->amount_expr->is_constant())
|
"Reduced amount is " << xact->amount);
|
||||||
xact->amount_expr = expr_t();
|
}
|
||||||
|
|
||||||
end = in.tellg();
|
// We don't need to store the actual expression that resulted in the
|
||||||
xact->amount_expr->set_text(string(line, long(beg), long(end - beg)));
|
// amount if it's constant
|
||||||
|
if (xact->amount_expr) {
|
||||||
|
if (xact->amount_expr->is_constant())
|
||||||
|
xact->amount_expr = expr_t();
|
||||||
|
|
||||||
|
end = in.tellg();
|
||||||
|
xact->amount_expr->set_text(string(line, long(beg), long(end - beg)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -786,8 +790,7 @@ xact_t * textual_parser_t::instance_t::parse_xact(char * line,
|
||||||
p = peek_next_nonws(in);
|
p = peek_next_nonws(in);
|
||||||
if (p == '@') {
|
if (p == '@') {
|
||||||
if (! saw_amount)
|
if (! saw_amount)
|
||||||
throw parse_error
|
throw parse_error("Transaction cannot have a cost without an amount");
|
||||||
("Transaction cannot have a cost expression with an amount");
|
|
||||||
|
|
||||||
DEBUG("textual.parse", "line " << linenum << ": " <<
|
DEBUG("textual.parse", "line " << linenum << ": " <<
|
||||||
"Found a price indicator");
|
"Found a price indicator");
|
||||||
|
|
@ -805,19 +808,23 @@ xact_t * textual_parser_t::instance_t::parse_xact(char * line,
|
||||||
|
|
||||||
beg = in.tellg();
|
beg = in.tellg();
|
||||||
|
|
||||||
xact->cost_expr =
|
if (p != '(') { // indicates a value expression
|
||||||
parse_amount_expr(in, *xact->cost, xact.get(),
|
xact->cost->parse(in, amount_t::PARSE_NO_MIGRATE);
|
||||||
static_cast<uint_least8_t>(expr_t::PARSE_NO_MIGRATE) |
|
} else {
|
||||||
static_cast<uint_least8_t>(expr_t::PARSE_NO_ASSIGN));
|
xact->cost_expr =
|
||||||
|
parse_amount_expr(in, *xact->cost, xact.get(),
|
||||||
|
static_cast<uint_least8_t>(expr_t::PARSE_NO_MIGRATE) |
|
||||||
|
static_cast<uint_least8_t>(expr_t::PARSE_NO_ASSIGN));
|
||||||
|
|
||||||
if (xact->cost_expr) {
|
if (xact->cost_expr) {
|
||||||
end = in.tellg();
|
end = in.tellg();
|
||||||
if (per_unit)
|
if (per_unit)
|
||||||
xact->cost_expr->set_text(string("@") +
|
xact->cost_expr->set_text(string("@") +
|
||||||
string(line, long(beg), long(end - beg)));
|
string(line, long(beg), long(end - beg)));
|
||||||
else
|
else
|
||||||
xact->cost_expr->set_text(string("@@") +
|
xact->cost_expr->set_text(string("@@") +
|
||||||
string(line, long(beg), long(end - beg)));
|
string(line, long(beg), long(end - beg)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xact->cost->sign() < 0)
|
if (xact->cost->sign() < 0)
|
||||||
|
|
@ -857,21 +864,25 @@ xact_t * textual_parser_t::instance_t::parse_xact(char * line,
|
||||||
|
|
||||||
beg = in.tellg();
|
beg = in.tellg();
|
||||||
|
|
||||||
xact->assigned_amount_expr =
|
if (p != '(') { // indicates a value expression
|
||||||
parse_amount_expr(in, *xact->assigned_amount, xact.get(),
|
xact->assigned_amount->parse(in, amount_t::PARSE_NO_MIGRATE);
|
||||||
static_cast<uint_least8_t>(expr_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));
|
||||||
|
|
||||||
if (xact->assigned_amount->is_null())
|
if (xact->assigned_amount->is_null())
|
||||||
throw parse_error
|
throw parse_error
|
||||||
("An assigned balance must evaluate to a constant value");
|
("An assigned balance must evaluate to a constant value");
|
||||||
|
|
||||||
DEBUG("textual.parse", "line " << linenum << ": " <<
|
DEBUG("textual.parse", "line " << linenum << ": " <<
|
||||||
"XACT assign: parsed amt = " << *xact->assigned_amount);
|
"XACT assign: parsed amt = " << *xact->assigned_amount);
|
||||||
|
|
||||||
if (xact->assigned_amount_expr) {
|
if (xact->assigned_amount_expr) {
|
||||||
end = in.tellg();
|
end = in.tellg();
|
||||||
xact->assigned_amount_expr->set_text
|
xact->assigned_amount_expr->set_text
|
||||||
(string("=") + string(line, long(beg), long(end - beg)));
|
(string("=") + string(line, long(beg), long(end - beg)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
account_t::xdata_t& xdata(xact->account->xdata());
|
account_t::xdata_t& xdata(xact->account->xdata());
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue