static void lex_unget_unsave(lex_t *lex, char c) { char d; stream_unget(&lex->stream, c); d = strbuffer_pop(&lex->saved_text); assert(c == d); }
static void lex_unget_unsave(lex_t *lex, int c) { if(c != STREAM_STATE_EOF && c != STREAM_STATE_ERROR) { char d; stream_unget(&lex->stream, c); d = strbuffer_pop(&lex->saved_text); assert(c == d); } }
bool WhereMatcher::parse_or() { bool left = parse_not(); Token t = stream_get(); if (t.first == bool_or) { return left || parse_and(); } else { if (t.first != value_undefined_type) stream_unget(t); return left; } }
bool WhereMatcher::parse_not() { bool left = parse_conditional(); Token t = stream_get(); if (t.first == bool_not) { return !left; } else { if (t.first != value_undefined_type) stream_unget(t); return left; } }
static void lex_unget_unsave(lex_t *lex, int c) { if (c != STREAM_STATE_EOF && c != STREAM_STATE_ERROR) { uint32_t len; len = ph_string_len(&lex->saved_text); assert(len > 0 && lex->saved_text.buf[len-1] == c); lex->saved_text.len--; stream_unget(&lex->stream, c); } }
static void lex_unget_unsave(lex_t *lex, int c) { if(c != STREAM_STATE_EOF && c != STREAM_STATE_ERROR) { /* Since we treat warnings as errors, when assertions are turned * off the "d" variable would be set but never used. Which is * treated as an error by GCC. */ #ifndef NDEBUG char d; #endif stream_unget(&lex->stream, c); #ifndef NDEBUG d = #endif strbuffer_pop(&lex->saved_text); assert(c == d); } }
bool WhereMatcher::parse_conditional() { Token left_token = stream_get(); // handling of parenthesis if (left_token.first == parenthesis_left) { bool result = parse_and(); Token close_parenthesis = stream_get(); if (close_parenthesis.first != parenthesis_right) { throw QuerySyntaxError("Invalid syntax, missing closing parenthesis."); } else { return result; } } Token op_token = stream_get(); TokenType value_type = left_token.first; // the left side is an attribute_name, we need to look ahead for the type if (value_type == attribute_name) { Token right_token = stream_get(); value_type = right_token.first; stream_unget(right_token); } stream_unget(left_token); // In C++ you can't declare variables of the same name, even if they were // never actually declared, this is a really ugly fix, but if there is a way // to emulate some sort of dynamic typing C++, we could make this a lot better switch (op_token.first) { case conditional_eq: switch (value_type) { case value_numeral: return parse_value<float>() == parse_value<float>(); case value_varchar: case value_date: case value_time: return parse_value<string>().compare(parse_value<string>()) == 0; } case conditional_neq: switch (value_type) { case value_numeral: return parse_value<float>() != parse_value<float>(); case value_varchar: case value_date: case value_time: return parse_value<string>().compare(parse_value<string>()) != 0; } case conditional_lt: switch (value_type) { case value_numeral: return parse_value<float>() < parse_value<float>(); case value_varchar: case value_date: case value_time: return parse_value<string>().compare(parse_value<string>()) > 0; } case conditional_gt: switch (value_type) { case value_numeral: return parse_value<float>() > parse_value<float>(); case value_varchar: case value_date: case value_time: return parse_value<string>().compare(parse_value<string>()) < 0; } break; case conditional_lte: switch (value_type) { case value_numeral: return parse_value<float>() <= parse_value<float>(); case value_varchar: case value_date: case value_time: return parse_value<string>().compare(parse_value<string>()) >= 0; } break; case conditional_gte: switch (value_type) { case value_numeral: return parse_value<float>() >= parse_value<float>(); case value_varchar: case value_date: case value_time: return parse_value<string>().compare(parse_value<string>()) <= 0; } break; default: throw QuerySyntaxError("Unrecognized symbol: " + left_token.second); } throw QuerySyntaxError("Unknown type, internal error"); }
static void lex_unget(lex_t *lex, int c) { stream_unget(&lex->stream, c); }