diff --git a/include/cql2cpp/ast_node.h b/include/cql2cpp/ast_node.h index 6872fad..839ff14 100644 --- a/include/cql2cpp/ast_node.h +++ b/include/cql2cpp/ast_node.h @@ -11,6 +11,7 @@ #pragma once #include +#include #include #include @@ -31,7 +32,7 @@ class AstNode { std::string id_; NodeType type_; Operator op_; - std::vector children_; + std::vector children_; ValueT origin_value_; mutable ValueT value_; static std::ostream* ous_; @@ -39,22 +40,22 @@ class AstNode { public: static void set_ostream(std::ostream* ous) { ous_ = ous; } - AstNode(NodeType type, Operator op, const std::vector children) + AstNode(NodeType type, Operator op, const std::vector children) : type_(type), op_(op), children_(children) { id_ = idg.Gen(); - *ous_ << "AstNode " << ToString() << std::endl; + LOG(INFO) << "AstNode " << ToString() << std::endl; } AstNode(NodeType type, const ValueT& value) : type_(type), op_(NullOp), origin_value_(value), value_(NullValue) { id_ = idg.Gen(); - *ous_ << "AstNode " << ToString() << std::endl; + LOG(INFO) << "AstNode " << ToString() << std::endl; } AstNode(const ValueT& value) : type_(Literal), op_(NullOp), origin_value_(value), value_(NullValue) { id_ = idg.Gen(); - *ous_ << "AstNode " << ToString() << std::endl; + LOG(INFO) << "AstNode " << ToString() << std::endl; } const std::string& id() const { return id_; } @@ -63,8 +64,8 @@ class AstNode { Operator op() const { return op_; } - const std::vector& children() const { return children_; } - void append(AstNode* node) { children_.emplace_back(node); } + const std::vector& children() const { return children_; } + void append(AstNodePtr node) { children_.emplace_back(node); } const ValueT& origin_value() const { return origin_value_; } ValueT value() const { return value_; } diff --git a/include/cql2cpp/cql2_parser.h b/include/cql2cpp/cql2_parser.h index bc2c5c4..61c51ab 100644 --- a/include/cql2cpp/cql2_parser.h +++ b/include/cql2cpp/cql2_parser.h @@ -17,7 +17,7 @@ class Cql2Parser : public cql2cpp::Cql2ParserBase { private: - cql2cpp::AstNode* root_; + cql2cpp::AstNodePtr root_; public: Cql2Parser() : cql2cpp::Cql2ParserBase(&root_) {} @@ -26,12 +26,5 @@ class Cql2Parser : public cql2cpp::Cql2ParserBase { LOG(ERROR) << "Cql2Parser Error: " << msg << std::endl; } - cql2cpp::AstNode* root() const { return root_; } - - void DeConstructRoot() { DeConstructAST(root_); } - - static void DeConstructAST(cql2cpp::AstNode* node) { - for (auto* child : node->children()) DeConstructAST(child); - delete node; - } + cql2cpp::AstNodePtr root() const { return root_; } }; diff --git a/include/cql2cpp/cql2cpp.h b/include/cql2cpp/cql2cpp.h index fc9f188..edc26f3 100644 --- a/include/cql2cpp/cql2cpp.h +++ b/include/cql2cpp/cql2cpp.h @@ -52,7 +52,7 @@ class Cql2Cpp { bool filter(const std::string& cql2_query, std::vector* result) const { // Parse - AstNode* root; + AstNodePtr root; if (not Parse(cql2_query, &root, &error_msg_)) return false; // Prepare evaluator @@ -70,7 +70,6 @@ class Cql2Cpp { LOG(ERROR) << "evaluation error: " << evaluator_.error_msg(); } } - Cql2Parser::DeConstructAST(root); return result; } @@ -80,7 +79,7 @@ class Cql2Cpp { bool Evaluate(const std::string& cql2_query, const FeatureSource& fs, bool* result, std::string* error_msg, std::string* dot) { // Parse - AstNode* root; + AstNodePtr root; if (not Parse(cql2_query, &root, error_msg)) return false; // Evaluate @@ -93,11 +92,9 @@ class Cql2Cpp { cql2cpp::Tree2Dot::GenerateDot(ss, root); *dot = ss.str(); } - Cql2Parser::DeConstructAST(root); return true; } else { if (error_msg != nullptr) *error_msg = evaluator_.error_msg(); - Cql2Parser::DeConstructAST(root); return false; } } @@ -105,7 +102,7 @@ class Cql2Cpp { static bool ToDot(const std::string& cql2_query, std::string* dot, std::string* error_msg) { // Parse - AstNode* root; + AstNodePtr root; if (not Parse(cql2_query, &root, error_msg)) return false; // to dot @@ -113,13 +110,11 @@ class Cql2Cpp { cql2cpp::Tree2Dot::GenerateDot(ss, root); *dot = ss.str(); - Cql2Parser::DeConstructAST(root); - return true; } private: - static bool Parse(const std::string& cql2_query, AstNode** root, + static bool Parse(const std::string& cql2_query, AstNodePtr* root, std::string* error_msg) { std::istringstream iss(cql2_query); std::ostringstream oss; @@ -135,7 +130,6 @@ class Cql2Cpp { *root = parser.root(); return true; } else { - parser.DeConstructRoot(); return false; } } diff --git a/include/cql2cpp/evaluator.h b/include/cql2cpp/evaluator.h index 6faa189..db6649e 100644 --- a/include/cql2cpp/evaluator.h +++ b/include/cql2cpp/evaluator.h @@ -61,7 +61,7 @@ class Evaluator { eval_func.Register(functor); } - bool Evaluate(const AstNode* root, const FeatureSource* fs, + bool Evaluate(const AstNodePtr root, const FeatureSource* fs, ValueT* result) const { if (type_evaluator_.find(root->type()) == type_evaluator_.end() || type_evaluator_.at(root->type()).find(root->op()) == @@ -73,7 +73,7 @@ class Evaluator { } std::vector child_values; - for (AstNode* child : root->children()) { + for (AstNodePtr child : root->children()) { ValueT value; if (Evaluate(child, fs, &value)) child_values.emplace_back(value); diff --git a/include/cql2cpp/evaluator_ast_node.h b/include/cql2cpp/evaluator_ast_node.h index d0c31bb..1988d55 100644 --- a/include/cql2cpp/evaluator_ast_node.h +++ b/include/cql2cpp/evaluator_ast_node.h @@ -20,7 +20,7 @@ namespace cql2cpp { using NodeEval = - std::function&, + std::function&, const FeatureSource*, ValueT*, std::string* error_msg)>; class EvaluatorAstNode { diff --git a/include/cql2cpp/evaluator_in.h b/include/cql2cpp/evaluator_in.h index ce17e7a..37e6df9 100644 --- a/include/cql2cpp/evaluator_in.h +++ b/include/cql2cpp/evaluator_in.h @@ -61,8 +61,8 @@ class EvaluatorIn : public EvaluatorAstNode { *errmsg = "left hand side is not scalar type"; return false; } - AstNode* in_list = n->children()[1]; - for (const AstNode* grand_child : in_list->children()) { + AstNodePtr in_list = n->children()[1]; + for (const AstNodePtr& grand_child : in_list->children()) { if (isVariantEqual(vs.at(0), grand_child->value())) { *value = true; return true; diff --git a/include/cql2cpp/tree_dot.h b/include/cql2cpp/tree_dot.h index 3667e55..0d6bdfd 100644 --- a/include/cql2cpp/tree_dot.h +++ b/include/cql2cpp/tree_dot.h @@ -18,14 +18,14 @@ namespace cql2cpp { class Tree2Dot { public: - static std::string node_name(const AstNode* node) { + static std::string node_name(const AstNodePtr node) { if (node->op() != NullOp) return OpName.at(node->op()); else return TypeName.at(node->type()); } - static bool GenerateDot(std::ostream& ous, const AstNode* node) { + static bool GenerateDot(std::ostream& ous, const AstNodePtr node) { ous << "digraph G {" << std::endl; GenerateDotNode(ous, node); ous << std::endl; @@ -34,21 +34,21 @@ class Tree2Dot { return true; } - static bool GenerateDotNode(std::ostream& ous, const AstNode* node) { + static bool GenerateDotNode(std::ostream& ous, const AstNodePtr node) { if (node == nullptr) return true; ous << " \"" << node->id() << "\" [label=\"" << node->id() << ". " << node_name(node) << "(" << value_str(node->value()) << ")" << "\"];" << std::endl; - for (const auto child : node->children()) GenerateDotNode(ous, child); + for (const auto& child : node->children()) GenerateDotNode(ous, child); return true; } - static bool GenerateDotEdge(std::ostream& ous, const AstNode* node) { + static bool GenerateDotEdge(std::ostream& ous, const AstNodePtr node) { if (node == nullptr) return true; - for (const auto child : node->children()) { + for (const auto& child : node->children()) { ous << " \"" << node->id() << "\" -> \"" << child->id() << "\";\n"; GenerateDotEdge(ous, child); } diff --git a/src/cql2_parser.y b/src/cql2_parser.y index 603b32d..c65818f 100644 --- a/src/cql2_parser.y +++ b/src/cql2_parser.y @@ -6,6 +6,7 @@ #include using cql2cpp::AstNode; +using cql2cpp::AstNodePtr; using cql2cpp::BoolExpression; using cql2cpp::BinCompPred; @@ -51,7 +52,7 @@ void cql2cpp::Cql2ParserBase::error(const std::string& msg) { %define api.parser.class {Cql2ParserBase} %define api.value.type variant %define parse.error verbose -%parse-param {cql2cpp::AstNode **root_} +%parse-param {cql2cpp::AstNodePtr* root_} %token NUMBER_INT %token NUMBER_FLOAT @@ -74,32 +75,32 @@ void cql2cpp::Cql2ParserBase::error(const std::string& msg) { %token POLYGON_WKT %token BBOX_TEXT -%type booleanExpression -%type booleanTerm -%type booleanFactor -%type booleanPrimary -%type booleanLiteral -%type characterExpression -%type characterClause -%type propertyName -%type predicate -%type comparisonPredicate -%type binaryComparisonPredicate -%type scalarExpression -%type numericLiteral -%type spatialPredicate -%type geomExpression -%type spatialInstance -%type isInListPredicate -%type inList -%type arrayPredicate -%type arrayExpression -%type array -%type arrayElement -%type arrayList -%type function -%type argumentList -%type argument +%type booleanExpression +%type booleanTerm +%type booleanFactor +%type booleanPrimary +%type booleanLiteral +%type characterExpression +%type characterClause +%type propertyName +%type predicate +%type comparisonPredicate +%type binaryComparisonPredicate +%type scalarExpression +%type numericLiteral +%type spatialPredicate +%type geomExpression +%type spatialInstance +%type isInListPredicate +%type inList +%type arrayPredicate +%type arrayExpression +%type array +%type arrayElement +%type arrayList +%type function +%type argumentList +%type argument %type geometryLiteral %type pointTaggedText @@ -120,15 +121,15 @@ program: booleanExpression: booleanTerm - | booleanTerm OR booleanExpression { $$ = new AstNode(BoolExpression, Or, {$1, $3}); } + | booleanTerm OR booleanExpression { $$ = std::make_shared(BoolExpression, Or, std::vector({$1, $3})); } booleanTerm: booleanFactor - | booleanFactor AND booleanTerm { $$ = new AstNode(BoolExpression, And, {$1, $3}); } + | booleanFactor AND booleanTerm { $$ = std::make_shared(BoolExpression, And, std::vector({$1, $3})); } booleanFactor: booleanPrimary - | NOT booleanPrimary { $$ = new AstNode(BoolExpression, Not, { $2 }); } + | NOT booleanPrimary { $$ = std::make_shared(BoolExpression, Not, std::vector({ $2 })); } booleanPrimary: function @@ -137,8 +138,8 @@ booleanPrimary: | LPT booleanExpression RPT { $$ = $2; } booleanLiteral: - TRUE { $$ = new AstNode($1); } - | FALSE { $$ = new AstNode($1); } + TRUE { $$ = std::make_shared($1); } + | FALSE { $$ = std::make_shared($1); } predicate: comparisonPredicate @@ -150,20 +151,20 @@ comparisonPredicate: | isInListPredicate isInListPredicate: - scalarExpression IN LPT inList RPT { $$ = new AstNode(IsInListPred, In, {$1, $4}); } - | scalarExpression NOT IN LPT inList RPT { $$ = new AstNode(IsInListPred, NotIn, {$1, $5}); } + scalarExpression IN LPT inList RPT { $$ = std::make_shared(IsInListPred, In, std::vector({$1, $4})); } + | scalarExpression NOT IN LPT inList RPT { $$ = std::make_shared(IsInListPred, NotIn, std::vector({$1, $5})); } inList: - scalarExpression { $$ = new AstNode(InList, NullOp, {$1}); } + scalarExpression { $$ = std::make_shared(InList, NullOp, std::vector({$1})); } | inList COMMA scalarExpression { $1->append($3); $$ = $1; } binaryComparisonPredicate: - scalarExpression EQ scalarExpression { $$ = new AstNode(BinCompPred, cql2cpp::Equal, {$1, $3}); } - | scalarExpression LT GT scalarExpression { $$ = new AstNode(BinCompPred, cql2cpp::NotEqual, {$1, $4}); } - | scalarExpression LT scalarExpression { $$ = new AstNode(BinCompPred, cql2cpp::Lesser, {$1, $3}); } - | scalarExpression GT scalarExpression { $$ = new AstNode(BinCompPred, cql2cpp::Greater, {$1, $3}); } - | scalarExpression LT EQ scalarExpression { $$ = new AstNode(BinCompPred, cql2cpp::LesserEqual, {$1, $4}); } - | scalarExpression GT EQ scalarExpression { $$ = new AstNode(BinCompPred, cql2cpp::GreaterEqual, {$1, $4}); } + scalarExpression EQ scalarExpression { $$ = std::make_shared(BinCompPred, cql2cpp::Equal, std::vector({$1, $3})); } + | scalarExpression LT GT scalarExpression { $$ = std::make_shared(BinCompPred, cql2cpp::NotEqual, std::vector({$1, $4})); } + | scalarExpression LT scalarExpression { $$ = std::make_shared(BinCompPred, cql2cpp::Lesser, std::vector({$1, $3})); } + | scalarExpression GT scalarExpression { $$ = std::make_shared(BinCompPred, cql2cpp::Greater, std::vector({$1, $3})); } + | scalarExpression LT EQ scalarExpression { $$ = std::make_shared(BinCompPred, cql2cpp::LesserEqual, std::vector({$1, $4})); } + | scalarExpression GT EQ scalarExpression { $$ = std::make_shared(BinCompPred, cql2cpp::GreaterEqual, std::vector({$1, $4})); } scalarExpression: numericLiteral @@ -175,22 +176,22 @@ scalarExpression: characterClause: CASEI LPT characterExpression RPT { $$ = $3; } // TODO | ACCENTI LPT characterExpression RPT { $$ = $3; } // TODO - | CHAR_LIT { std::string s = std::string($1); $$ = new AstNode(s.substr(1, s.size() - 2)); } + | CHAR_LIT { std::string s = std::string($1); $$ = std::make_shared(s.substr(1, s.size() - 2)); } characterExpression: characterClause | propertyName { $$ = $1; } numericLiteral: - NUMBER_INT { $$ = new AstNode($1); } - | NUMBER_FLOAT { $$ = new AstNode($1); } + NUMBER_INT { $$ = std::make_shared($1); } + | NUMBER_FLOAT { $$ = std::make_shared($1); } propertyName: - ID { $$ = new AstNode(PropertyName, std::string($1)); } + ID { $$ = std::make_shared(PropertyName, std::string($1)); } // | DQUOTE ID DQUOTE; spatialPredicate: - SPT_FUNC LPT geomExpression COMMA geomExpression RPT { $$ = new AstNode(SpatialPred, NameOp.at($1), {$3, $5}); } + SPT_FUNC LPT geomExpression COMMA geomExpression RPT { $$ = std::make_shared(SpatialPred, NameOp.at($1), std::vector({$3, $5})); } geomExpression: @@ -203,7 +204,7 @@ spatialInstance: geometryLiteral { auto p = geos::io::WKTReader().read($1); if (p) { - $$ = new AstNode(p.release()); + $$ = std::make_shared(p.release()); } else { error("Can not parse WKT"); YYERROR; @@ -212,7 +213,7 @@ spatialInstance: | bboxTaggedText { auto p = cql2cpp::BBoxReader().read($1); if (p) { - $$ = new AstNode(p.release()); + $$ = std::make_shared(p.release()); } else { error("Can not parse BBOX"); YYERROR; @@ -220,7 +221,7 @@ spatialInstance: } arrayPredicate: - arrayFunction LPT arrayExpression COMMA arrayExpression RPT { $$ = new AstNode(ArrayPred, NameOp.at($1), {$3, $5}); } + arrayFunction LPT arrayExpression COMMA arrayExpression RPT { $$ = std::make_shared(ArrayPred, NameOp.at($1), std::vector({$3, $5})); } arrayExpression: array @@ -228,11 +229,11 @@ arrayExpression: | function array: - LPT RPT { $$ = new AstNode(Array, NullOp, {}); } + LPT RPT { $$ = std::make_shared(Array, NullOp, std::vector()); } | LPT arrayList RPT { $$ = $2; } arrayList: - arrayElement { $$ = new AstNode(Array, NullOp, {$1}); } + arrayElement { $$ = std::make_shared(Array, NullOp, std::vector({$1})); } | arrayList COMMA arrayElement { $1->append($3); $$ = $1; } arrayElement: @@ -248,17 +249,17 @@ arrayElement: function: ID LPT RPT { - AstNode * function_name = new AstNode($1); - $$ = new AstNode(Function, NullOp, {function_name}); + AstNodePtr function_name = std::make_shared($1); + $$ = std::make_shared(Function, NullOp, std::vector({function_name})); } | ID LPT argumentList RPT { - AstNode * function_name = new AstNode($1); - $$ = new AstNode(Function, NullOp, {function_name, $3}); + AstNodePtr function_name = std::make_shared($1); + $$ = std::make_shared(Function, NullOp, std::vector({function_name, $3})); } argumentList: - argument { $$ = new AstNode(ArgumentList, NullOp, {$1}); } + argument { $$ = std::make_shared(ArgumentList, NullOp, std::vector({$1})); } | argumentList COMMA argument { $1->append($3); $$ = $1; } argument: