mirror of
https://github.com/dragonflydb/dragonfly.git
synced 2025-05-11 18:35:46 +02:00
feat: Extend parsing to field impressions (#1154)
feat: Extend parsing to field impressions. Add search_parser_test to PR tests. Signed-off-by: Roman Gershman <roman@dragonflydb.io>
This commit is contained in:
parent
0651339f79
commit
494ca14e4e
4 changed files with 49 additions and 11 deletions
|
@ -1,5 +1,3 @@
|
||||||
# apt install libfl-dev
|
|
||||||
|
|
||||||
gen_flex(lexer)
|
gen_flex(lexer)
|
||||||
gen_bison(parser)
|
gen_bison(parser)
|
||||||
|
|
||||||
|
@ -7,4 +5,4 @@ cur_gen_dir(gen_dir)
|
||||||
|
|
||||||
add_library(query_parser query_driver.cc ${gen_dir}/parser.cc ${gen_dir}/lexer.cc)
|
add_library(query_parser query_driver.cc ${gen_dir}/parser.cc ${gen_dir}/lexer.cc)
|
||||||
target_link_libraries(query_parser base absl::strings TRDP::reflex)
|
target_link_libraries(query_parser base absl::strings TRDP::reflex)
|
||||||
cxx_test(search_parser_test query_parser)
|
cxx_test(search_parser_test query_parser LABELS DFLY)
|
||||||
|
|
|
@ -53,9 +53,11 @@ term_char [_]|\w
|
||||||
"(" return Parser::make_LPAREN (loc());
|
"(" return Parser::make_LPAREN (loc());
|
||||||
")" return Parser::make_RPAREN (loc());
|
")" return Parser::make_RPAREN (loc());
|
||||||
"*" return Parser::make_STAR (loc());
|
"*" return Parser::make_STAR (loc());
|
||||||
"~" return Parser::make_NOT_OP (loc());
|
"-" return Parser::make_NOT_OP (loc());
|
||||||
":" return Parser::make_COLON (loc());
|
":" return Parser::make_COLON (loc());
|
||||||
"=>" return Parser::make_ARROW (loc());
|
"=>" return Parser::make_ARROW (loc());
|
||||||
|
"[" return Parser::make_LBRACKET (loc());
|
||||||
|
"]" return Parser::make_RBRACKET (loc());
|
||||||
|
|
||||||
-?[0-9]+ return make_INT64(matched_view(), loc());
|
-?[0-9]+ return make_INT64(matched_view(), loc());
|
||||||
|
|
||||||
|
|
|
@ -46,14 +46,18 @@ using namespace std;
|
||||||
STAR "*"
|
STAR "*"
|
||||||
ARROW "=>"
|
ARROW "=>"
|
||||||
COLON ":"
|
COLON ":"
|
||||||
NOT_OP "~"
|
LBRACKET "["
|
||||||
|
RBRACKET "]"
|
||||||
;
|
;
|
||||||
|
|
||||||
%token YYEOF
|
%precedence NOT_OP
|
||||||
|
|
||||||
|
// Needed 0 at the end to satisfy bison 3.5.1
|
||||||
|
%token YYEOF 0
|
||||||
%token <std::string> TERM "term" PARAM "param" FIELD "field"
|
%token <std::string> TERM "term" PARAM "param" FIELD "field"
|
||||||
|
|
||||||
%token <int64_t> INT64 "int64"
|
%token <int64_t> INT64 "int64"
|
||||||
%nterm <AstExpr> search_expr
|
%nterm <AstExpr> search_expr field_filter field_cond range_value term_list opt_neg_term
|
||||||
|
|
||||||
%printer { yyo << $$; } <*>;
|
%printer { yyo << $$; } <*>;
|
||||||
|
|
||||||
|
@ -64,9 +68,25 @@ query:
|
||||||
| query search_expr
|
| query search_expr
|
||||||
;
|
;
|
||||||
|
|
||||||
search_expr: TERM {
|
|
||||||
cout << $1 << endl;
|
search_expr:
|
||||||
}
|
LPAREN search_expr RPAREN { $$ = $2; }
|
||||||
|
| NOT_OP search_expr { $$ = AstExpr{}; };
|
||||||
|
| TERM { }
|
||||||
|
| field_filter;
|
||||||
|
|
||||||
|
field_filter:
|
||||||
|
FIELD COLON field_cond { $$ = AstExpr{}; }
|
||||||
|
|
||||||
|
field_cond: term_list | range_value
|
||||||
|
range_value: LBRACKET INT64 INT64 RBRACKET { $$ = AstExpr{}; }
|
||||||
|
|
||||||
|
term_list:
|
||||||
|
opt_neg_term |
|
||||||
|
LPAREN term_list opt_neg_term RPAREN { };
|
||||||
|
|
||||||
|
opt_neg_term:
|
||||||
|
TERM { } | NOT_OP TERM { $$ = AstExpr{}; };
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,16 @@ class SearchParserTest : public ::testing::Test {
|
||||||
auto tok = Lex(); \
|
auto tok = Lex(); \
|
||||||
ASSERT_EQ(tok.type_get(), Parser::token::tok_enum); \
|
ASSERT_EQ(tok.type_get(), Parser::token::tok_enum); \
|
||||||
}
|
}
|
||||||
|
#define NEXT_ERROR() \
|
||||||
|
{ \
|
||||||
|
bool caught = false; \
|
||||||
|
try { \
|
||||||
|
auto tok = Lex(); \
|
||||||
|
} catch (const Parser::syntax_error& e) { \
|
||||||
|
caught = true; \
|
||||||
|
} \
|
||||||
|
ASSERT_TRUE(caught); \
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(SearchParserTest, Scanner) {
|
TEST_F(SearchParserTest, Scanner) {
|
||||||
SetInput("ab cd");
|
SetInput("ab cd");
|
||||||
|
@ -76,10 +86,18 @@ TEST_F(SearchParserTest, Scanner) {
|
||||||
SetInput("почтальон Печкин");
|
SetInput("почтальон Печкин");
|
||||||
NEXT_EQ(TOK_TERM, string, "почтальон");
|
NEXT_EQ(TOK_TERM, string, "почтальон");
|
||||||
NEXT_EQ(TOK_TERM, string, "Печкин");
|
NEXT_EQ(TOK_TERM, string, "Печкин");
|
||||||
|
|
||||||
|
SetInput("18446744073709551616");
|
||||||
|
NEXT_ERROR();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(SearchParserTest, Parse) {
|
TEST_F(SearchParserTest, Parse) {
|
||||||
EXPECT_EQ(0, Parse(" foo "));
|
EXPECT_EQ(0, Parse(" foo bar (baz) "));
|
||||||
|
EXPECT_EQ(0, Parse(" -(foo) @foo:bar @ss:[1 2]"));
|
||||||
|
EXPECT_EQ(1, Parse(" -(foo "));
|
||||||
|
EXPECT_EQ(1, Parse(" foo:bar "));
|
||||||
|
EXPECT_EQ(1, Parse(" @foo:@bar "));
|
||||||
|
EXPECT_EQ(1, Parse(" @foo: "));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace search
|
} // namespace search
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue