Parse '/' in an operator context as "div"
This commit is contained in:
parent
fcd7f4f73b
commit
6f7f87699c
6 changed files with 22 additions and 24 deletions
|
|
@ -83,7 +83,8 @@ public:
|
||||||
PARSE_NO_MIGRATE = 0x04,
|
PARSE_NO_MIGRATE = 0x04,
|
||||||
PARSE_NO_REDUCE = 0x08,
|
PARSE_NO_REDUCE = 0x08,
|
||||||
PARSE_NO_ASSIGN = 0x10,
|
PARSE_NO_ASSIGN = 0x10,
|
||||||
PARSE_NO_DATES = 0x20
|
PARSE_NO_DATES = 0x20,
|
||||||
|
PARSE_OP_CONTEXT = 0x40
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -376,7 +376,7 @@ bool expr_t::op_t::print(std::ostream& out, const context_t& context) const
|
||||||
out << "(";
|
out << "(";
|
||||||
if (left() && left()->print(out, context))
|
if (left() && left()->print(out, context))
|
||||||
found = true;
|
found = true;
|
||||||
out << " // ";
|
out << " / ";
|
||||||
if (has_right() && right()->print(out, context))
|
if (has_right() && right()->print(out, context))
|
||||||
found = true;
|
found = true;
|
||||||
out << ")";
|
out << ")";
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ expr_t::parser_t::parse_value_term(std::istream& in,
|
||||||
node->set_ident(ident);
|
node->set_ident(ident);
|
||||||
|
|
||||||
// An identifier followed by ( represents a function call
|
// An identifier followed by ( represents a function call
|
||||||
tok = next_token(in, tflags);
|
tok = next_token(in, tflags.plus_flags(PARSE_OP_CONTEXT));
|
||||||
if (tok.kind == token_t::LPAREN) {
|
if (tok.kind == token_t::LPAREN) {
|
||||||
ptr_op_t call_node(new op_t(op_t::O_CALL));
|
ptr_op_t call_node(new op_t(op_t::O_CALL));
|
||||||
call_node->set_left(node);
|
call_node->set_left(node);
|
||||||
|
|
@ -91,7 +91,7 @@ expr_t::parser_t::parse_dot_expr(std::istream& in,
|
||||||
|
|
||||||
if (node && ! tflags.has_flags(PARSE_SINGLE)) {
|
if (node && ! tflags.has_flags(PARSE_SINGLE)) {
|
||||||
while (true) {
|
while (true) {
|
||||||
token_t& tok = next_token(in, tflags);
|
token_t& tok = next_token(in, tflags.plus_flags(PARSE_OP_CONTEXT));
|
||||||
if (tok.kind == token_t::DOT) {
|
if (tok.kind == token_t::DOT) {
|
||||||
ptr_op_t prev(node);
|
ptr_op_t prev(node);
|
||||||
node = new op_t(op_t::O_LOOKUP);
|
node = new op_t(op_t::O_LOOKUP);
|
||||||
|
|
@ -170,9 +170,10 @@ expr_t::parser_t::parse_mul_expr(std::istream& in,
|
||||||
|
|
||||||
if (node && ! tflags.has_flags(PARSE_SINGLE)) {
|
if (node && ! tflags.has_flags(PARSE_SINGLE)) {
|
||||||
while (true) {
|
while (true) {
|
||||||
token_t& tok = next_token(in, tflags);
|
token_t& tok = next_token(in, tflags.plus_flags(PARSE_OP_CONTEXT));
|
||||||
|
|
||||||
if (tok.kind == token_t::STAR || tok.kind == token_t::KW_DIV) {
|
if (tok.kind == token_t::STAR || tok.kind == token_t::SLASH ||
|
||||||
|
tok.kind == token_t::KW_DIV) {
|
||||||
ptr_op_t prev(node);
|
ptr_op_t prev(node);
|
||||||
node = new op_t(tok.kind == token_t::STAR ?
|
node = new op_t(tok.kind == token_t::STAR ?
|
||||||
op_t::O_MUL : op_t::O_DIV);
|
op_t::O_MUL : op_t::O_DIV);
|
||||||
|
|
@ -199,7 +200,7 @@ expr_t::parser_t::parse_add_expr(std::istream& in,
|
||||||
|
|
||||||
if (node && ! tflags.has_flags(PARSE_SINGLE)) {
|
if (node && ! tflags.has_flags(PARSE_SINGLE)) {
|
||||||
while (true) {
|
while (true) {
|
||||||
token_t& tok = next_token(in, tflags);
|
token_t& tok = next_token(in, tflags.plus_flags(PARSE_OP_CONTEXT));
|
||||||
|
|
||||||
if (tok.kind == token_t::PLUS ||
|
if (tok.kind == token_t::PLUS ||
|
||||||
tok.kind == token_t::MINUS) {
|
tok.kind == token_t::MINUS) {
|
||||||
|
|
@ -231,7 +232,7 @@ expr_t::parser_t::parse_logic_expr(std::istream& in,
|
||||||
while (true) {
|
while (true) {
|
||||||
op_t::kind_t kind = op_t::LAST;
|
op_t::kind_t kind = op_t::LAST;
|
||||||
parse_flags_t _flags = tflags;
|
parse_flags_t _flags = tflags;
|
||||||
token_t& tok = next_token(in, tflags);
|
token_t& tok = next_token(in, tflags.plus_flags(PARSE_OP_CONTEXT));
|
||||||
bool negate = false;
|
bool negate = false;
|
||||||
|
|
||||||
switch (tok.kind) {
|
switch (tok.kind) {
|
||||||
|
|
@ -303,7 +304,7 @@ expr_t::parser_t::parse_and_expr(std::istream& in,
|
||||||
|
|
||||||
if (node && ! tflags.has_flags(PARSE_SINGLE)) {
|
if (node && ! tflags.has_flags(PARSE_SINGLE)) {
|
||||||
while (true) {
|
while (true) {
|
||||||
token_t& tok = next_token(in, tflags);
|
token_t& tok = next_token(in, tflags.plus_flags(PARSE_OP_CONTEXT));
|
||||||
|
|
||||||
if (tok.kind == token_t::KW_AND) {
|
if (tok.kind == token_t::KW_AND) {
|
||||||
ptr_op_t prev(node);
|
ptr_op_t prev(node);
|
||||||
|
|
@ -330,7 +331,7 @@ expr_t::parser_t::parse_or_expr(std::istream& in,
|
||||||
|
|
||||||
if (node && ! tflags.has_flags(PARSE_SINGLE)) {
|
if (node && ! tflags.has_flags(PARSE_SINGLE)) {
|
||||||
while (true) {
|
while (true) {
|
||||||
token_t& tok = next_token(in, tflags);
|
token_t& tok = next_token(in, tflags.plus_flags(PARSE_OP_CONTEXT));
|
||||||
|
|
||||||
if (tok.kind == token_t::KW_OR) {
|
if (tok.kind == token_t::KW_OR) {
|
||||||
ptr_op_t prev(node);
|
ptr_op_t prev(node);
|
||||||
|
|
@ -356,7 +357,7 @@ expr_t::parser_t::parse_querycolon_expr(std::istream& in,
|
||||||
ptr_op_t node(parse_or_expr(in, tflags));
|
ptr_op_t node(parse_or_expr(in, tflags));
|
||||||
|
|
||||||
if (node && ! tflags.has_flags(PARSE_SINGLE)) {
|
if (node && ! tflags.has_flags(PARSE_SINGLE)) {
|
||||||
token_t& tok = next_token(in, tflags);
|
token_t& tok = next_token(in, tflags.plus_flags(PARSE_OP_CONTEXT));
|
||||||
|
|
||||||
if (tok.kind == token_t::QUERY) {
|
if (tok.kind == token_t::QUERY) {
|
||||||
ptr_op_t prev(node);
|
ptr_op_t prev(node);
|
||||||
|
|
@ -367,7 +368,7 @@ expr_t::parser_t::parse_querycolon_expr(std::istream& in,
|
||||||
throw_(parse_error,
|
throw_(parse_error,
|
||||||
tok.symbol << " operator not followed by argument");
|
tok.symbol << " operator not followed by argument");
|
||||||
|
|
||||||
token_t& next_tok = next_token(in, tflags);
|
token_t& next_tok = next_token(in, tflags.plus_flags(PARSE_OP_CONTEXT));
|
||||||
if (next_tok.kind != token_t::COLON)
|
if (next_tok.kind != token_t::COLON)
|
||||||
next_tok.expected(':');
|
next_tok.expected(':');
|
||||||
|
|
||||||
|
|
@ -394,7 +395,7 @@ expr_t::parser_t::parse_value_expr(std::istream& in,
|
||||||
ptr_op_t node(parse_querycolon_expr(in, tflags));
|
ptr_op_t node(parse_querycolon_expr(in, tflags));
|
||||||
|
|
||||||
if (node && ! tflags.has_flags(PARSE_SINGLE)) {
|
if (node && ! tflags.has_flags(PARSE_SINGLE)) {
|
||||||
token_t& tok = next_token(in, tflags);
|
token_t& tok = next_token(in, tflags.plus_flags(PARSE_OP_CONTEXT));
|
||||||
|
|
||||||
if (tok.kind == token_t::COMMA) {
|
if (tok.kind == token_t::COMMA) {
|
||||||
ptr_op_t prev(node);
|
ptr_op_t prev(node);
|
||||||
|
|
@ -404,7 +405,7 @@ expr_t::parser_t::parse_value_expr(std::istream& in,
|
||||||
if (! node->right())
|
if (! node->right())
|
||||||
throw_(parse_error,
|
throw_(parse_error,
|
||||||
tok.symbol << " operator not followed by argument");
|
tok.symbol << " operator not followed by argument");
|
||||||
tok = next_token(in, tflags);
|
tok = next_token(in, tflags.plus_flags(PARSE_OP_CONTEXT));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tok.kind != token_t::TOK_EOF) {
|
if (tok.kind != token_t::TOK_EOF) {
|
||||||
|
|
|
||||||
|
|
@ -231,7 +231,7 @@ public:
|
||||||
OPTION(report_t, ansi_invert);
|
OPTION(report_t, ansi_invert);
|
||||||
|
|
||||||
OPTION_(report_t, average, DO() { // -A
|
OPTION_(report_t, average, DO() { // -A
|
||||||
parent->HANDLER(display_total_).set_expr("total//count");
|
parent->HANDLER(display_total_).set_expr("total/count");
|
||||||
});
|
});
|
||||||
|
|
||||||
OPTION(report_t, balance_format_);
|
OPTION(report_t, balance_format_);
|
||||||
|
|
|
||||||
11
src/token.cc
11
src/token.cc
|
|
@ -272,14 +272,9 @@ void expr_t::token_t::next(std::istream& in, const uint_least8_t pflags)
|
||||||
|
|
||||||
case '/': {
|
case '/': {
|
||||||
in.get(c);
|
in.get(c);
|
||||||
c = in.peek();
|
if (pflags & PARSE_OP_CONTEXT) { // operator context
|
||||||
if (c == '/') {
|
kind = SLASH;
|
||||||
in.get(c);
|
} else { // terminal context
|
||||||
symbol[1] = c;
|
|
||||||
symbol[2] = '\0';
|
|
||||||
kind = KW_DIV;
|
|
||||||
length = 2;
|
|
||||||
} else {
|
|
||||||
// Read in the regexp
|
// Read in the regexp
|
||||||
char buf[256];
|
char buf[256];
|
||||||
READ_INTO_(in, buf, 255, c, length, c != '/');
|
READ_INTO_(in, buf, 255, c, length, c != '/');
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,8 @@ struct expr_t::token_t : public noncopyable
|
||||||
MINUS, // -
|
MINUS, // -
|
||||||
PLUS, // +
|
PLUS, // +
|
||||||
STAR, // *
|
STAR, // *
|
||||||
KW_DIV, // /
|
SLASH, // /
|
||||||
|
KW_DIV, // div
|
||||||
|
|
||||||
EXCLAM, // !, not
|
EXCLAM, // !, not
|
||||||
KW_AND, // &, &&, and
|
KW_AND, // &, &&, and
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue