susumu.yata
null+****@clear*****
Fri Feb 13 13:01:17 JST 2015
susumu.yata 2015-02-13 13:01:17 +0900 (Fri, 13 Feb 2015) New Revision: 83517e6371f1de23c0c71643b3a53b6c9929b131 https://github.com/groonga/grnxx/commit/83517e6371f1de23c0c71643b3a53b6c9929b131 Message: Update Expression::parse() to support "From.To". (#143) Modified files: lib/grnxx/impl/expression.cpp test/test_expression.cpp Modified: lib/grnxx/impl/expression.cpp (+22 -5) =================================================================== --- lib/grnxx/impl/expression.cpp 2015-02-13 10:47:10 +0900 (4b8d477) +++ lib/grnxx/impl/expression.cpp 2015-02-13 13:01:17 +0900 (a1e73d1) @@ -2845,7 +2845,12 @@ void ExpressionParser::push_token(const ExpressionToken &token) { // 前方にある優先度の高い演算子を適用する. while (stack_.size() >= 2) { ExpressionToken operator_token = stack_[stack_.size() - 2]; - if (operator_token.type() == UNARY_OPERATOR_TOKEN) { + if (operator_token.type() == DEREFERENCE_TOKEN) { + builder_->end_subexpression(); + stack_.pop_back(); + stack_.pop_back(); + push_token(ExpressionToken("", DUMMY_TOKEN)); + } else if (operator_token.type() == UNARY_OPERATOR_TOKEN) { builder_->push_operator(operator_token.operator_type()); stack_.pop_back(); stack_.pop_back(); @@ -2865,8 +2870,10 @@ void ExpressionParser::push_token(const ExpressionToken &token) { break; } case DEREFERENCE_TOKEN: { - // TODO: Not supported yet. - throw "Not supported yet"; + builder_->begin_subexpression(); + stack_.pop_back(); + stack_.push_back(token); + break; } case BRACKET_TOKEN: { if (token.bracket_type() == LEFT_ROUND_BRACKET) { @@ -2883,7 +2890,12 @@ void ExpressionParser::push_token(const ExpressionToken &token) { // 括弧内にある演算子をすべて解決する. while (stack_.size() >= 2) { ExpressionToken operator_token = stack_[stack_.size() - 2]; - if (operator_token.type() == UNARY_OPERATOR_TOKEN) { + if (operator_token.type() == DEREFERENCE_TOKEN) { + builder_->end_subexpression(); + stack_.pop_back(); + stack_.pop_back(); + push_token(ExpressionToken("", DUMMY_TOKEN)); + } else if (operator_token.type() == UNARY_OPERATOR_TOKEN) { builder_->push_operator(operator_token.operator_type()); stack_.pop_back(); stack_.pop_back(); @@ -2919,7 +2931,12 @@ void ExpressionParser::push_token(const ExpressionToken &token) { // 括弧内にある演算子をすべて解決する. while (stack_.size() >= 2) { ExpressionToken operator_token = stack_[stack_.size() - 2]; - if (operator_token.type() == UNARY_OPERATOR_TOKEN) { + if (operator_token.type() == DEREFERENCE_TOKEN) { + builder_->end_subexpression(); + stack_.pop_back(); + stack_.pop_back(); + push_token(ExpressionToken("", DUMMY_TOKEN)); + } else if (operator_token.type() == UNARY_OPERATOR_TOKEN) { builder_->push_operator(operator_token.operator_type()); stack_.pop_back(); stack_.pop_back(); Modified: test/test_expression.cpp (+30 -6) =================================================================== --- test/test_expression.cpp 2015-02-13 10:47:10 +0900 (53d8cf6) +++ test/test_expression.cpp 2015-02-13 13:01:17 +0900 (e4222d2) @@ -2749,12 +2749,10 @@ void test_subexpression() { } void test_parser() try { - // Create an expression. + // Test an expression (Int < Int2 && Float >= Float2). auto expression = grnxx::Expression::parse( test.table, "Int < Int2 && Float >= Float2"); - auto records = create_input_records(); - grnxx::Array<grnxx::Bool> bool_results; expression->evaluate(records, &bool_results); assert(bool_results.size() == test.table->num_rows()); @@ -2765,11 +2763,9 @@ void test_parser() try { (test.float_values[row_id] >= test.float2_values[row_id]))); } - // Create an expression. + // Test an expression (FloatVector[Int + Int2]) expression = grnxx::Expression::parse(test.table, "FloatVector[Int + Int2]"); - records = create_input_records(); - grnxx::Array<grnxx::Float> float_results; expression->evaluate(records, &float_results); assert(float_results.size() == test.table->num_rows()); @@ -2779,6 +2775,34 @@ void test_parser() try { const auto &float_vector_value = test.float_vector_values[row_id]; assert(float_results[i].match(float_vector_value[sum])); } + + // Test an expression (Ref.Ref.Text). + expression = grnxx::Expression::parse(test.table, "Ref.Ref.Text"); + records = create_input_records(); + grnxx::Array<grnxx::Text> text_results; + expression->evaluate(records, &text_results); + assert(text_results.size() == test.table->num_rows()); + for (size_t i = 0; i < text_results.size(); ++i) { + size_t row_id = records[i].row_id.raw(); + const auto ref_value = test.ref_values[row_id]; + const auto ref_ref_value = test.ref_values[ref_value.raw()]; + const auto text_value = test.text_values[ref_ref_value.raw()]; + assert(text_results[i].match(text_value)); + } + + // Test an expression (Int + Ref.Int2 * Int). + expression = grnxx::Expression::parse(test.table, "Int + Ref.Int2 * Int"); + records = create_input_records(); + grnxx::Array<grnxx::Int> int_results; + expression->evaluate(records, &int_results); + assert(int_results.size() == test.table->num_rows()); + for (size_t i = 0; i < int_results.size(); ++i) { + size_t row_id = records[i].row_id.raw(); + const auto int_value = test.int_values[row_id]; + const auto ref_value = test.ref_values[row_id]; + const auto ref_int2_value = test.int2_values[ref_value.raw()]; + assert(int_results[i].match(int_value + (ref_int2_value * int_value))); + } } catch (const char *msg) { std::cerr << "msg: " << msg << std::endl; throw; -------------- next part -------------- HTML����������������������������... 다운로드