From e8dd444bcfb94b460b7dc9e9d81adab878e46dda Mon Sep 17 00:00:00 2001 From: Kunlin Yu Date: Sat, 28 Dec 2024 01:49:21 +0800 Subject: [PATCH] Finish parsing of IN Signed-off-by: Kunlin Yu --- include/cql2cpp/node_type.h | 3 +++ include/cql2cpp/tree_dot.h | 15 +++++---------- src/cql2_lexer.l | 2 +- src/cql2_parser.y | 20 ++++++++++---------- src/main.cc | 4 ++++ test/indoorjson/in_list.txt | 1 + test/test_parse.cc | 7 ++++--- 7 files changed, 28 insertions(+), 24 deletions(-) create mode 100644 test/indoorjson/in_list.txt diff --git a/include/cql2cpp/node_type.h b/include/cql2cpp/node_type.h index fdebea3..1c25b03 100644 --- a/include/cql2cpp/node_type.h +++ b/include/cql2cpp/node_type.h @@ -52,11 +52,14 @@ const std::map TypeName { TYPE_2_NAME(IsLikePred) TYPE_2_NAME(IsBetweenPred) TYPE_2_NAME(IsInListPred) + TYPE_2_NAME(InList) TYPE_2_NAME(IsNullPred) TYPE_2_NAME(SpatialPred) TYPE_2_NAME(TemporalPred) TYPE_2_NAME(ArrayPred) TYPE_2_NAME(PropertyName) + TYPE_2_NAME(Function) + TYPE_2_NAME(ArgumentList) }; } // namespace cql2cpp diff --git a/include/cql2cpp/tree_dot.h b/include/cql2cpp/tree_dot.h index 07a89b6..3667e55 100644 --- a/include/cql2cpp/tree_dot.h +++ b/include/cql2cpp/tree_dot.h @@ -20,15 +20,9 @@ class Tree2Dot { public: static std::string node_name(const AstNode* node) { if (node->op() != NullOp) - return OpName.at(node->op()) + "(" + value_str(node->value()) + ")"; - else if (node->type() == PropertyName) - return std::string("property") + "(" + value_str(node->value()) + ")"; + return OpName.at(node->op()); else - return value_str(node->value()); - } - - static std::string node_value_str(const AstNode* node) { - return value_str(node->value()); + return TypeName.at(node->type()); } static bool GenerateDot(std::ostream& ous, const AstNode* node) { @@ -43,8 +37,9 @@ class Tree2Dot { static bool GenerateDotNode(std::ostream& ous, const AstNode* node) { if (node == nullptr) return true; - ous << " \"" << node->id() << "\" [label=\"(" << node->id() << ") " - << node_name(node) << "\"];" << std::endl; + ous << " \"" << node->id() << "\" [label=\"" << node->id() << ". " + << node_name(node) << "(" << value_str(node->value()) << ")" + << "\"];" << std::endl; for (const auto child : node->children()) GenerateDotNode(ous, child); return true; diff --git a/src/cql2_lexer.l b/src/cql2_lexer.l index 6342250..2a588cb 100644 --- a/src/cql2_lexer.l +++ b/src/cql2_lexer.l @@ -7,7 +7,7 @@ DIGIT [0-9] ID [a-z][.a-z0-9_\-]* -CHAR_LIT \'.*\' +CHAR_LIT \'[^\']*\' %% diff --git a/src/cql2_parser.y b/src/cql2_parser.y index 12db14b..f64ce00 100644 --- a/src/cql2_parser.y +++ b/src/cql2_parser.y @@ -80,8 +80,8 @@ using cql2cpp::NameOp; %type booleanFactor %type booleanPrimary %type booleanLiteral -// %type characterExpression -// %type characterClause +%type characterExpression +%type characterClause %type propertyName %type predicate %type comparisonPredicate @@ -165,16 +165,16 @@ scalarExpression: | propertyName | function | booleanLiteral -//| characterClause + | characterClause -// characterClause: -// CASEI LPT characterExpression RPT -// | ACCENTI LPT characterExpression RPT -// | CHAR_LIT { std::string s = std::string($1); $$ = new AstNode(s.substr(1, s.size() - 2)); } +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)); } -// characterExpression: -// characterClause -// | propertyName { $$ = $1; } +characterExpression: + characterClause + | propertyName { $$ = $1; } numericLiteral: NUMBER_INT { $$ = new AstNode($1); } diff --git a/src/main.cc b/src/main.cc index 6ac576b..18df471 100644 --- a/src/main.cc +++ b/src/main.cc @@ -22,6 +22,7 @@ DEFINE_string(cql2_query, "", "cql2 query string"); DEFINE_string(geojson, "", "data set to be queried"); DEFINE_string(dot, "", "generate dot file"); +DEFINE_bool(verbose, false, "Enable verbose output"); int main(int argc, char** argv) { gflags::SetUsageMessage( @@ -39,6 +40,9 @@ int main(int argc, char** argv) { LOG(INFO) << "geojson: " << FLAGS_geojson; LOG(INFO) << "dot: " << FLAGS_dot; + if (FLAGS_verbose) + cql2cpp::AstNode::set_ostream(&std::cout); + if (FLAGS_cql2_query.empty()) { LOG(ERROR) << "you should provide cql2_query"; return 0; diff --git a/test/indoorjson/in_list.txt b/test/indoorjson/in_list.txt new file mode 100644 index 0000000..cd3283f --- /dev/null +++ b/test/indoorjson/in_list.txt @@ -0,0 +1 @@ +'CONTAINER' IN ('ABC', 'CONTAINER', 'xyz') diff --git a/test/test_parse.cc b/test/test_parse.cc index 9cbfff8..618f743 100644 --- a/test/test_parse.cc +++ b/test/test_parse.cc @@ -48,8 +48,9 @@ class ParseTest : public testing::Test { }; // clang-format off -TEST_F(ParseTest, binary ) { EXPECT_TRUE(Parse(case_name_)); } // BBOX -// TEST_F(ParseTest, binlocations) { EXPECT_TRUE(Parse(case_name_)); } // function -// TEST_F(ParseTest, labels ) { EXPECT_TRUE(Parse(case_name_)); } // IN +TEST_F(ParseTest, binary ) { EXPECT_TRUE(Parse(case_name_)); } +TEST_F(ParseTest, in_list ) { EXPECT_TRUE(Parse(case_name_)); } TEST_F(ParseTest, localization) { EXPECT_TRUE(Parse(case_name_)); } +// TEST_F(ParseTest, binlocations) { EXPECT_TRUE(Parse(case_name_)); } // function +// TEST_F(ParseTest, labels ) { EXPECT_TRUE(Parse(case_name_)); } // clang-format on