From cd9126aae8922e6cb47da1308d800e8746ffdd9f Mon Sep 17 00:00:00 2001 From: laura-ding <48548375+laura-ding@users.noreply.github.com> Date: Thu, 12 Sep 2019 09:39:24 +0800 Subject: [PATCH] Add logic xor and Arithmetic ^ (#858) --- src/executor/test/YieldTest.cpp | 54 +++++++++++++++++++++++++++++++++ src/parser/parser.yy | 41 +++++++++++++++++++------ src/parser/scanner.lex | 5 +++ src/parser/test/ScannerTest.cpp | 9 ++++++ 4 files changed, 100 insertions(+), 9 deletions(-) diff --git a/src/executor/test/YieldTest.cpp b/src/executor/test/YieldTest.cpp index 94788f05..865635ed 100644 --- a/src/executor/test/YieldTest.cpp +++ b/src/executor/test/YieldTest.cpp @@ -149,5 +149,59 @@ TEST_F(YieldTest, hashCall) { } } +TEST_F(YieldTest, Logic) { + auto client = gEnv->getClient(); + ASSERT_NE(nullptr, client); + { + cpp2::ExecutionResponse resp; + std::string query = "YIELD NOT 0 || 0 AND 0 XOR 0"; + auto code = client->execute(query, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + std::vector<std::tuple<int64_t>> expected{ + 1 + }; + ASSERT_TRUE(verifyResult(resp, expected)); + } + { + cpp2::ExecutionResponse resp; + std::string query = "YIELD !0 OR 0 && 0 XOR 1"; + auto code = client->execute(query, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + std::vector<std::tuple<int64_t>> expected{ + 0 + }; + ASSERT_TRUE(verifyResult(resp, expected)); + } + { + cpp2::ExecutionResponse resp; + std::string query = "YIELD (NOT 0 || 0) AND 0 XOR 1"; + auto code = client->execute(query, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + std::vector<std::tuple<int64_t>> expected{ + 1 + }; + ASSERT_TRUE(verifyResult(resp, expected)); + } + { + cpp2::ExecutionResponse resp; + std::string query = "YIELD 2.5 % 1.2 ^ 1.6"; + auto code = client->execute(query, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + std::vector<std::tuple<double>> expected{ + 2.5 + }; + ASSERT_TRUE(verifyResult(resp, expected)); + } + { + cpp2::ExecutionResponse resp; + std::string query = "YIELD (5 % 3) ^ 1"; + auto code = client->execute(query, resp); + ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code); + std::vector<std::tuple<int64_t>> expected{ + 3 + }; + ASSERT_TRUE(verifyResult(resp, expected)); + } +} } // namespace graph } // namespace nebula diff --git a/src/parser/parser.yy b/src/parser/parser.yy index 78739af2..670d2f7a 100644 --- a/src/parser/parser.yy +++ b/src/parser/parser.yy @@ -92,7 +92,7 @@ class GraphScanner; %destructor { delete $$; } <*> /* keywords */ -%token KW_GO KW_AS KW_TO KW_OR KW_USE KW_SET KW_FROM KW_WHERE KW_ALTER +%token KW_GO KW_AS KW_TO KW_OR KW_AND KW_XOR KW_USE KW_SET KW_FROM KW_WHERE KW_ALTER %token KW_MATCH KW_INSERT KW_VALUES KW_YIELD KW_RETURN KW_CREATE KW_VERTEX %token KW_EDGE KW_EDGES KW_UPDATE KW_STEPS KW_OVER KW_UPTO KW_REVERSELY KW_SPACE KW_DELETE KW_FIND %token KW_INT KW_BIGINT KW_DOUBLE KW_STRING KW_BOOL KW_TAG KW_TAGS KW_UNION KW_INTERSECT KW_MINUS @@ -109,7 +109,7 @@ class GraphScanner; %token KW_BALANCE KW_LEADER /* symbols */ %token L_PAREN R_PAREN L_BRACKET R_BRACKET L_BRACE R_BRACE COMMA -%token PIPE OR AND LT LE GT GE EQ NE PLUS MINUS MUL DIV MOD NOT NEG ASSIGN +%token PIPE OR AND XOR LT LE GT GE EQ NE PLUS MINUS MUL DIV MOD NOT NEG ASSIGN %token DOT COLON SEMICOLON L_ARROW R_ARROW AT %token ID_PROP TYPE_PROP SRC_ID_PROP DST_ID_PROP RANK_PROP INPUT_REF DST_REF SRC_REF @@ -120,8 +120,8 @@ class GraphScanner; %token <strval> STRING VARIABLE LABEL %type <strval> name_label unreserved_keyword -%type <expr> expression logic_or_expression logic_and_expression -%type <expr> relational_expression multiplicative_expression additive_expression +%type <expr> expression logic_xor_expression logic_or_expression logic_and_expression +%type <expr> relational_expression multiplicative_expression additive_expression arithmetic_xor_expression %type <expr> unary_expression primary_expression equality_expression %type <expr> src_ref_expression %type <expr> dst_ref_expression @@ -353,6 +353,9 @@ unary_expression | NOT unary_expression { $$ = new UnaryExpression(UnaryExpression::NOT, $2); } + | KW_NOT unary_expression { + $$ = new UnaryExpression(UnaryExpression::NOT, $2); + } | L_PAREN type_spec R_PAREN unary_expression { $$ = new TypeCastingExpression($2, $4); } @@ -367,15 +370,22 @@ type_spec | KW_TIMESTAMP { $$ = ColumnType::TIMESTAMP; } ; -multiplicative_expression +arithmetic_xor_expression : unary_expression { $$ = $1; } - | multiplicative_expression MUL unary_expression { + | arithmetic_xor_expression XOR unary_expression { + $$ = new ArithmeticExpression($1, ArithmeticExpression::XOR, $3); + } + ; + +multiplicative_expression + : arithmetic_xor_expression { $$ = $1; } + | multiplicative_expression MUL arithmetic_xor_expression { $$ = new ArithmeticExpression($1, ArithmeticExpression::MUL, $3); } - | multiplicative_expression DIV unary_expression { + | multiplicative_expression DIV arithmetic_xor_expression { $$ = new ArithmeticExpression($1, ArithmeticExpression::DIV, $3); } - | multiplicative_expression MOD unary_expression { + | multiplicative_expression MOD arithmetic_xor_expression { $$ = new ArithmeticExpression($1, ArithmeticExpression::MOD, $3); } ; @@ -421,6 +431,9 @@ logic_and_expression | logic_and_expression AND equality_expression { $$ = new LogicalExpression($1, LogicalExpression::AND, $3); } + | logic_and_expression KW_AND equality_expression { + $$ = new LogicalExpression($1, LogicalExpression::AND, $3); + } ; logic_or_expression @@ -428,10 +441,20 @@ logic_or_expression | logic_or_expression OR logic_and_expression { $$ = new LogicalExpression($1, LogicalExpression::OR, $3); } + | logic_or_expression KW_OR logic_and_expression { + $$ = new LogicalExpression($1, LogicalExpression::OR, $3); + } ; -expression +logic_xor_expression : logic_or_expression { $$ = $1; } + | logic_xor_expression KW_XOR logic_or_expression { + $$ = new LogicalExpression($1, LogicalExpression::XOR, $3); + } + ; + +expression + : logic_xor_expression { $$ = $1; } ; go_sentence diff --git a/src/parser/scanner.lex b/src/parser/scanner.lex index 5b4e7f72..104484da 100644 --- a/src/parser/scanner.lex +++ b/src/parser/scanner.lex @@ -28,6 +28,8 @@ GO ([Gg][Oo]) AS ([Aa][Ss]) TO ([Tt][Oo]) OR ([Oo][Rr]) +AND ([Aa][Nn][Dd]) +XOR ([Xx][Oo][Rr]) USE ([Uu][Ss][Ee]) SET ([Ss][Ee][Tt]) FROM ([Ff][Rr][Oo][Mm]) @@ -132,6 +134,8 @@ IP_OCTET ([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]) {AS} { return TokenType::KW_AS; } {TO} { return TokenType::KW_TO; } {OR} { return TokenType::KW_OR; } +{AND} { return TokenType::KW_AND; } +{XOR} { return TokenType::KW_XOR; } {USE} { return TokenType::KW_USE; } {SET} { return TokenType::KW_SET; } {FROM} { return TokenType::KW_FROM; } @@ -232,6 +236,7 @@ IP_OCTET ([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]) "/" { return TokenType::DIV; } "%" { return TokenType::MOD; } "!" { return TokenType::NOT; } +"^" { return TokenType::XOR; } "<" { return TokenType::LT; } "<=" { return TokenType::LE; } diff --git a/src/parser/test/ScannerTest.cpp b/src/parser/test/ScannerTest.cpp index e8a8d663..0fa0f776 100644 --- a/src/parser/test/ScannerTest.cpp +++ b/src/parser/test/ScannerTest.cpp @@ -278,6 +278,15 @@ TEST(Scanner, Basic) { CHECK_SEMANTIC_TYPE("NOT", TokenType::KW_NOT), CHECK_SEMANTIC_TYPE("Not", TokenType::KW_NOT), CHECK_SEMANTIC_TYPE("not", TokenType::KW_NOT), + CHECK_SEMANTIC_TYPE("OR", TokenType::KW_OR), + CHECK_SEMANTIC_TYPE("Or", TokenType::KW_OR), + CHECK_SEMANTIC_TYPE("or", TokenType::KW_OR), + CHECK_SEMANTIC_TYPE("AND", TokenType::KW_AND), + CHECK_SEMANTIC_TYPE("And", TokenType::KW_AND), + CHECK_SEMANTIC_TYPE("and", TokenType::KW_AND), + CHECK_SEMANTIC_TYPE("XOR", TokenType::KW_XOR), + CHECK_SEMANTIC_TYPE("Xor", TokenType::KW_XOR), + CHECK_SEMANTIC_TYPE("xor", TokenType::KW_XOR), CHECK_SEMANTIC_TYPE("EXISTS", TokenType::KW_EXISTS), CHECK_SEMANTIC_TYPE("Exists", TokenType::KW_EXISTS), CHECK_SEMANTIC_TYPE("exists", TokenType::KW_EXISTS), -- GitLab