[Groonga-commit] groonga/grnxx at f0c1039 [master] Add a stub of ExpressionParser. (#143)

Back to archive index

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 



More information about the Groonga-commit mailing list
Back to archive index