susumu.yata
null+****@clear*****
Mon Feb 9 18:40:48 JST 2015
susumu.yata 2015-02-09 18:40:48 +0900 (Mon, 09 Feb 2015) New Revision: f0c103914b70c6168dc74de8b0682fe7521e1938 https://github.com/groonga/grnxx/commit/f0c103914b70c6168dc74de8b0682fe7521e1938 Message: Add a stub of ExpressionParser. (#143) Modified files: include/grnxx/constants.h include/grnxx/expression.hpp lib/grnxx/expression.cpp lib/grnxx/impl/expression.cpp lib/grnxx/impl/expression.hpp Modified: include/grnxx/constants.h (+26 -26) =================================================================== --- include/grnxx/constants.h 2015-02-09 14:48:59 +0900 (c056390) +++ include/grnxx/constants.h 2015-02-09 18:40:48 +0900 (6854a1b) @@ -47,55 +47,55 @@ typedef enum { typedef enum { // -- Unary operators -- - GRNXX_LOGICAL_NOT, // For Bool. + GRNXX_LOGICAL_NOT, // For Bool (!x). - GRNXX_BITWISE_NOT, // For Bool, Int. + GRNXX_BITWISE_NOT, // For Bool, Int (~x). - GRNXX_POSITIVE, // For Int, Float. - GRNXX_NEGATIVE, // For Int, Float. + GRNXX_POSITIVE, // For Int, Float (+x). + GRNXX_NEGATIVE, // For Int, Float (-x). // Typecast operators. // GRNXX_TO_BOOL, - GRNXX_TO_INT, // For Float. - GRNXX_TO_FLOAT, // For Int. + GRNXX_TO_INT, // For Float (Int x). + GRNXX_TO_FLOAT, // For Int (Float x). // GRNXX_TO_GEO_POINT, // GRNXX_TO_TEXT, // -- Binary operators -- // Logical operators. - GRNXX_LOGICAL_AND, // For Bool. - GRNXX_LOGICAL_OR, // For Bool. + GRNXX_LOGICAL_AND, // For Bool (x && y). + GRNXX_LOGICAL_OR, // For Bool (x || y). // Equality operators. - GRNXX_EQUAL, // For any types. - GRNXX_NOT_EQUAL, // For any types. + GRNXX_EQUAL, // For any types (x == y). + GRNXX_NOT_EQUAL, // For any types (x != y). // Comparison operators. - GRNXX_LESS, // Int, Float, Text. - GRNXX_LESS_EQUAL, // Int, Float, Text. - GRNXX_GREATER, // Int, Float, Text. - GRNXX_GREATER_EQUAL, // Int, Float, Text. + GRNXX_LESS, // Int, Float, Text (x < y). + GRNXX_LESS_EQUAL, // Int, Float, Text (x <= y). + GRNXX_GREATER, // Int, Float, Text (x > y). + GRNXX_GREATER_EQUAL, // Int, Float, Text (x >= y). // Bitwise operators. - GRNXX_BITWISE_AND, // For Bool, Int. - GRNXX_BITWISE_OR, // For Bool, Int. - GRNXX_BITWISE_XOR, // For Bool, Int. + GRNXX_BITWISE_AND, // For Bool, Int (x & y). + GRNXX_BITWISE_OR, // For Bool, Int (x | y). + GRNXX_BITWISE_XOR, // For Bool, Int (x ^ y). // Arithmetic operators. - GRNXX_PLUS, // For Int, Float. - GRNXX_MINUS, // For Int, Float. - GRNXX_MULTIPLICATION, // For Int, Float. - GRNXX_DIVISION, // For Int, Float. - GRNXX_MODULUS, // For Int. + GRNXX_PLUS, // For Int, Float (x + y). + GRNXX_MINUS, // For Int, Float (x - y). + GRNXX_MULTIPLICATION, // For Int, Float (x * y). + GRNXX_DIVISION, // For Int, Float (x / y). + GRNXX_MODULUS, // For Int, Float (x % y). // Search operators. - GRNXX_STARTS_WITH, // For Text. - GRNXX_ENDS_WITH, // For Text. - GRNXX_CONTAINS, // For Text. + GRNXX_STARTS_WITH, // For Text (x @^ y). + GRNXX_ENDS_WITH, // For Text (x @$ y). + GRNXX_CONTAINS, // For Text (x @ y). // Vector operators. - GRNXX_SUBSCRIPT, + GRNXX_SUBSCRIPT, // For Vector (x[y]). // -- TODO: Ternary operators -- } grnxx_operator_type; Modified: include/grnxx/expression.hpp (+6 -0) =================================================================== --- include/grnxx/expression.hpp 2015-02-09 14:48:59 +0900 (6839007) +++ include/grnxx/expression.hpp 2015-02-09 18:40:48 +0900 (a9185a2) @@ -140,6 +140,12 @@ class Expression { ArrayRef<Vector<GeoPoint>> results) = 0; virtual void evaluate(ArrayCRef<Record> records, ArrayRef<Vector<Text>> results) = 0; + + // Parse "query" and create an expression. + // + // On success, returns the expression. + // On failure, throws an exception. + static std::unique_ptr<Expression> parse(const String &query); }; class ExpressionBuilder { Modified: lib/grnxx/expression.cpp (+4 -0) =================================================================== --- lib/grnxx/expression.cpp 2015-02-09 14:48:59 +0900 (e14c841) +++ lib/grnxx/expression.cpp 2015-02-09 18:40:48 +0900 (5763b58) @@ -6,6 +6,10 @@ namespace grnxx { +std::unique_ptr<Expression> Expression::parse(const String &query) { + return impl::ExpressionParser::parse(query); +} + std::unique_ptr<ExpressionBuilder> ExpressionBuilder::create( const Table *table) try { return std::unique_ptr<ExpressionBuilder>( Modified: lib/grnxx/impl/expression.cpp (+117 -0) =================================================================== --- lib/grnxx/impl/expression.cpp 2015-02-09 14:48:59 +0900 (6ed06fe) +++ lib/grnxx/impl/expression.cpp 2015-02-09 18:40:48 +0900 (033d4a8) @@ -2477,5 +2477,122 @@ Node *ExpressionBuilder::create_dereference_node( } } +// -- ExpressionParser -- + +ExpressionTokenType ExpressionToken::get_operator_token_type( + OperatorType operator_type) { + switch (operator_type) { + case GRNXX_LOGICAL_NOT: + case GRNXX_BITWISE_NOT: + case GRNXX_POSITIVE: + case GRNXX_NEGATIVE: + case GRNXX_TO_INT: + case GRNXX_TO_FLOAT: { + return UNARY_OPERATOR_TOKEN; + } + case GRNXX_LOGICAL_AND: + case GRNXX_LOGICAL_OR: + case GRNXX_EQUAL: + case GRNXX_NOT_EQUAL: + case GRNXX_LESS: + case GRNXX_LESS_EQUAL: + case GRNXX_GREATER: + case GRNXX_GREATER_EQUAL: + case GRNXX_BITWISE_AND: + case GRNXX_BITWISE_OR: + case GRNXX_BITWISE_XOR: + case GRNXX_PLUS: + case GRNXX_MINUS: + case GRNXX_MULTIPLICATION: + case GRNXX_DIVISION: + case GRNXX_MODULUS: + case GRNXX_STARTS_WITH: + case GRNXX_ENDS_WITH: + case GRNXX_CONTAINS: + case GRNXX_SUBSCRIPT: { + return BINARY_OPERATOR_TOKEN; + } + default: { + throw "Unsupported operator type"; + } + } +} + +int ExpressionToken::get_operator_priority(OperatorType operator_type) { + switch (operator_type) { + case GRNXX_LOGICAL_NOT: + case GRNXX_BITWISE_NOT: + case GRNXX_POSITIVE: + case GRNXX_NEGATIVE: + case GRNXX_TO_INT: + case GRNXX_TO_FLOAT: { + return 3; + } + case GRNXX_LOGICAL_AND: { + return 13; + } + case GRNXX_LOGICAL_OR: { + return 14; + } + case GRNXX_EQUAL: + case GRNXX_NOT_EQUAL: { + return 9; + } + case GRNXX_LESS: + case GRNXX_LESS_EQUAL: + case GRNXX_GREATER: + case GRNXX_GREATER_EQUAL: { + return 8; + } + case GRNXX_BITWISE_AND: { + return 10; + } + case GRNXX_BITWISE_OR: { + return 12; + } + case GRNXX_BITWISE_XOR: { + return 11; + } + case GRNXX_PLUS: + case GRNXX_MINUS: { + return 6; + } + case GRNXX_MULTIPLICATION: + case GRNXX_DIVISION: + case GRNXX_MODULUS: { + return 5; + } + case GRNXX_STARTS_WITH: + case GRNXX_ENDS_WITH: + case GRNXX_CONTAINS: { + return 7; + } + case GRNXX_SUBSCRIPT: { + return 2; + } + default: { + throw "Unsupported operator type"; + } + } +} + +std::unique_ptr<ExpressionInterface> ExpressionParser::parse( + const String &query) try { + std::unique_ptr<ExpressionParser> parser(new ExpressionParser); + parser->tokenize(query); + return parser->build(); +} catch (const std::bad_alloc &) { + throw "Memory allocation failed"; +} + +void ExpressionParser::tokenize(const String &query) { + // TODO +} + +std::unique_ptr<ExpressionInterface> ExpressionParser::build() { + // TODO + return builder_->release(); +} + } // namespace impl } // namespace grnxx Modified: lib/grnxx/impl/expression.hpp (+76 -1) =================================================================== --- lib/grnxx/impl/expression.hpp 2015-02-09 14:48:59 +0900 (d75829c) +++ lib/grnxx/impl/expression.hpp 2015-02-09 18:40:48 +0900 (1264847) @@ -106,7 +106,7 @@ class ExpressionBuilder : public ExpressionBuilderInterface { void clear(); std::unique_ptr<ExpressionInterface> release( - const ExpressionOptions &options); + const ExpressionOptions &options = ExpressionOptions()); private: const Table *table_; @@ -205,6 +205,81 @@ class ExpressionBuilder : public ExpressionBuilderInterface { const ExpressionOptions &options); }; +enum ExpressionTokenType { + NODE_TOKEN, + UNARY_OPERATOR_TOKEN, + BINARY_OPERATOR_TOKEN, + DEREFERENCE_TOKEN, + BRACKET_TOKEN +}; + +enum ExpressionBracketType { + LEFT_ROUND_BRACKET, + RIGHT_ROUND_BRACKET, + LEFT_SQUARE_BRACKET, + RIGHT_SQUARE_BRACKET +}; + +class ExpressionToken { + public: + ExpressionToken() : type_(NODE_TOKEN), dummy_(0), priority_(0) {} + explicit ExpressionToken(ExpressionTokenType token_type) + : type_(token_type), + dummy_(0), + priority_(0) {} + explicit ExpressionToken(ExpressionBracketType bracket_type) + : type_(BRACKET_TOKEN), + bracket_type_(bracket_type), + priority_(0) {} + explicit ExpressionToken(OperatorType operator_type) + : type_(get_operator_token_type(operator_type)), + operator_type_(operator_type), + priority_(get_operator_priority(operator_type)) {} + + ExpressionTokenType type() const { + return type_; + } + ExpressionBracketType bracket_type() const { + return bracket_type_; + } + OperatorType operator_type() const { + return operator_type_; + } + int priority() const { + return priority_; + } + + private: + ExpressionTokenType type_; + union { + int dummy_; + ExpressionBracketType bracket_type_; + OperatorType operator_type_; + }; + int priority_; + + static ExpressionTokenType get_operator_token_type( + OperatorType operator_type); + static int get_operator_priority(OperatorType operator_type); +}; + +class ExpressionParser { + public: + static std::unique_ptr<ExpressionInterface> parse(const String &query); + + ~ExpressionParser() = default; + + private: + Array<ExpressionToken> tokens_; + Array<ExpressionToken> stack_; + std::unique_ptr<ExpressionBuilder> builder_; + + ExpressionParser() = default; + + void tokenize(const String &query); + std::unique_ptr<ExpressionInterface> build(); +}; + } // namespace impl } // namespace grnxx -------------- next part -------------- HTML����������������������������... Download