From 7707bfb268ee030d9b9dc7e277f309d2a9eae695 Mon Sep 17 00:00:00 2001 From: thamindu Date: Fri, 16 Aug 2024 23:35:44 +0530 Subject: [PATCH 1/5] add feature cypher ast --- CMakeLists.txt | 19 +- Dockerfile | 19 +- src/frontend/JasmineGraphFrontEnd.cpp | 55 +- src/frontend/JasmineGraphFrontEndProtocol.cpp | 1 + src/frontend/JasmineGraphFrontEndProtocol.h | 1 + .../cypher/astbuilder/ASTBuilder.cpp | 5 + .../processor/cypher/astbuilder/ASTBuilder.h | 1479 +++++++++++++++++ .../cypher/astbuilder/ASTInternalNode.cpp | 5 + .../cypher/astbuilder/ASTInternalNode.h | 29 + .../cypher/astbuilder/ASTLeafNoValue.cpp | 5 + .../cypher/astbuilder/ASTLeafNoValue.h | 19 + .../cypher/astbuilder/ASTLeafValue.cpp | 5 + .../cypher/astbuilder/ASTLeafValue.h | 23 + .../cypher/astbuilder/ASTStructure.cpp | 5 + .../cypher/astbuilder/ASTStructure.h | 42 + 15 files changed, 1707 insertions(+), 5 deletions(-) create mode 100644 src/query/processor/cypher/astbuilder/ASTBuilder.cpp create mode 100644 src/query/processor/cypher/astbuilder/ASTBuilder.h create mode 100644 src/query/processor/cypher/astbuilder/ASTInternalNode.cpp create mode 100644 src/query/processor/cypher/astbuilder/ASTInternalNode.h create mode 100644 src/query/processor/cypher/astbuilder/ASTLeafNoValue.cpp create mode 100644 src/query/processor/cypher/astbuilder/ASTLeafNoValue.h create mode 100644 src/query/processor/cypher/astbuilder/ASTLeafValue.cpp create mode 100644 src/query/processor/cypher/astbuilder/ASTLeafValue.h create mode 100644 src/query/processor/cypher/astbuilder/ASTStructure.cpp create mode 100644 src/query/processor/cypher/astbuilder/ASTStructure.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 845512a0..0455602f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.10) project(JasmineGraph) -set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD 17) set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) @@ -39,6 +39,11 @@ set(HEADERS globals.h src/query/algorithms/linkprediction/JasminGraphLinkPredictor.h src/query/algorithms/triangles/Triangles.h src/query/algorithms/triangles/StreamingTriangles.h + src/query/processor/cypher/astbuilder/ASTBuilder.h + src/query/processor/cypher/astbuilder/ASTInternalNode.h + src/query/processor/cypher/astbuilder/ASTLeafNoValue.h + src/query/processor/cypher/astbuilder/ASTLeafValue.h + src/query/processor/cypher/astbuilder/ASTStructure.h src/scale/scaler.h src/server/JasmineGraphInstance.h src/server/JasmineGraphInstanceFileTransferService.h @@ -106,6 +111,11 @@ set(SOURCES src/backend/JasmineGraphBackend.cpp src/query/algorithms/linkprediction/JasminGraphLinkPredictor.cpp src/query/algorithms/triangles/Triangles.cpp src/query/algorithms/triangles/StreamingTriangles.cpp + src/query/processor/cypher/astbuilder/ASTBuilder.cpp + src/query/processor/cypher/astbuilder/ASTInternalNode.cpp + src/query/processor/cypher/astbuilder/ASTLeafNoValue.cpp + src/query/processor/cypher/astbuilder/ASTLeafValue.cpp + src/query/processor/cypher/astbuilder/ASTStructure.cpp src/scale/scaler.cpp src/server/JasmineGraphInstance.cpp src/server/JasmineGraphInstanceFileTransferService.cpp @@ -137,7 +147,8 @@ if (CMAKE_BUILD_TYPE STREQUAL "DEBUG") add_compile_options(-DUNIT_TEST) endif () -add_library(JasmineGraphLib ${HEADERS} ${SOURCES}) +file(GLOB GENERATED_SRC ${CMAKE_SOURCE_DIR}/code_generated/antlr/*.cpp) +add_library(JasmineGraphLib ${HEADERS} ${SOURCES} ${GENERATED_SRC}) add_executable(JasmineGraph main.h main.cpp) target_compile_definitions(JasmineGraphLib PUBLIC ROOT_DIR="${CMAKE_CURRENT_SOURCE_DIR}/") @@ -162,11 +173,15 @@ target_link_libraries(JasmineGraphLib PRIVATE /usr/local/lib/libcppkafka.so) target_link_libraries(JasmineGraph JasmineGraphLib) target_link_libraries(JasmineGraph curl) +include_directories(/usr/local/include/antlr4-runtime) +link_directories(/usr/local/lib) include_directories(/usr/local/include/yaml-cpp) target_link_libraries(JasmineGraphLib PRIVATE m) target_link_libraries(JasmineGraphLib PRIVATE /usr/local/lib/libkubernetes.so) target_link_libraries(JasmineGraphLib PRIVATE yaml-cpp) target_link_libraries(JasmineGraphLib PRIVATE curl) +target_link_libraries(JasmineGraphLib PRIVATE antlr4-runtime) + if (CMAKE_BUILD_TYPE STREQUAL "DEBUG") # Include google test diff --git a/Dockerfile b/Dockerfile index 5d29c35e..86cc57af 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM miyurud/jasminegraph-prerequisites:20240101T095619 +FROM pre:latest RUN apt-get update && apt-get install -y libcurl4-openssl-dev sysstat nmon RUN rm -r /usr/lib/python3.8/distutils @@ -16,6 +16,23 @@ RUN if [ "$DEBUG" = "true" ]; then apt-get update \ && apt-get install --no-install-recommends -y gdb gdbserver \ && apt-get clean; fi +WORKDIR "${HOME}" +RUN mkdir antlr +WORKDIR "${HOME}"/antlr +RUN apt-get update && apt-get install --no-install-recommends -y default-jre +RUN curl -O https://s3.amazonaws.com/artifacts.opencypher.org/M23/Cypher.g4 +RUN curl -O https://www.antlr.org/download/antlr-4.13.2-complete.jar +RUN java -jar antlr-4.13.2-complete.jar -Dlanguage=Cpp -visitor Cypher.g4 +RUN apt-get purge default-jre -y + +WORKDIR "${JASMINEGRAPH_HOME}" +RUN mkdir "${JASMINEGRAPH_HOME}"/code_generated/ +RUN mkdir "${JASMINEGRAPH_HOME}"/code_generated/antlr +RUN mv /home/ubuntu/antlr/*.cpp "${JASMINEGRAPH_HOME}"/code_generated/antlr +RUN mv /home/ubuntu/antlr/*.h "${JASMINEGRAPH_HOME}"/code_generated/antlr +RUN rm -f "${HOME}"/antlr/* + +WORKDIR "${JASMINEGRAPH_HOME}" COPY ./build.sh ./build.sh COPY ./CMakeLists.txt ./CMakeLists.txt COPY ./main.h ./main.h diff --git a/src/frontend/JasmineGraphFrontEnd.cpp b/src/frontend/JasmineGraphFrontEnd.cpp index d9d02bdd..14ce0b4b 100644 --- a/src/frontend/JasmineGraphFrontEnd.cpp +++ b/src/frontend/JasmineGraphFrontEnd.cpp @@ -45,6 +45,10 @@ limitations under the License. #include "JasmineGraphFrontEndProtocol.h" #include "core/CoreConstants.h" #include "core/scheduler/JobScheduler.h" +#include "antlr4-runtime.h" +#include "/home/ubuntu/software/jasminegraph/code_generated/antlr/CypherLexer.h" +#include "/home/ubuntu/software/jasminegraph/code_generated/antlr/CypherParser.h" +#include "../query/processor/cypher/astbuilder/ASTBuilder.h" #define MAX_PENDING_CONNECTIONS 10 #define DATA_BUFFER_SIZE (FRONTEND_DATA_LENGTH + 1) @@ -64,6 +68,7 @@ bool JasmineGraphFrontEnd::strian_exit; static std::string getPartitionCount(std::string path); static void list_command(int connFd, SQLiteDBInterface *sqlite, bool *loop_exit_p); +static void cypher_ast_command(int connFd, bool *loop_exit_p); static void add_rdf_command(std::string masterIP, int connFd, SQLiteDBInterface *sqlite, bool *loop_exit_p); static void add_graph_command(std::string masterIP, int connFd, SQLiteDBInterface *sqlite, bool *loop_exit_p); static void add_graph_cust_command(std::string masterIP, int connFd, SQLiteDBInterface *sqlite, bool *loop_exit_p); @@ -169,7 +174,9 @@ void *frontendservicesesion(void *dummyPt) { break; } else if (line.compare(LIST) == 0) { list_command(connFd, sqlite, &loop_exit); - } else if (line.compare(SHTDN) == 0) { + } else if (line.compare(CYPHER_AST) == 0){ + cypher_ast_command(connFd, &loop_exit); + }else if (line.compare(SHTDN) == 0) { JasmineGraphServer::shutdown_workers(); close(connFd); exit(0); @@ -627,6 +634,49 @@ static void list_command(int connFd, SQLiteDBInterface *sqlite, bool *loop_exit_ } } +static void cypher_ast_command(int connFd, bool *loop_exit) +{ + + string msg_1 = "Input Query :"; + int result_wr = write(connFd, msg_1.c_str(), msg_1.length()); + if (result_wr < 0) { + frontend_logger.error("Error writing to socket"); + *loop_exit = true; + return; + } + result_wr = write(connFd, "\r\n", 2); + if (result_wr < 0) { + frontend_logger.error("Error writing to socket"); + *loop_exit = true; + return; + } + + // Get user response. + char user_res[FRONTEND_DATA_LENGTH + 1]; + bzero(user_res, FRONTEND_DATA_LENGTH + 1); + read(connFd, user_res, FRONTEND_DATA_LENGTH); + string user_res_s(user_res); + + antlr4::ANTLRInputStream input(user_res_s); + // Create a lexer from the input + CypherLexer lexer(&input); + + // Create a token stream from the lexer + antlr4::CommonTokenStream tokens(&lexer); + + // Create a parser from the token stream + CypherParser parser(&tokens); + + CypherASTBuilder ast_builder; + auto* ast = any_cast(ast_builder.visitOC_Cypher(parser.oC_Cypher())); + string result = ast->print(1); + int result_wrn = write(connFd, result.c_str(), result.length()); + if (result_wrn < 0) { + frontend_logger.error("Error writing to socket"); + *loop_exit = true; + } +} + static void add_rdf_command(std::string masterIP, int connFd, SQLiteDBInterface *sqlite, bool *loop_exit_p) { // add RDF graph int result_wr = write(connFd, SEND.c_str(), FRONTEND_COMMAND_LENGTH); @@ -804,7 +854,8 @@ static void add_graph_command(std::string masterIP, int connFd, SQLiteDBInterfac int result_wr = write(connFd, DONE.c_str(), DONE.size()); if (result_wr < 0) { frontend_logger.error("Error writing to socket"); - *loop_exit_p = true; + *loop_exit_p = + true; return; } result_wr = write(connFd, "\r\n", 2); diff --git a/src/frontend/JasmineGraphFrontEndProtocol.cpp b/src/frontend/JasmineGraphFrontEndProtocol.cpp index b8220750..ec8251f4 100644 --- a/src/frontend/JasmineGraphFrontEndProtocol.cpp +++ b/src/frontend/JasmineGraphFrontEndProtocol.cpp @@ -54,4 +54,5 @@ const string SLA = "sla"; const string COMMAND = "command"; const string PRIORITY = "priority(>=1)"; const string INVALID_FORMAT = "Invalid message format"; +const string CYPHER_AST = "cypher-ast"; diff --git a/src/frontend/JasmineGraphFrontEndProtocol.h b/src/frontend/JasmineGraphFrontEndProtocol.h index ad1ac85f..77ee8837 100644 --- a/src/frontend/JasmineGraphFrontEndProtocol.h +++ b/src/frontend/JasmineGraphFrontEndProtocol.h @@ -87,6 +87,7 @@ extern const string STOP_STRIAN; extern const string ADMDL; extern const string MERGE; extern const string INVALID_FORMAT; +extern const string CYPHER_AST; class JasminGraphFrontEndProtocol { // Note that this protocol do not need a handshake session since the communication in most of the time is conducted diff --git a/src/query/processor/cypher/astbuilder/ASTBuilder.cpp b/src/query/processor/cypher/astbuilder/ASTBuilder.cpp new file mode 100644 index 00000000..9d861b00 --- /dev/null +++ b/src/query/processor/cypher/astbuilder/ASTBuilder.cpp @@ -0,0 +1,5 @@ +// +// Created by thamindu on 7/24/24. +// + +#include "ASTBuilder.h" diff --git a/src/query/processor/cypher/astbuilder/ASTBuilder.h b/src/query/processor/cypher/astbuilder/ASTBuilder.h new file mode 100644 index 00000000..5e7931bf --- /dev/null +++ b/src/query/processor/cypher/astbuilder/ASTBuilder.h @@ -0,0 +1,1479 @@ +// +// Created by thamindu on 7/24/24. +// +#include +#include +#include +#include "ASTInternalNode.h" +#include "ASTLeafNoValue.h" +#include "ASTLeafValue.h" +#include "/home/ubuntu/software/jasminegraph/code_generated/antlr/CypherBaseVisitor.h" +#ifndef AST_BUILDER_H +#define AST_BUILDER_H + +using namespace std; + +class CypherASTBuilder : public CypherBaseVisitor { +public: + + // finished + std::any visitOC_Cypher(CypherParser::OC_CypherContext *ctx) override { + return visitOC_Statement(ctx->oC_Statement()); + } + + // finished + std::any visitOC_Statement(CypherParser::OC_StatementContext *ctx) override { + return visitOC_Query(ctx->oC_Query()); + } + + //finished + std::any visitOC_Query(CypherParser::OC_QueryContext *ctx) override { + if(ctx->oC_RegularQuery()) + { + return visitOC_RegularQuery(ctx->oC_RegularQuery()); + } + return visitOC_StandaloneCall(ctx->oC_StandaloneCall()); + } + + //finished + std::any visitOC_RegularQuery(CypherParser::OC_RegularQueryContext *ctx) override { + if(!ctx->oC_Union().empty()) + { + auto *node = new ASTInternalNode("UNION"); + node->addElements(any_cast(visitOC_SingleQuery(ctx->oC_SingleQuery()))); + for(CypherParser::OC_UnionContext* element : ctx->oC_Union()) + { + node->addElements(any_cast(visitOC_Union(element))); + } + return static_cast(node); + } + return visitOC_SingleQuery(ctx->oC_SingleQuery()); + } + + //finished + std::any visitOC_Union(CypherParser::OC_UnionContext *ctx) override { + if(ctx->ALL()) + { + auto *node = new ASTInternalNode("ALL"); + node->addElements(any_cast(visitOC_SingleQuery(ctx->oC_SingleQuery()))); + return static_cast(node); + } + return visitOC_SingleQuery(ctx->oC_SingleQuery()); + } + + //finished + std::any visitOC_SingleQuery(CypherParser::OC_SingleQueryContext *ctx) override { + if(ctx->oC_MultiPartQuery()) + { + return visitOC_MultiPartQuery(ctx->oC_MultiPartQuery()); + } + return visitOC_SinglePartQuery(ctx->oC_SinglePartQuery()); + } + + //finished + std::any visitOC_SinglePartQuery(CypherParser::OC_SinglePartQueryContext *ctx) override { + auto *queryNode = new ASTInternalNode("SINGLE_QUERY"); + for (CypherParser::OC_ReadingClauseContext* element : ctx->oC_ReadingClause()) { + queryNode->addElements(any_cast(visitOC_ReadingClause(element))); + } + + for(CypherParser::OC_UpdatingClauseContext* element : ctx->oC_UpdatingClause()){ + queryNode->addElements(any_cast(visitOC_UpdatingClause(element))); + } + + if(ctx->oC_Return()) + { + queryNode->addElements(any_cast(visitOC_Return(ctx->oC_Return()))); + } + return static_cast(queryNode); + } + + + //TODO: try to solve a efficient way + //finished + std::any visitOC_MultiPartQuery(CypherParser::OC_MultiPartQueryContext *ctx) override { + auto *node = new ASTInternalNode("MULTIPLE_QUERY"); + for(CypherParser::OC_WithContext* withElement : ctx->oC_With()) + { + size_t const with = withElement->getStart()->getTokenIndex(); + for(CypherParser::OC_ReadingClauseContext* element : ctx->oC_ReadingClause()) + { + if(element->getStop()->getTokenIndex() < with) + { + node->addElements(any_cast(visitOC_ReadingClause(element))); + } + } + for(CypherParser::OC_UpdatingClauseContext* element : ctx->oC_UpdatingClause()) + { + if(element->getStop()->getTokenIndex() < with) + { + node->addElements(any_cast(visitOC_UpdatingClause(element))); + } + + } + } + node->addElements(any_cast(visitOC_SinglePartQuery(ctx->oC_SinglePartQuery()))); + return static_cast(node); + } + + //finished + std::any visitOC_UpdatingClause(CypherParser::OC_UpdatingClauseContext *ctx) override { + + if(ctx->oC_Create()) + { + return visitOC_Create(ctx->oC_Create()); + }else if(ctx->oC_Delete()) + { + return visitOC_Delete(ctx->oC_Delete()); + }else if(ctx->oC_Merge()) + { + return visitOC_Merge(ctx->oC_Merge()); + }else if(ctx->oC_Remove()) + { + return visitOC_Remove(ctx->oC_Remove()); + } + return visitOC_Set(ctx->oC_Set()); + } + //finished + std::any visitOC_ReadingClause(CypherParser::OC_ReadingClauseContext *ctx) override { + if(ctx->oC_Match()) + { + return visitOC_Match(ctx->oC_Match()); + }else if(ctx->oC_Unwind()) + { + return visitOC_Unwind(ctx->oC_Unwind()); + }else + { + return visitOC_InQueryCall(ctx->oC_InQueryCall()); + } + } + + //finished + std::any visitOC_Match(CypherParser::OC_MatchContext *ctx) override { + auto *node = new ASTInternalNode("MATCH"); + if(ctx->OPTIONAL()) + { + node->addElements(new ASTLeafNoValue("OPTIONAL")); + } + node->addElements(any_cast(visitOC_Pattern(ctx->oC_Pattern()))); + if (ctx->oC_Where()) { + node->addElements(any_cast(visitOC_Where(ctx->oC_Where()))); + } + return static_cast(node); + } + + //finished + std::any visitOC_Unwind(CypherParser::OC_UnwindContext *ctx) override { + auto *node = new ASTInternalNode("UNWIND"); + auto *nodeAS = new ASTInternalNode("AS"); + nodeAS->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + nodeAS->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + node->addElements(nodeAS); + return static_cast(node); + } + + //finished + std::any visitOC_Merge(CypherParser::OC_MergeContext *ctx) override { + auto *node = new ASTInternalNode("MERGE"); + node->addElements(any_cast(visitOC_PatternPart(ctx->oC_PatternPart()))); + for(CypherParser::OC_MergeActionContext* element : ctx->oC_MergeAction()) + { + node->addElements(any_cast(visitOC_MergeAction(element))); + } + + return static_cast(node); + } + + //finished + std::any visitOC_MergeAction(CypherParser::OC_MergeActionContext *ctx) override { + if(ctx->CREATE()) + { + auto *node = new ASTInternalNode("ON_CREATE"); + node->addElements(any_cast(visitOC_Set(ctx->oC_Set()))); + return static_cast(node); + } + auto *node = new ASTInternalNode("ON_MATCH"); + node->addElements(any_cast(visitOC_Set(ctx->oC_Set()))); + return static_cast(node); + } + + //finished + std::any visitOC_Create(CypherParser::OC_CreateContext *ctx) override { + auto *node = new ASTInternalNode("CREATE"); + node->addElements(any_cast(visitOC_Pattern(ctx->oC_Pattern()))); + return static_cast(node); + } + + + //finished + std::any visitOC_Set(CypherParser::OC_SetContext *ctx) override { + if(ctx->oC_SetItem().size()>1) + { + auto *node = new ASTInternalNode("MULTIPLE_SET"); + for(CypherParser::OC_SetItemContext* element: ctx->oC_SetItem()) + { + node->addElements(any_cast(visitOC_SetItem(element))); + } + return static_cast(node); + } + return visitOC_SetItem(ctx->oC_SetItem()[0]); + } + + //finished + std::any visitOC_SetItem(CypherParser::OC_SetItemContext *ctx) override { + if(ctx->oC_PropertyExpression()) + { + auto *node = new ASTInternalNode("SET"); + node->addElements(any_cast(visitOC_PropertyExpression(ctx->oC_PropertyExpression()))); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + return static_cast(node); + } else + { + if(ctx->getText().find("+=") != std::string::npos) + { + auto *node = new ASTInternalNode("SET_+="); + node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + return static_cast(node); + }else if (ctx->getText().find("=") != std::string::npos) + { + auto *node = new ASTInternalNode("SET_="); + node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + return static_cast(node); + } + auto *node = new ASTInternalNode("SET"); + node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + node->addElements(any_cast(visitOC_NodeLabels(ctx->oC_NodeLabels()))); + return static_cast(node); + } + } + + //finished + std::any visitOC_Delete(CypherParser::OC_DeleteContext *ctx) override { + auto *deleteNode = new ASTInternalNode("DELETE"); + for(CypherParser::OC_ExpressionContext* element : ctx->oC_Expression()) + { + deleteNode->addElements(any_cast(visitOC_Expression(element))); + } + if(ctx->DETACH()) + { + auto *node = new ASTInternalNode("DETACH"); + node->addElements(deleteNode); + return static_cast(node); + } + return static_cast(deleteNode); + } + + //finished + std::any visitOC_Remove(CypherParser::OC_RemoveContext *ctx) override { + if(ctx->oC_RemoveItem().size()>1) + { + auto *node = new ASTInternalNode("REMOVE_LIST"); + for(CypherParser::OC_RemoveItemContext* element : ctx->oC_RemoveItem()) + { + node->addElements(any_cast(visitOC_RemoveItem(element))); + } + return static_cast(node); + } + + return visitOC_RemoveItem(ctx->oC_RemoveItem()[0]); + } + + + //finished + std::any visitOC_RemoveItem(CypherParser::OC_RemoveItemContext *ctx) override { + auto *node = new ASTInternalNode("REMOVE"); + if(ctx->oC_Variable()) + { + node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + node->addElements(any_cast(visitOC_NodeLabels(ctx->oC_NodeLabels()))); + return static_cast(node); + } + node->addElements(any_cast(visitOC_PropertyExpression(ctx->oC_PropertyExpression()))); + return static_cast(node); + } + + //finished + std::any visitOC_InQueryCall(CypherParser::OC_InQueryCallContext *ctx) override { + auto *node = new ASTInternalNode("CALL"); + node->addElements(any_cast(visitOC_ExplicitProcedureInvocation(ctx->oC_ExplicitProcedureInvocation()))); + + if(ctx->oC_YieldItems()) + { + node->addElements(any_cast(visitOC_YieldItems(ctx->oC_YieldItems()))); + } + return static_cast(node); + } + + //finished + std::any visitOC_StandaloneCall(CypherParser::OC_StandaloneCallContext *ctx) override { + if(ctx->oC_ExplicitProcedureInvocation()) + { + auto *node = new ASTInternalNode("CALL"); + node->addElements(any_cast(visitOC_ExplicitProcedureInvocation(ctx->oC_ExplicitProcedureInvocation()))); + if(ctx->oC_YieldItems()) + { + node->addElements(any_cast(visitOC_YieldItems(ctx->oC_YieldItems()))); + }else if(ctx->getText().find('*') != std::string::npos) + { + auto *star = new ASTLeafNoValue("*"); + node->addElements(star); + } + return static_cast(node); + } + + auto *node = new ASTInternalNode("CALL"); + node->addElements(any_cast(visitOC_ImplicitProcedureInvocation(ctx->oC_ImplicitProcedureInvocation()))); + if(ctx->oC_YieldItems()) + { + node->addElements(any_cast(visitOC_YieldItems(ctx->oC_YieldItems()))); + }else if(ctx->getText().find('*') != std::string::npos) + { + auto *star = new ASTLeafNoValue("*"); + node->addElements(star); + } + return static_cast(node); + } + + //finished + std::any visitOC_YieldItems(CypherParser::OC_YieldItemsContext *ctx) override { + + auto *node = new ASTInternalNode("YIELD_ITEMS"); + for(CypherParser::OC_YieldItemContext* element : ctx->oC_YieldItem()) + { + node->addElements(any_cast(visitOC_YieldItem(element))); + } + if(ctx->oC_Where()) + { + node->addElements(any_cast(visitOC_Where(ctx->oC_Where()))); + } + return static_cast(node); + } + + //finished + std::any visitOC_YieldItem(CypherParser::OC_YieldItemContext *ctx) override { + auto *node = new ASTInternalNode("YIELD"); + if(ctx->oC_ProcedureResultField()) + { + auto *as = new ASTInternalNode("AS"); + as->addElements(any_cast(visitOC_ProcedureResultField(ctx->oC_ProcedureResultField()))); + as->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + node->addElements(as); + } + node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + return static_cast(node); + } + + //finished + std::any visitOC_With(CypherParser::OC_WithContext *ctx) override { + auto *node = new ASTInternalNode("WITH"); + node->addElements(any_cast(visitOC_ProjectionBody(ctx->oC_ProjectionBody()))); + if(ctx->oC_Where()) + { + node->addElements(any_cast(visitOC_Where(ctx->oC_Where()))); + } + return static_cast(node); + } + + //finished + std::any visitOC_Return(CypherParser::OC_ReturnContext *ctx) override { + return visitOC_ProjectionBody(ctx->oC_ProjectionBody()); + } + + //finished + std::any visitOC_ProjectionBody(CypherParser::OC_ProjectionBodyContext *ctx) override { + auto *node = new ASTInternalNode("RETURN"); + if(ctx->DISTINCT()) + { + auto *distinct = new ASTInternalNode("DISTINCT"); + distinct->addElements(any_cast(visitOC_ProjectionItems(ctx->oC_ProjectionItems()))); + node->addElements(distinct); + }else + { + node->addElements(any_cast(visitOC_ProjectionItems(ctx->oC_ProjectionItems()))); + } + if(ctx->oC_Order()) + { + node->addElements(any_cast(visitOC_Order(ctx->oC_Order()))); + } + if(ctx->oC_Skip()) + { + node->addElements(any_cast(visitOC_Skip(ctx->oC_Skip()))); + } + if(ctx->oC_Limit()) + { + node->addElements(any_cast(visitOC_Limit(ctx->oC_Limit()))); + } + return static_cast(node); + } + + //finished + std::any visitOC_ProjectionItems(CypherParser::OC_ProjectionItemsContext *ctx) override { + auto *node = new ASTInternalNode("RETURN_BODY"); + if(ctx->children[0]->getText() == "*") + { + node->addElements(new ASTLeafNoValue("*")); + } + for(CypherParser::OC_ProjectionItemContext* element : ctx->oC_ProjectionItem()) + { + node->addElements(any_cast(visitOC_ProjectionItem(element))); + } + return static_cast(node); + } + + //finished + std::any visitOC_ProjectionItem(CypherParser::OC_ProjectionItemContext *ctx) override { + if(ctx->oC_Variable()) + { + auto *node = new ASTInternalNode("AS"); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + return static_cast(node); + } + return visitOC_Expression(ctx->oC_Expression()); + } + + //finished + std::any visitOC_Order(CypherParser::OC_OrderContext *ctx) override { + auto *node = new ASTInternalNode("ORDERED BY"); + for(CypherParser::OC_SortItemContext* element : ctx->oC_SortItem()) + { + node->addElements(any_cast(visitOC_SortItem(element))); + } + return static_cast(node); + } + + //finished + std::any visitOC_Skip(CypherParser::OC_SkipContext *ctx) override { + auto *node = new ASTInternalNode("SKIP"); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + return static_cast(node); + } + + //finished + std::any visitOC_Limit(CypherParser::OC_LimitContext *ctx) override { + auto *node = new ASTInternalNode("LIMIT"); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + return static_cast(node); + } + + + //finished + std::any visitOC_SortItem(CypherParser::OC_SortItemContext *ctx) override { + if(ctx->ASC() or ctx->ASCENDING()) + { + auto *node = new ASTInternalNode("ASC"); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + return static_cast(node); + }else + { + auto *node = new ASTInternalNode("DESC"); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + return static_cast(node); + } + } + + //finished + std::any visitOC_Where(CypherParser::OC_WhereContext *ctx) override { + auto *node = new ASTInternalNode("WHERE"); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + return static_cast(node); + } + + //finished + std::any visitOC_Pattern(CypherParser::OC_PatternContext *ctx) override { + auto *node = new ASTInternalNode("PATTERN"); + for(CypherParser::OC_PatternPartContext* element : ctx->oC_PatternPart()) + { + node->addElements(any_cast(visitOC_PatternPart(element))); + } + return static_cast(node); + } + + //finished + std::any visitOC_PatternPart(CypherParser::OC_PatternPartContext *ctx) override { + if(ctx->oC_Variable()) + { + auto *node = new ASTInternalNode("="); + + node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + node->addElements(any_cast(visitOC_AnonymousPatternPart(ctx->oC_AnonymousPatternPart()))); + + return static_cast(node); + } + return visitOC_AnonymousPatternPart(ctx->oC_AnonymousPatternPart()); + } + + //finished + std::any visitOC_AnonymousPatternPart(CypherParser::OC_AnonymousPatternPartContext *ctx) override { + return visitOC_PatternElement(ctx->oC_PatternElement()); + } + + //finished + std::any visitOC_PatternElement(CypherParser::OC_PatternElementContext *ctx) override { + if(ctx->oC_PatternElement()) + { + return visitOC_PatternElement(ctx->oC_PatternElement()); + } + + if(!ctx->oC_PatternElementChain().empty()) + { + auto *node = new ASTInternalNode("PATTERN_ELEMENTS"); + node->addElements(any_cast(visitOC_NodePattern(ctx->oC_NodePattern()))); + for(CypherParser::OC_PatternElementChainContext* element : ctx->oC_PatternElementChain()) + { + node->addElements(any_cast(visitOC_PatternElementChain(element))); + } + return static_cast(node); + } + return visitOC_NodePattern(ctx->oC_NodePattern()); + } + + //finsihed + std::any visitOC_RelationshipsPattern(CypherParser::OC_RelationshipsPatternContext *ctx) override { + auto *node = new ASTInternalNode("PATTERN_ELEMENTS"); + node->addElements(any_cast(visitOC_NodePattern(ctx->oC_NodePattern()))); + for(CypherParser::OC_PatternElementChainContext* element : ctx->oC_PatternElementChain()) + { + node->addElements(any_cast(visitOC_PatternElementChain(element))); + } + return static_cast(node); + } + + //finished + std::any visitOC_NodePattern(CypherParser::OC_NodePatternContext *ctx) override { + auto *node = new ASTInternalNode("NODE_PATTERN"); + if(ctx->oC_Variable()) + { + node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + } + if(ctx->oC_NodeLabels()) + { + node->addElements(any_cast(visitOC_NodeLabels(ctx->oC_NodeLabels()))); + } + if(ctx->oC_Properties()) + { + node->addElements(any_cast(visitOC_Properties(ctx->oC_Properties()))); + } + return static_cast(node); + } + + //finished + std::any visitOC_PatternElementChain(CypherParser::OC_PatternElementChainContext *ctx) override { + auto *node = new ASTInternalNode("PATTERN_ELEMENT_CHAIN"); + node->addElements(any_cast(visitOC_RelationshipPattern(ctx->oC_RelationshipPattern()))); + node->addElements(any_cast(visitOC_NodePattern(ctx->oC_NodePattern()))); + return static_cast(node); + } + + //finished + std::any visitOC_RelationshipPattern(CypherParser::OC_RelationshipPatternContext *ctx) override { + auto *node = new ASTInternalNode("RELATIONSHIP_PATTTERN"); + if(ctx->oC_LeftArrowHead() && !ctx->oC_RightArrowHead()) + { + node->addElements(any_cast(visitOC_LeftArrowHead(ctx->oC_LeftArrowHead()))); + }else if(!ctx->oC_LeftArrowHead() && ctx->oC_RightArrowHead()) + { + node->addElements(any_cast(visitOC_RightArrowHead(ctx->oC_RightArrowHead()))); + }else + { + node->addElements(new ASTLeafNoValue("UNIDIRECTION_ARROW")); + } + if(ctx->oC_RelationshipDetail()) + { + node->addElements(any_cast(visitOC_RelationshipDetail(ctx->oC_RelationshipDetail()))); + } + return static_cast(node); + } + + //finished + std::any visitOC_RelationshipDetail(CypherParser::OC_RelationshipDetailContext *ctx) override { + auto *node = new ASTInternalNode("RELATIONSHIP_DETAILS"); + if(ctx->oC_Variable()) + { + node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + } + if(ctx->oC_RelationshipTypes()) + { + node->addElements(any_cast(visitOC_RelationshipTypes(ctx->oC_RelationshipTypes()))); + } + if(ctx->oC_RangeLiteral()) + { + node->addElements(any_cast(visitOC_RangeLiteral(ctx->oC_RangeLiteral()))); + } + if(ctx->oC_Properties()) + { + node->addElements(any_cast(visitOC_Properties(ctx->oC_Properties()))); + } + return static_cast(node); ; + } + + //finished + std::any visitOC_Properties(CypherParser::OC_PropertiesContext *ctx) override { + if(ctx->oC_Parameter()) + { + return visitOC_Parameter(ctx->oC_Parameter()); + } + return visitOC_MapLiteral(ctx->oC_MapLiteral()); + } + + //finished + std::any visitOC_RelationshipTypes(CypherParser::OC_RelationshipTypesContext *ctx) override { + + if(ctx->oC_RelTypeName().size()>1) + { + auto *node = new ASTInternalNode("RELATIONSHIP_TYPES"); + for(CypherParser::OC_RelTypeNameContext* element : ctx->oC_RelTypeName()) + { + node->addElements(any_cast(visitOC_RelTypeName(element))); + } + return static_cast(node); + } + return visitOC_RelTypeName(ctx->oC_RelTypeName()[0]); + } + + //finished + std::any visitOC_NodeLabels(CypherParser::OC_NodeLabelsContext *ctx) override { + if(ctx->oC_NodeLabel().size()>1) + { + auto *node = new ASTInternalNode("NODE_LABELS"); + for(CypherParser::OC_NodeLabelContext* element : ctx->oC_NodeLabel()) + { + node->addElements(any_cast(visitOC_NodeLabel(element))); + } + return static_cast(node); + } + return visitOC_NodeLabel(ctx->oC_NodeLabel()[0]); + } + + //finished + std::any visitOC_NodeLabel(CypherParser::OC_NodeLabelContext *ctx) override { + auto *node = new ASTInternalNode("NODE_LABEL"); + node->addElements(any_cast(visitOC_LabelName(ctx->oC_LabelName()))); + return static_cast(node); + } + + //finished + std::any visitOC_RangeLiteral(CypherParser::OC_RangeLiteralContext *ctx) override { + auto *node = new ASTInternalNode("RANGE"); + if(ctx->oC_IntegerLiteral().size()>1) + { + node->addElements(any_cast(visitOC_IntegerLiteral(ctx->oC_IntegerLiteral()[0]))); + node->addElements(any_cast(visitOC_IntegerLiteral(ctx->oC_IntegerLiteral()[1]))); + return static_cast(node); + } + node->addElements(any_cast(visitOC_IntegerLiteral(ctx->oC_IntegerLiteral()[0]))); + return static_cast(node); + } + + //finished + std::any visitOC_LabelName(CypherParser::OC_LabelNameContext *ctx) override { + return visitOC_SchemaName(ctx->oC_SchemaName()); + } + + //finished + std::any visitOC_RelTypeName(CypherParser::OC_RelTypeNameContext *ctx) override { + return visitOC_SchemaName(ctx->oC_SchemaName()); + } + + //finished + std::any visitOC_PropertyExpression(CypherParser::OC_PropertyExpressionContext *ctx) override { + auto *node = new ASTInternalNode("PROPERTY"); + node->addElements(any_cast(visitOC_Atom(ctx->oC_Atom()))); + for(CypherParser::OC_PropertyLookupContext* element : ctx->oC_PropertyLookup()) + { + node->addElements(any_cast(visitOC_PropertyLookup(element))); + } + return static_cast(node); + } + + //finished + std::any visitOC_Expression(CypherParser::OC_ExpressionContext *ctx) override { + return visitOC_OrExpression(ctx->oC_OrExpression()); + } + + //finished + std::any visitOC_OrExpression(CypherParser::OC_OrExpressionContext *ctx) override { + if(ctx->oC_XorExpression().size()>1) + { + auto *node = new ASTInternalNode("OR"); + for(CypherParser::OC_XorExpressionContext* element : ctx->oC_XorExpression()) + { + node->addElements(any_cast(visitOC_XorExpression(element))); + } + return static_cast(node); + } + return visitOC_XorExpression(ctx->oC_XorExpression()[0]); + } + + //finished + std::any visitOC_XorExpression(CypherParser::OC_XorExpressionContext *ctx) override { + if(ctx->oC_AndExpression().size()>1) + { + auto *node = new ASTInternalNode("XOR"); + for(CypherParser::OC_AndExpressionContext* element : ctx->oC_AndExpression()) + { + node->addElements(any_cast(visitOC_AndExpression(element))); + } + } + return visitOC_AndExpression(ctx->oC_AndExpression()[0]); + } + + //finished + std::any visitOC_AndExpression(CypherParser::OC_AndExpressionContext *ctx) override { + if(ctx->oC_NotExpression().size()>1) + { + auto *node = new ASTInternalNode("AND"); + for(CypherParser::OC_NotExpressionContext* element : ctx->oC_NotExpression()) + { + node->addElements(any_cast(visitOC_NotExpression(element))); + } + return static_cast(node); + } + return visitOC_NotExpression(ctx->oC_NotExpression()[0]); + } + + //finished + std::any visitOC_NotExpression(CypherParser::OC_NotExpressionContext *ctx) override { + if(!ctx->NOT().empty()) + { + if(ctx->NOT().size() % 2 != 0) + { + auto *node = new ASTInternalNode("NOT"); + node->addElements(any_cast(visitOC_ComparisonExpression(ctx->oC_ComparisonExpression()))); + return static_cast(node); + } + } + return visitOC_ComparisonExpression(ctx->oC_ComparisonExpression()); + } + + + //finished + std::any visitOC_ComparisonExpression(CypherParser::OC_ComparisonExpressionContext *ctx) override { + if(!ctx->oC_PartialComparisonExpression().empty()) + { + auto *node = new ASTInternalNode("COMPARISON"); + node->addElements(any_cast(visitOC_StringListNullPredicateExpression(ctx->oC_StringListNullPredicateExpression()))); + for(CypherParser::OC_PartialComparisonExpressionContext* element : ctx->oC_PartialComparisonExpression()) + { + node->addElements(any_cast(visitOC_PartialComparisonExpression(element))); + } + return static_cast(node); + } + return visitOC_StringListNullPredicateExpression(ctx->oC_StringListNullPredicateExpression()); + } + + //finished + std::any visitOC_PartialComparisonExpression(CypherParser::OC_PartialComparisonExpressionContext *ctx) override { + if(ctx->getText().find(">") != string::npos) + { + auto *node = new ASTInternalNode(">"); + node->addElements(any_cast(visitOC_StringListNullPredicateExpression(ctx->oC_StringListNullPredicateExpression()))); + return static_cast(node); + }else if(ctx->getText().find("<>") != string::npos) + { + auto *node = new ASTInternalNode("<>"); + node->addElements(any_cast(visitOC_StringListNullPredicateExpression(ctx->oC_StringListNullPredicateExpression()))); + return static_cast(node); + }else if(ctx->getText().find("=") != string::npos) + { + auto *node = new ASTInternalNode("=="); + node->addElements(any_cast(visitOC_StringListNullPredicateExpression(ctx->oC_StringListNullPredicateExpression()))); + return static_cast(node); + }else if(ctx->getText().find("<") != string::npos) + { + auto *node = new ASTInternalNode("<"); + node->addElements(any_cast(visitOC_StringListNullPredicateExpression(ctx->oC_StringListNullPredicateExpression()))); + return static_cast(node); + }else if(ctx->getText().find(">=") != string::npos) + { + auto *node = new ASTInternalNode(">="); + node->addElements(any_cast(visitOC_StringListNullPredicateExpression(ctx->oC_StringListNullPredicateExpression()))); + return static_cast(node); + }else + { + auto *node = new ASTInternalNode("<="); + node->addElements(any_cast(visitOC_StringListNullPredicateExpression(ctx->oC_StringListNullPredicateExpression()))); + return static_cast(node); + } + } + + //finished + std::any visitOC_StringListNullPredicateExpression(CypherParser::OC_StringListNullPredicateExpressionContext *ctx) override { + auto *node = new ASTInternalNode("PREDICATE_EXPRESSIONS"); + node->addElements(any_cast(visitOC_AddOrSubtractExpression(ctx->oC_AddOrSubtractExpression()))); + if(!ctx->oC_StringPredicateExpression().empty()) + { + auto *strPredicate = new ASTInternalNode("STRING_PREDICATES"); + for(CypherParser::OC_StringPredicateExpressionContext* element: ctx->oC_StringPredicateExpression()) + { + strPredicate->addElements(any_cast(visitOC_StringPredicateExpression(element))); + } + node->addElements(strPredicate); + } + if(!ctx->oC_ListPredicateExpression().empty()) + { + auto *listPredicate = new ASTInternalNode("LIST_PREDICATES"); + for(CypherParser::OC_ListPredicateExpressionContext* element: ctx->oC_ListPredicateExpression()) + { + listPredicate->addElements(any_cast(visitOC_ListPredicateExpression(element))); + } + node->addElements(listPredicate); + } + if(!ctx->oC_NullPredicateExpression().empty()) + { + auto *nullPredicate = new ASTInternalNode("NULL_PREDICATES"); + for(CypherParser::OC_NullPredicateExpressionContext* element: ctx->oC_NullPredicateExpression()) + { + nullPredicate->addElements(any_cast(visitOC_NullPredicateExpression(element))); + } + node->addElements(nullPredicate); + } + if(node->elements.size()>1) + { + return static_cast(node); + }else + { + return visitOC_AddOrSubtractExpression(ctx->oC_AddOrSubtractExpression()); + } + } + + //finished + std::any visitOC_StringPredicateExpression(CypherParser::OC_StringPredicateExpressionContext *ctx) override { + if(ctx->STARTS()) + { + auto *node = new ASTInternalNode("STARTS_WITH"); + node->addElements(any_cast(visitOC_AddOrSubtractExpression(ctx->oC_AddOrSubtractExpression()))); + return static_cast(node); + }else if(ctx->ENDS()) + { + auto *node = new ASTInternalNode("ENDS_WITH"); + node->addElements(any_cast(visitOC_AddOrSubtractExpression(ctx->oC_AddOrSubtractExpression()))); + return static_cast(node); + }else + { + auto *node = new ASTInternalNode("CONTAINS"); + node->addElements(any_cast(visitOC_AddOrSubtractExpression(ctx->oC_AddOrSubtractExpression()))); + return static_cast(node); + } + } + + + //finished + std::any visitOC_ListPredicateExpression(CypherParser::OC_ListPredicateExpressionContext *ctx) override { + auto *node = new ASTInternalNode("IN"); + node->addElements(any_cast(visitOC_AddOrSubtractExpression(ctx->oC_AddOrSubtractExpression()))); + return static_cast(node); + } + + //finished + std::any visitOC_NullPredicateExpression(CypherParser::OC_NullPredicateExpressionContext *ctx) override { + if(ctx->NOT()) + { + auto *node = new ASTLeafNoValue("IS_NOT_NULL"); + return static_cast(node); + } + auto *node = new ASTLeafNoValue("IS_NULL"); + return static_cast(node); + } + + //finished + std::any visitOC_AddOrSubtractExpression(CypherParser::OC_AddOrSubtractExpressionContext *ctx) override { + if(ctx->oC_MultiplyDivideModuloExpression().size()>1) + { + int multIndex =1; + auto *node = new ASTInternalNode("ADD_OR_SUBSTRACT"); + node->addElements(any_cast(visitOC_MultiplyDivideModuloExpression(ctx->oC_MultiplyDivideModuloExpression(0)))); + + for(int i=0; ichildren.size();i++) + { + if(ctx->children[i]->getText() == "+") + { + auto *plus = new ASTInternalNode("+"); + plus->addElements(any_cast(visitOC_MultiplyDivideModuloExpression(ctx->oC_MultiplyDivideModuloExpression(multIndex++)))); + node->addElements(plus); + }else if(ctx->children[i]->getText() == "-") + { + auto *minus = new ASTInternalNode("-"); + minus->addElements(any_cast(visitOC_MultiplyDivideModuloExpression(ctx->oC_MultiplyDivideModuloExpression(multIndex++)))); + node->addElements(minus); + } + } + return static_cast(node); + } + return visitOC_MultiplyDivideModuloExpression(ctx->oC_MultiplyDivideModuloExpression(0)); + } + + //finished + std::any visitOC_MultiplyDivideModuloExpression(CypherParser::OC_MultiplyDivideModuloExpressionContext *ctx) override { + if(ctx->oC_PowerOfExpression().size()>1) + { + int powIndex = 1; + auto *node = new ASTInternalNode("MULTIPLY_DIVID_MODULO"); + node->addElements(any_cast(visitOC_PowerOfExpression(ctx->oC_PowerOfExpression(0)))); + + for(int i=0; ichildren.size();i++) + { + if(ctx->children[i]->getText() == "*") + { + auto *plus = new ASTInternalNode("*"); + plus->addElements(any_cast(visitOC_PowerOfExpression(ctx->oC_PowerOfExpression(powIndex++)))); + node->addElements(plus); + }else if(ctx->children[i]->getText() == "/") + { + auto *minus = new ASTInternalNode("/"); + minus->addElements(any_cast(visitOC_PowerOfExpression(ctx->oC_PowerOfExpression(powIndex++)))); + node->addElements(minus); + } + } + return static_cast(node); + } + + return visitOC_PowerOfExpression(ctx->oC_PowerOfExpression(0)); + } + + //finished + std::any visitOC_PowerOfExpression(CypherParser::OC_PowerOfExpressionContext *ctx) override { + if(ctx->oC_UnaryAddOrSubtractExpression().size()>1) + { + int unaryIndex = 1; + auto *node = new ASTInternalNode("POWER_OF"); + node->addElements(any_cast(visitOC_UnaryAddOrSubtractExpression(ctx->oC_UnaryAddOrSubtractExpression(0)))); + + for(int i=0; ichildren.size();i++) + { + if(ctx->children[i]->getText() == "^") + { + auto *plus = new ASTInternalNode("^"); + plus->addElements(any_cast(visitOC_UnaryAddOrSubtractExpression(ctx->oC_UnaryAddOrSubtractExpression(unaryIndex++)))); + node->addElements(plus); + } + } + return static_cast(node); + } + return visitOC_UnaryAddOrSubtractExpression(ctx->oC_UnaryAddOrSubtractExpression(0)); + } + + + //finished + std::any visitOC_UnaryAddOrSubtractExpression(CypherParser::OC_UnaryAddOrSubtractExpressionContext *ctx) override { + if(ctx->children[0]->getText() == "+") + { + auto *node = new ASTInternalNode("UNARY_+"); + node->addElements(any_cast(visitOC_NonArithmeticOperatorExpression(ctx->oC_NonArithmeticOperatorExpression()))); + return static_cast(node); + }else if(ctx->children[0]->getText() == "-") + { + auto *node = new ASTInternalNode("UNARY_-"); + node->addElements(any_cast(visitOC_NonArithmeticOperatorExpression(ctx->oC_NonArithmeticOperatorExpression()))); + return static_cast(node); + }else + { + return visitOC_NonArithmeticOperatorExpression(ctx->oC_NonArithmeticOperatorExpression()); + } + } + + //finished + std::any visitOC_NonArithmeticOperatorExpression(CypherParser::OC_NonArithmeticOperatorExpressionContext *ctx) override { + if(!ctx->oC_ListOperatorExpression().empty() | !ctx->oC_PropertyLookup().empty()) + { + auto *node = new ASTInternalNode("NON_ARITHMETIC_OPERATOR"); + int i = 0; + int j = 0; + for(auto *child : ctx->children) + { + std::string typeName = typeid(*child).name(); + if(typeName.substr(17) == "OC_AtomContextE") + { + node->addElements(any_cast(visitOC_Atom(ctx->oC_Atom()))); + }else if(typeName.substr(17) == "OC_PropertyLookupContextE") + { + node->addElements(any_cast(visitOC_PropertyLookup(ctx->oC_PropertyLookup(i++)))); + }else if(typeName.substr(17) == "OC_ListOperatorExpressionContextE") + { + node->addElements(any_cast(visitOC_ListOperatorExpression(ctx->oC_ListOperatorExpression(j++)))); + }else + { + node->addElements(any_cast(visitOC_NodeLabels(ctx->oC_NodeLabels()))); + } + } + return static_cast(node); + } + return visitOC_Atom(ctx->oC_Atom()); + } + + //finished + std::any visitOC_ListOperatorExpression(CypherParser::OC_ListOperatorExpressionContext *ctx) override { + if(ctx->oC_Expression().size() == 2) + { + auto *node = new ASTInternalNode("LIST_INDEX_RANGE"); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression(0)))); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression(1)))); + return static_cast(node); + } + auto *node = new ASTInternalNode("LIST_INDEX"); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression(0)))); + return static_cast(node); + } + + //finished + std::any visitOC_PropertyLookup(CypherParser::OC_PropertyLookupContext *ctx) override { + return visitOC_PropertyKeyName(ctx->oC_PropertyKeyName()); + } + + //finished + std::any visitOC_Atom(CypherParser::OC_AtomContext *ctx) override { + if(ctx->oC_Literal()) + { + return visitOC_Literal(ctx->oC_Literal()); + }else if(ctx->oC_Parameter()) + { + return visitOC_Parameter(ctx->oC_Parameter()); + }else if(ctx->oC_Quantifier()) + { + return visitOC_Quantifier(ctx->oC_Quantifier()); + }else if(ctx->oC_Variable()) + { + return visitOC_Variable(ctx->oC_Variable()); + }else if(ctx->oC_CaseExpression()) + { + return visitOC_CaseExpression(ctx->oC_CaseExpression()); + }else if(ctx->oC_ExistentialSubquery()) + { + return visitOC_ExistentialSubquery(ctx->oC_ExistentialSubquery()); + }else if(ctx->oC_FunctionInvocation()) + { + return visitOC_FunctionInvocation(ctx->oC_FunctionInvocation()); + }else if(ctx->oC_ListComprehension()) + { + return visitOC_ListComprehension(ctx->oC_ListComprehension()); + }else if(ctx->oC_ParenthesizedExpression()) + { + return visitOC_ParenthesizedExpression(ctx->oC_ParenthesizedExpression()); + }else if(ctx->oC_PatternComprehension()) + { + return visitOC_PatternComprehension(ctx->oC_PatternComprehension()); + }else if(ctx->oC_PatternPredicate()) + { + return visitOC_PatternPredicate(ctx->oC_PatternPredicate()); + }else + { + auto *node = new ASTLeafValue("COUNT", "*"); + return static_cast(node); + } + } + + //finished + std::any visitOC_CaseExpression(CypherParser::OC_CaseExpressionContext *ctx) override { + auto *caseNode = new ASTInternalNode("CASE_PATTERN"); + int caseAlt = 0; + for(int i = 0; ichildren.size(); i++) + { + string text = ctx->children[i]->getText(); + std::transform(text.begin(), text.end(), text.begin(), ::toupper); + string type; + if(i+2 < ctx->children.size()) + { + type = typeid(*ctx->children[i+2]).name(); + } + if(text == "CASE" && type.substr(17) == "OC_ExpressionContextE") + { + auto *node = new ASTInternalNode("CASE_EXPRESSION"); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression(0)))); + caseNode->addElements(node); + }else if(text == "ELSE" && ctx->oC_Expression().size()>1) + { + auto *node = new ASTInternalNode("ELSE_EXPRESSION"); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression(1)))); + caseNode->addElements(node); + }else if(text == "ELSE") + { + auto *node = new ASTInternalNode("ELSE_EXPRESSION"); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression(0)))); + caseNode->addElements(node); + }else if(text.find("WHEN") != string::npos) + { + caseNode->addElements(any_cast(visitOC_CaseAlternative(ctx->oC_CaseAlternative(caseAlt++)))); + } + } + return static_cast(caseNode); + } + + //finished + std::any visitOC_CaseAlternative(CypherParser::OC_CaseAlternativeContext *ctx) override { + auto *node = new ASTInternalNode("CASE"); + + auto *when = new ASTInternalNode("WHEN"); + when->addElements(any_cast(visitOC_Expression(ctx->oC_Expression(0)))); + + auto *then = new ASTInternalNode("THEN"); + then->addElements(any_cast(visitOC_Expression(ctx->oC_Expression(1)))); + + node->addElements(when); + node->addElements(then); + return static_cast(node); + } + + //finished + std::any visitOC_ListComprehension(CypherParser::OC_ListComprehensionContext *ctx) override { + auto *node = new ASTInternalNode("LIST_COMPREHENSION"); + node->addElements(any_cast(visitOC_FilterExpression(ctx->oC_FilterExpression()))); + if(ctx->getText().find('|') != string::npos) + { + auto *result = new ASTInternalNode("FILTER_RESULT"); + result->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + node->addElements(result); + } + return static_cast(node); + } + + //finished + std::any visitOC_PatternComprehension(CypherParser::OC_PatternComprehensionContext *ctx) override { + auto *node = new ASTInternalNode("PATTERN_COMPREHENSION"); + if(ctx->oC_Variable()) + { + auto *eual = new ASTInternalNode("="); + eual->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + eual->addElements(any_cast(visitOC_RelationshipsPattern(ctx->oC_RelationshipsPattern()))); + node->addElements(eual); + }else + { + node->addElements(any_cast(visitOC_RelationshipsPattern(ctx->oC_RelationshipsPattern()))); + } + if(ctx->oC_Where()) + { + node->addElements(any_cast(visitOC_Where(ctx->oC_Where()))); + } + auto *result = new ASTInternalNode("FILTER_RESULT"); + result->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + node->addElements(result); + return static_cast(node); + } + + //finished + std::any visitOC_Quantifier(CypherParser::OC_QuantifierContext *ctx) override { + if(ctx->ALL()) + { + auto *node = new ASTInternalNode("ALL"); + node->addElements(any_cast(visitOC_FilterExpression(ctx->oC_FilterExpression()))); + return static_cast(node); + }else if(ctx->ANY()) + { + auto *node = new ASTInternalNode("ANY"); + node->addElements(any_cast(visitOC_FilterExpression(ctx->oC_FilterExpression()))); + return static_cast(node); + }else if(ctx->NONE()) + { + auto *node = new ASTInternalNode("NONE"); + node->addElements(any_cast(visitOC_FilterExpression(ctx->oC_FilterExpression()))); + return static_cast(node); + }else + { + auto *node = new ASTInternalNode("SINGLE"); + node->addElements(any_cast(visitOC_FilterExpression(ctx->oC_FilterExpression()))); + return static_cast(node); + } + } + + //finished + std::any visitOC_FilterExpression(CypherParser::OC_FilterExpressionContext *ctx) override { + auto *node = new ASTInternalNode("FILTER_EXPRESSION"); + node->addElements(any_cast(visitOC_IdInColl(ctx->oC_IdInColl()))); + if(ctx->oC_Where()) + { + node->addElements(any_cast(visitOC_Where(ctx->oC_Where()))); + } + return static_cast(node); + } + + //finished + std::any visitOC_PatternPredicate(CypherParser::OC_PatternPredicateContext *ctx) override { + return visitOC_RelationshipsPattern(ctx->oC_RelationshipsPattern()); + } + + //finished + std::any visitOC_ParenthesizedExpression(CypherParser::OC_ParenthesizedExpressionContext *ctx) override { + return visitOC_Expression(ctx->oC_Expression()); + } + + //finished + std::any visitOC_IdInColl(CypherParser::OC_IdInCollContext *ctx) override { + auto *node = new ASTInternalNode("LIST_ITERATE"); + node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + return static_cast(node); + } + + //finished + std::any visitOC_FunctionInvocation(CypherParser::OC_FunctionInvocationContext *ctx) override { + auto *node = new ASTInternalNode("FUNCTION_BODY"); + node->addElements(any_cast(visitOC_FunctionName(ctx->oC_FunctionName()))); + + auto *aug = new ASTInternalNode("ARGUMENTS"); + if(ctx->DISTINCT()) + { + auto *distinct = new ASTInternalNode("DISTINCT"); + for(CypherParser::OC_ExpressionContext* elements : ctx->oC_Expression()) + { + distinct->addElements(any_cast(visitOC_Expression(elements))); + } + aug->addElements(distinct); + node->addElements(aug); + return static_cast(node); + } + + for(CypherParser::OC_ExpressionContext* elements : ctx->oC_Expression()) + { + aug->addElements(any_cast(visitOC_Expression(elements))); + } + if(!aug->elements.empty()) + { + node->addElements(aug); + } + return static_cast(node); + } + + //finished + std::any visitOC_FunctionName(CypherParser::OC_FunctionNameContext *ctx) override { + auto *node = new ASTInternalNode("FUNCTION"); + node->addElements(any_cast(visitOC_Namespace(ctx->oC_Namespace()))); + auto *name = new ASTLeafValue("FUNCTION_NAME", any_cast(visitOC_SymbolicName(ctx->oC_SymbolicName()))); + node->addElements(name); + return static_cast(node); + } + + //finished + std::any visitOC_ExistentialSubquery(CypherParser::OC_ExistentialSubqueryContext *ctx) override { + auto *node = new ASTInternalNode("EXISTS"); + if(ctx->oC_RegularQuery()) + { + node->addElements(any_cast(visitOC_RegularQuery(ctx->oC_RegularQuery()))); + return static_cast(node); + }else + { + node->addElements(any_cast(visitOC_Pattern(ctx->oC_Pattern()))); + if(ctx->oC_Where()) + { + node->addElements(any_cast(visitOC_Where(ctx->oC_Where()))); + } + return static_cast(node); + } + } + + //finished + std::any visitOC_ExplicitProcedureInvocation(CypherParser::OC_ExplicitProcedureInvocationContext *ctx) override { + auto *node = new ASTInternalNode("EXPLICIT_PROCEDURE"); + node->addElements(any_cast(visitOC_ProcedureName(ctx->oC_ProcedureName()))); + if(ctx->oC_Expression().size()>1) + { + auto *arg = new ASTInternalNode("ARGUMENTS"); + for(CypherParser::OC_ExpressionContext* elements : ctx->oC_Expression()) + { + arg->addElements(any_cast(visitOC_Expression(elements))); + } + node->addElements(arg); + return static_cast(node); + } + return static_cast(node); + } + + //finished + std::any visitOC_ImplicitProcedureInvocation(CypherParser::OC_ImplicitProcedureInvocationContext *ctx) override { + auto *node = new ASTInternalNode("IMPLICIT_PROCEDURE"); + node->addElements(any_cast(visitOC_ProcedureName(ctx->oC_ProcedureName()))); + return static_cast(node); + } + + //finished + std::any visitOC_ProcedureResultField(CypherParser::OC_ProcedureResultFieldContext *ctx) override { + auto *node = new ASTLeafValue("PROCEDURE_RESULT", any_cast(visitOC_SymbolicName(ctx->oC_SymbolicName()))); + return static_cast(node); + } + + //finished + std::any visitOC_ProcedureName(CypherParser::OC_ProcedureNameContext *ctx) override { + auto *node = new ASTInternalNode("PROCEDURE"); + node->addElements(any_cast(visitOC_Namespace(ctx->oC_Namespace()))); + auto *name = new ASTLeafValue("PROCEDURE_NAME", any_cast(visitOC_SymbolicName(ctx->oC_SymbolicName()))); + node->addElements(name); + return static_cast(node); + } + + + //finished + std::any visitOC_Namespace(CypherParser::OC_NamespaceContext *ctx) override { + auto *node = new ASTInternalNode("NAMESPACE"); + for(CypherParser::OC_SymbolicNameContext* element : ctx->oC_SymbolicName()) + { + auto *name = new ASTLeafNoValue(any_cast(visitOC_SymbolicName(element))); + node->addElements(name); + } + return static_cast(node); + } + + //finished + std::any visitOC_Variable(CypherParser::OC_VariableContext *ctx) override { + auto *node = new ASTLeafValue("VARIABLE", any_cast(visitOC_SymbolicName(ctx->oC_SymbolicName()))); + return static_cast(node); + } + + //finished + std::any visitOC_Literal(CypherParser::OC_LiteralContext *ctx) override { + if(ctx->oC_BooleanLiteral()) + { + return visitOC_BooleanLiteral(ctx->oC_BooleanLiteral()); + }else if(ctx->oC_ListLiteral()) + { + return visitOC_ListLiteral(ctx->oC_ListLiteral()); + }else if(ctx->oC_MapLiteral()) + { + return visitOC_MapLiteral(ctx->oC_MapLiteral()); + }else if(ctx->oC_NumberLiteral()) + { + return visitOC_NumberLiteral(ctx->oC_NumberLiteral()); + }else if(ctx->NULL_()) + { + auto *node = new ASTLeafNoValue("NULL"); + return static_cast(node); + }else + { + auto *node = new ASTLeafValue("STRING", ctx->getText()); + return static_cast(node); + } + } + + //finished + std::any visitOC_BooleanLiteral(CypherParser::OC_BooleanLiteralContext *ctx) override { + if(ctx->TRUE()) + { + auto *node = new ASTLeafValue("BOOLEAN", "TRUE"); + return static_cast(node); + } else + { + auto *node = new ASTLeafValue("BOOLEAN", "FALSE"); + return static_cast(node); + } + } + + //finished + std::any visitOC_NumberLiteral(CypherParser::OC_NumberLiteralContext *ctx) override { + if(ctx->oC_DoubleLiteral()) + { + return visitOC_DoubleLiteral(ctx->oC_DoubleLiteral()); + } + return visitOC_IntegerLiteral(ctx->oC_IntegerLiteral()); + } + + //finished + std::any visitOC_IntegerLiteral(CypherParser::OC_IntegerLiteralContext *ctx) override { + if(ctx->DecimalInteger()) + { + auto *node = new ASTLeafValue("DECIMAL", ctx->getText()); + return static_cast(node); + } else if(ctx->HexInteger()) + { + auto *node = new ASTLeafValue("HEX", ctx->getText()); + return static_cast(node); + }else + { + auto *node = new ASTLeafValue("OCTAL", ctx->getText()); + return static_cast(node); + } + + } + + //finished + std::any visitOC_DoubleLiteral(CypherParser::OC_DoubleLiteralContext *ctx) override { + if(ctx->ExponentDecimalReal()) + { + auto *node = new ASTLeafValue("EXP_DECIMAL", ctx->getText()); + return static_cast(node); + }else + { + auto *node = new ASTLeafValue("REGULAR_DECIMAL", ctx->getText()); + return static_cast(node); + } + } + + //finished + std::any visitOC_ListLiteral(CypherParser::OC_ListLiteralContext *ctx) override { + auto *node = new ASTInternalNode("LIST"); + for(CypherParser::OC_ExpressionContext* element: ctx->oC_Expression()) + { + node->addElements(any_cast(visitOC_Expression(element))); + } + return static_cast(node); + } + + //finished + std::any visitOC_MapLiteral(CypherParser::OC_MapLiteralContext *ctx) override { + auto *node = new ASTInternalNode("PROPERIES_MAP"); + for(int i=0; ioC_PropertyKeyName().size();i++) + { + auto *propNode = new ASTInternalNode("PROPERTY"); + propNode->addElements(any_cast(visitOC_PropertyKeyName(ctx->oC_PropertyKeyName()[i]))); + propNode->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()[i]))); + node->addElements(propNode); + } + + return static_cast(node); + } + + //finished + std::any visitOC_PropertyKeyName(CypherParser::OC_PropertyKeyNameContext *ctx) override { + return visitOC_SchemaName(ctx->oC_SchemaName()); + } + + //finished + std::any visitOC_Parameter(CypherParser::OC_ParameterContext *ctx) override { + if(ctx->oC_SymbolicName()) + { + auto *node = new ASTLeafValue("PARAMETER", any_cast(visitOC_SymbolicName(ctx->oC_SymbolicName()))); + return static_cast(node); + }else + { + auto *node = new ASTLeafValue("PARAMETER", ctx->getText()); + return static_cast(node); + } + } + + //finished + std::any visitOC_SchemaName(CypherParser::OC_SchemaNameContext *ctx) override { + if(ctx->oC_ReservedWord()) + { + return visitOC_ReservedWord(ctx->oC_ReservedWord()); + } + auto *node = new ASTLeafValue("SYMBOLIC_WORD",any_cast(visitOC_SymbolicName(ctx->oC_SymbolicName()))); + return static_cast(node); + } + + //finished + std::any visitOC_ReservedWord(CypherParser::OC_ReservedWordContext *ctx) override { + auto *node = new ASTLeafValue("RESERVED_WORD", ctx->getText()); + return static_cast(node); + } + + //finished + std::any visitOC_SymbolicName(CypherParser::OC_SymbolicNameContext *ctx) override { + return ctx->getText(); + } + + //finished + std::any visitOC_LeftArrowHead(CypherParser::OC_LeftArrowHeadContext *ctx) override { + return static_cast(new ASTLeafNoValue("LEFT_ARRROW")); + } + + //finished + std::any visitOC_RightArrowHead(CypherParser::OC_RightArrowHeadContext *ctx) override { + return static_cast(new ASTLeafNoValue("RIGHT_ARROW"));; + } + + //finished + std::any visitOC_Dash(CypherParser::OC_DashContext *ctx) override { + return visitChildren(ctx); + } +}; + + +#endif //AST_BUILDER_H diff --git a/src/query/processor/cypher/astbuilder/ASTInternalNode.cpp b/src/query/processor/cypher/astbuilder/ASTInternalNode.cpp new file mode 100644 index 00000000..4c01043b --- /dev/null +++ b/src/query/processor/cypher/astbuilder/ASTInternalNode.cpp @@ -0,0 +1,5 @@ +// +// Created by thamindu on 7/25/24. +// + +#include "ASTInternalNode.h" diff --git a/src/query/processor/cypher/astbuilder/ASTInternalNode.h b/src/query/processor/cypher/astbuilder/ASTInternalNode.h new file mode 100644 index 00000000..38c80fcb --- /dev/null +++ b/src/query/processor/cypher/astbuilder/ASTInternalNode.h @@ -0,0 +1,29 @@ +// +// Created by thamindu on 7/25/24. +// +#include "ASTStructure.h" + +#ifndef ASTINTERNALNODE_H +#define ASTINTERNALNODE_H + +using namespace std; + +class ASTInternalNode : public ASTNode{ + + public: + + ASTInternalNode(string nodeType) + { + this->nodeType = nodeType; + } + + void addElements(ASTNode* element) { + elements.push_back(element); + } + + +}; + + + +#endif //ASTINTERNALNODE_H diff --git a/src/query/processor/cypher/astbuilder/ASTLeafNoValue.cpp b/src/query/processor/cypher/astbuilder/ASTLeafNoValue.cpp new file mode 100644 index 00000000..a3cb7465 --- /dev/null +++ b/src/query/processor/cypher/astbuilder/ASTLeafNoValue.cpp @@ -0,0 +1,5 @@ +// +// Created by thamindu on 7/25/24. +// + +#include "ASTLeafNoValue.h" diff --git a/src/query/processor/cypher/astbuilder/ASTLeafNoValue.h b/src/query/processor/cypher/astbuilder/ASTLeafNoValue.h new file mode 100644 index 00000000..c1bd4b2b --- /dev/null +++ b/src/query/processor/cypher/astbuilder/ASTLeafNoValue.h @@ -0,0 +1,19 @@ +// +// Created by thamindu on 7/25/24. +// +#include "ASTStructure.h" +#ifndef ASTLEAFNOVALUE_H +#define ASTLEAFNOVALUE_H + + + +class ASTLeafNoValue : public ASTNode { +public: + ASTLeafNoValue(const std::string& name) + { + this->nodeType = name; + }; + +}; + +#endif //ASTLEAFNOVALUE_H diff --git a/src/query/processor/cypher/astbuilder/ASTLeafValue.cpp b/src/query/processor/cypher/astbuilder/ASTLeafValue.cpp new file mode 100644 index 00000000..cd21c3ef --- /dev/null +++ b/src/query/processor/cypher/astbuilder/ASTLeafValue.cpp @@ -0,0 +1,5 @@ +// +// Created by thamindu on 7/25/24. +// + +#include "ASTLeafValue.h" diff --git a/src/query/processor/cypher/astbuilder/ASTLeafValue.h b/src/query/processor/cypher/astbuilder/ASTLeafValue.h new file mode 100644 index 00000000..c44e85d0 --- /dev/null +++ b/src/query/processor/cypher/astbuilder/ASTLeafValue.h @@ -0,0 +1,23 @@ +// +// Created by thamindu on 7/25/24. +// +#include "ASTStructure.h" +#ifndef ASTLEAFVALUE_H +#define ASTLEAFVALUE_H + + + +class ASTLeafValue : public ASTNode { +public: + + ASTLeafValue(const std::string& name, const std::string& value) + { + this->nodeType = name; + this->value = value; + }; + +}; + + + +#endif //ASTLEAFVALUE_H diff --git a/src/query/processor/cypher/astbuilder/ASTStructure.cpp b/src/query/processor/cypher/astbuilder/ASTStructure.cpp new file mode 100644 index 00000000..eb003bad --- /dev/null +++ b/src/query/processor/cypher/astbuilder/ASTStructure.cpp @@ -0,0 +1,5 @@ +// +// Created by thamindu on 7/24/24. +// + +#include "ASTStructure.h" diff --git a/src/query/processor/cypher/astbuilder/ASTStructure.h b/src/query/processor/cypher/astbuilder/ASTStructure.h new file mode 100644 index 00000000..d346e363 --- /dev/null +++ b/src/query/processor/cypher/astbuilder/ASTStructure.h @@ -0,0 +1,42 @@ +// +// Created by thamindu on 7/24/24. +// +#include +#include +#include +#include +#ifndef AST_STRUCTURE_H +#define AST_STRUCTURE_H + +using namespace std; + +class ASTNode { + public: + string nodeType; + vector elements; + string value; + virtual ~ASTNode() = default; + + string print(int depth = 0, string prefix = "", bool isLast = true) const { + stringstream ss; + + ss << prefix; + ss << (isLast ? "└───" : "├──"); + ss << nodeType << ": " << value << endl; + + string result = ss.str(); + prefix += isLast ? " " : "│ "; + + for (size_t i = 0; i < elements.size(); ++i) { + result += elements[i]->print(depth + 1, prefix, i == elements.size() - 1); + } + + return result; + } + +}; + + + + +#endif //AST_STRUCTURE_H From 71c83491f8895f08c6a86fc9bcab195b3384e40d Mon Sep 17 00:00:00 2001 From: thamindu Date: Sat, 17 Aug 2024 10:59:50 +0530 Subject: [PATCH 2/5] add feature cypher ast --- CMakeLists.txt | 4 +- src/frontend/JasmineGraphFrontEnd.cpp | 4 +- .../cypher/astbuilder/ASTBuilder.cpp | 1671 +++++++++++++++- .../processor/cypher/astbuilder/ASTBuilder.h | 1674 ++--------------- .../cypher/astbuilder/ASTInternalNode.cpp | 9 +- .../cypher/astbuilder/ASTInternalNode.h | 14 +- .../cypher/astbuilder/ASTLeafNoValue.cpp | 4 - .../cypher/astbuilder/ASTLeafNoValue.h | 7 +- .../cypher/astbuilder/ASTLeafValue.cpp | 4 - .../cypher/astbuilder/ASTLeafValue.h | 9 +- .../processor/cypher/astbuilder/ASTNode.cpp | 25 + .../processor/cypher/astbuilder/ASTNode.h | 24 + .../cypher/astbuilder/ASTStructure.cpp | 5 - .../cypher/astbuilder/ASTStructure.h | 42 - 14 files changed, 1937 insertions(+), 1559 deletions(-) create mode 100644 src/query/processor/cypher/astbuilder/ASTNode.cpp create mode 100644 src/query/processor/cypher/astbuilder/ASTNode.h delete mode 100644 src/query/processor/cypher/astbuilder/ASTStructure.cpp delete mode 100644 src/query/processor/cypher/astbuilder/ASTStructure.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 0455602f..4d6f15b7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,8 +42,8 @@ set(HEADERS globals.h src/query/processor/cypher/astbuilder/ASTBuilder.h src/query/processor/cypher/astbuilder/ASTInternalNode.h src/query/processor/cypher/astbuilder/ASTLeafNoValue.h + src/query/processor/cypher/astbuilder/ASTNode.h src/query/processor/cypher/astbuilder/ASTLeafValue.h - src/query/processor/cypher/astbuilder/ASTStructure.h src/scale/scaler.h src/server/JasmineGraphInstance.h src/server/JasmineGraphInstanceFileTransferService.h @@ -114,8 +114,8 @@ set(SOURCES src/backend/JasmineGraphBackend.cpp src/query/processor/cypher/astbuilder/ASTBuilder.cpp src/query/processor/cypher/astbuilder/ASTInternalNode.cpp src/query/processor/cypher/astbuilder/ASTLeafNoValue.cpp + src/query/processor/cypher/astbuilder/ASTNode.cpp src/query/processor/cypher/astbuilder/ASTLeafValue.cpp - src/query/processor/cypher/astbuilder/ASTStructure.cpp src/scale/scaler.cpp src/server/JasmineGraphInstance.cpp src/server/JasmineGraphInstanceFileTransferService.cpp diff --git a/src/frontend/JasmineGraphFrontEnd.cpp b/src/frontend/JasmineGraphFrontEnd.cpp index 14ce0b4b..e25af4de 100644 --- a/src/frontend/JasmineGraphFrontEnd.cpp +++ b/src/frontend/JasmineGraphFrontEnd.cpp @@ -49,6 +49,8 @@ limitations under the License. #include "/home/ubuntu/software/jasminegraph/code_generated/antlr/CypherLexer.h" #include "/home/ubuntu/software/jasminegraph/code_generated/antlr/CypherParser.h" #include "../query/processor/cypher/astbuilder/ASTBuilder.h" +#include "../query/processor/cypher/astbuilder/ASTNode.h" + #define MAX_PENDING_CONNECTIONS 10 #define DATA_BUFFER_SIZE (FRONTEND_DATA_LENGTH + 1) @@ -667,7 +669,7 @@ static void cypher_ast_command(int connFd, bool *loop_exit) // Create a parser from the token stream CypherParser parser(&tokens); - CypherASTBuilder ast_builder; + ASTBuilder ast_builder; auto* ast = any_cast(ast_builder.visitOC_Cypher(parser.oC_Cypher())); string result = ast->print(1); int result_wrn = write(connFd, result.c_str(), result.length()); diff --git a/src/query/processor/cypher/astbuilder/ASTBuilder.cpp b/src/query/processor/cypher/astbuilder/ASTBuilder.cpp index 9d861b00..f7af1548 100644 --- a/src/query/processor/cypher/astbuilder/ASTBuilder.cpp +++ b/src/query/processor/cypher/astbuilder/ASTBuilder.cpp @@ -1,5 +1,1668 @@ -// -// Created by thamindu on 7/24/24. -// - #include "ASTBuilder.h" +#include +#include +#include "ASTInternalNode.h" +#include "ASTLeafNoValue.h" +#include "ASTLeafValue.h" +#include "/home/ubuntu/software/jasminegraph/code_generated/antlr/CypherBaseVisitor.h" + +any visitOC_Cypher(CypherParser::OC_CypherContext *ctx) ; + +any visitOC_Statement(CypherParser::OC_StatementContext *ctx) ; + +any visitOC_Query(CypherParser::OC_QueryContext *ctx) ; + +any visitOC_RegularQuery(CypherParser::OC_RegularQueryContext *ctx) ; + +any visitOC_Union(CypherParser::OC_UnionContext *ctx) ; + +any visitOC_SingleQuery(CypherParser::OC_SingleQueryContext *ctx) ; + +any visitOC_SinglePartQuery(CypherParser::OC_SinglePartQueryContext *ctx) ; + +any visitOC_MultiPartQuery(CypherParser::OC_MultiPartQueryContext *ctx) ; + +any visitOC_UpdatingClause(CypherParser::OC_UpdatingClauseContext *ctx) ; + +any visitOC_ReadingClause(CypherParser::OC_ReadingClauseContext *ctx) ; + +any visitOC_Match(CypherParser::OC_MatchContext *ctx) ; + +any visitOC_Unwind(CypherParser::OC_UnwindContext *ctx) ; + +any visitOC_Merge(CypherParser::OC_MergeContext *ctx) ; + +any visitOC_MergeAction(CypherParser::OC_MergeActionContext *ctx) ; + +any visitOC_Create(CypherParser::OC_CreateContext *ctx) ; + +any visitOC_Set(CypherParser::OC_SetContext *ctx) ; + +any visitOC_SetItem(CypherParser::OC_SetItemContext *ctx) ; + +any visitOC_Delete(CypherParser::OC_DeleteContext *ctx) ; + +any visitOC_Remove(CypherParser::OC_RemoveContext *ctx) ; + +any visitOC_RemoveItem(CypherParser::OC_RemoveItemContext *ctx) ; + +any visitOC_InQueryCall(CypherParser::OC_InQueryCallContext *ctx) ; + +any visitOC_StandaloneCall(CypherParser::OC_StandaloneCallContext *ctx) ; + +any visitOC_YieldItems(CypherParser::OC_YieldItemsContext *ctx) ; + +any visitOC_YieldItem(CypherParser::OC_YieldItemContext *ctx) ; + +any visitOC_With(CypherParser::OC_WithContext *ctx) ; + +any visitOC_Return(CypherParser::OC_ReturnContext *ctx) ; + +any visitOC_ProjectionBody(CypherParser::OC_ProjectionBodyContext *ctx) ; + +any visitOC_ProjectionItems(CypherParser::OC_ProjectionItemsContext *ctx) ; + +any visitOC_ProjectionItem(CypherParser::OC_ProjectionItemContext *ctx) ; + +any visitOC_Order(CypherParser::OC_OrderContext *ctx) ; + +any visitOC_Skip(CypherParser::OC_SkipContext *ctx) ; + +any visitOC_Limit(CypherParser::OC_LimitContext *ctx) ; + +any visitOC_SortItem(CypherParser::OC_SortItemContext *ctx) ; + +any visitOC_Where(CypherParser::OC_WhereContext *ctx) ; + +any visitOC_Pattern(CypherParser::OC_PatternContext *ctx) ; + +any visitOC_PatternPart(CypherParser::OC_PatternPartContext *ctx) ; + +any visitOC_AnonymousPatternPart(CypherParser::OC_AnonymousPatternPartContext *ctx) ; + +any visitOC_PatternElement(CypherParser::OC_PatternElementContext *ctx) ; + +any visitOC_RelationshipsPattern(CypherParser::OC_RelationshipsPatternContext *ctx) ; + +any visitOC_NodePattern(CypherParser::OC_NodePatternContext *ctx) ; + +any visitOC_PatternElementChain(CypherParser::OC_PatternElementChainContext *ctx) ; + +any visitOC_RelationshipPattern(CypherParser::OC_RelationshipPatternContext *ctx) ; + +any visitOC_RelationshipDetail(CypherParser::OC_RelationshipDetailContext *ctx) ; + +any visitOC_Properties(CypherParser::OC_PropertiesContext *ctx) ; + +any visitOC_RelationshipTypes(CypherParser::OC_RelationshipTypesContext *ctx) ; + + +any visitOC_NodeLabels(CypherParser::OC_NodeLabelsContext *ctx) ; + +any visitOC_NodeLabel(CypherParser::OC_NodeLabelContext *ctx) ; + +any visitOC_RangeLiteral(CypherParser::OC_RangeLiteralContext *ctx) ; + +any visitOC_LabelName(CypherParser::OC_LabelNameContext *ctx) ; + +any visitOC_RelTypeName(CypherParser::OC_RelTypeNameContext *ctx) ; + +any visitOC_PropertyExpression(CypherParser::OC_PropertyExpressionContext *ctx) ; + +any visitOC_Expression(CypherParser::OC_ExpressionContext *ctx) ; + +any visitOC_OrExpression(CypherParser::OC_OrExpressionContext *ctx) ; + +any visitOC_XorExpression(CypherParser::OC_XorExpressionContext *ctx) ; + +any visitOC_AndExpression(CypherParser::OC_AndExpressionContext *ctx) ; + +any visitOC_NotExpression(CypherParser::OC_NotExpressionContext *ctx) ; + +any visitOC_ComparisonExpression(CypherParser::OC_ComparisonExpressionContext *ctx) ; + +any visitOC_PartialComparisonExpression(CypherParser::OC_PartialComparisonExpressionContext *ctx) ; + +any visitOC_StringListNullPredicateExpression(CypherParser::OC_StringListNullPredicateExpressionContext *ctx) ; + +any visitOC_StringPredicateExpression(CypherParser::OC_StringPredicateExpressionContext *ctx) ; + +any visitOC_ListPredicateExpression(CypherParser::OC_ListPredicateExpressionContext *ctx) ; + +any visitOC_NullPredicateExpression(CypherParser::OC_NullPredicateExpressionContext *ctx) ; + +any visitOC_AddOrSubtractExpression(CypherParser::OC_AddOrSubtractExpressionContext *ctx) ; + +any visitOC_MultiplyDivideModuloExpression(CypherParser::OC_MultiplyDivideModuloExpressionContext *ctx) ; + +any visitOC_PowerOfExpression(CypherParser::OC_PowerOfExpressionContext *ctx) ; + +any visitOC_UnaryAddOrSubtractExpression(CypherParser::OC_UnaryAddOrSubtractExpressionContext *ctx) ; + +any visitOC_NonArithmeticOperatorExpression(CypherParser::OC_NonArithmeticOperatorExpressionContext *ctx) ; + +any visitOC_ListOperatorExpression(CypherParser::OC_ListOperatorExpressionContext *ctx) ; + +any visitOC_PropertyLookup(CypherParser::OC_PropertyLookupContext *ctx) ; + +any visitOC_Atom(CypherParser::OC_AtomContext *ctx) ; + +any visitOC_CaseExpression(CypherParser::OC_CaseExpressionContext *ctx) ; + +any visitOC_CaseAlternative(CypherParser::OC_CaseAlternativeContext *ctx) ; + +any visitOC_ListComprehension(CypherParser::OC_ListComprehensionContext *ctx) ; + +any visitOC_PatternComprehension(CypherParser::OC_PatternComprehensionContext *ctx) ; + +any visitOC_Quantifier(CypherParser::OC_QuantifierContext *ctx) ; + +any visitOC_FilterExpression(CypherParser::OC_FilterExpressionContext *ctx) ; + +any visitOC_PatternPredicate(CypherParser::OC_PatternPredicateContext *ctx) ; + +any visitOC_ParenthesizedExpression(CypherParser::OC_ParenthesizedExpressionContext *ctx) ; + +any visitOC_IdInColl(CypherParser::OC_IdInCollContext *ctx) ; + +any visitOC_FunctionInvocation(CypherParser::OC_FunctionInvocationContext *ctx) ; + +any visitOC_FunctionName(CypherParser::OC_FunctionNameContext *ctx) ; + +any visitOC_ExistentialSubquery(CypherParser::OC_ExistentialSubqueryContext *ctx) ; + +any visitOC_ExplicitProcedureInvocation(CypherParser::OC_ExplicitProcedureInvocationContext *ctx) ; + +any visitOC_ImplicitProcedureInvocation(CypherParser::OC_ImplicitProcedureInvocationContext *ctx) ; + +any visitOC_ProcedureResultField(CypherParser::OC_ProcedureResultFieldContext *ctx) ; + +any visitOC_ProcedureName(CypherParser::OC_ProcedureNameContext *ctx) ; + +any visitOC_Namespace(CypherParser::OC_NamespaceContext *ctx) ; + +any visitOC_Variable(CypherParser::OC_VariableContext *ctx) ; + +any visitOC_Literal(CypherParser::OC_LiteralContext *ctx) ; + +any visitOC_BooleanLiteral(CypherParser::OC_BooleanLiteralContext *ctx) ; + +any visitOC_NumberLiteral(CypherParser::OC_NumberLiteralContext *ctx) ; + +any visitOC_IntegerLiteral(CypherParser::OC_IntegerLiteralContext *ctx) ; + +any visitOC_DoubleLiteral(CypherParser::OC_DoubleLiteralContext *ctx) ; + +any visitOC_ListLiteral(CypherParser::OC_ListLiteralContext *ctx) ; + +any visitOC_MapLiteral(CypherParser::OC_MapLiteralContext *ctx) ; + +any visitOC_PropertyKeyName(CypherParser::OC_PropertyKeyNameContext *ctx) ; + +any visitOC_Parameter(CypherParser::OC_ParameterContext *ctx) ; + +any visitOC_SchemaName(CypherParser::OC_SchemaNameContext *ctx) ; + +any visitOC_ReservedWord(CypherParser::OC_ReservedWordContext *ctx) ; + +any visitOC_SymbolicName(CypherParser::OC_SymbolicNameContext *ctx) ; + +any visitOC_LeftArrowHead(CypherParser::OC_LeftArrowHeadContext *ctx) ; + +any visitOC_RightArrowHead(CypherParser::OC_RightArrowHeadContext *ctx) ; + +any visitOC_Dash(CypherParser::OC_DashContext *ctx) ; + + + +any ASTBuilder::visitOC_Cypher(CypherParser::OC_CypherContext *ctx) { + return visitOC_Statement(ctx->oC_Statement()); +} + + +any ASTBuilder::visitOC_Statement(CypherParser::OC_StatementContext *ctx) { + return visitOC_Query(ctx->oC_Query()); +} + + +any ASTBuilder::visitOC_Query(CypherParser::OC_QueryContext *ctx) { + if(ctx->oC_RegularQuery()) + { + return visitOC_RegularQuery(ctx->oC_RegularQuery()); + } + return visitOC_StandaloneCall(ctx->oC_StandaloneCall()); +} + + +any ASTBuilder::visitOC_RegularQuery(CypherParser::OC_RegularQueryContext *ctx) { + if(!ctx->oC_Union().empty()) + { + auto *node = new ASTInternalNode("UNION"); + node->addElements(any_cast(visitOC_SingleQuery(ctx->oC_SingleQuery()))); + for(CypherParser::OC_UnionContext* element : ctx->oC_Union()) + { + node->addElements(any_cast(visitOC_Union(element))); + } + return static_cast(node); + } + return visitOC_SingleQuery(ctx->oC_SingleQuery()); +} + + +any ASTBuilder::visitOC_Union(CypherParser::OC_UnionContext *ctx) { + if(ctx->ALL()) + { + auto *node = new ASTInternalNode("ALL"); + node->addElements(any_cast(visitOC_SingleQuery(ctx->oC_SingleQuery()))); + return static_cast(node); + } + return visitOC_SingleQuery(ctx->oC_SingleQuery()); +} + + +any ASTBuilder::visitOC_SingleQuery(CypherParser::OC_SingleQueryContext *ctx) { + if(ctx->oC_MultiPartQuery()) + { + return visitOC_MultiPartQuery(ctx->oC_MultiPartQuery()); + } + return visitOC_SinglePartQuery(ctx->oC_SinglePartQuery()); +} + + +any ASTBuilder::visitOC_SinglePartQuery(CypherParser::OC_SinglePartQueryContext *ctx) { + auto *queryNode = new ASTInternalNode("SINGLE_QUERY"); + for (CypherParser::OC_ReadingClauseContext* element : ctx->oC_ReadingClause()) { + queryNode->addElements(any_cast(visitOC_ReadingClause(element))); + } + + for(CypherParser::OC_UpdatingClauseContext* element : ctx->oC_UpdatingClause()){ + queryNode->addElements(any_cast(visitOC_UpdatingClause(element))); + } + + if(ctx->oC_Return()) + { + queryNode->addElements(any_cast(visitOC_Return(ctx->oC_Return()))); + } + return static_cast(queryNode); +} + + +//TODO: try to solve a efficient way + +any ASTBuilder::visitOC_MultiPartQuery(CypherParser::OC_MultiPartQueryContext *ctx) { + auto *node = new ASTInternalNode("MULTIPLE_QUERY"); + for(CypherParser::OC_WithContext* withElement : ctx->oC_With()) + { + size_t const with = withElement->getStart()->getTokenIndex(); + for(CypherParser::OC_ReadingClauseContext* element : ctx->oC_ReadingClause()) + { + if(element->getStop()->getTokenIndex() < with) + { + node->addElements(any_cast(visitOC_ReadingClause(element))); + } + } + for(CypherParser::OC_UpdatingClauseContext* element : ctx->oC_UpdatingClause()) + { + if(element->getStop()->getTokenIndex() < with) + { + node->addElements(any_cast(visitOC_UpdatingClause(element))); + } + + } + } + node->addElements(any_cast(visitOC_SinglePartQuery(ctx->oC_SinglePartQuery()))); + return static_cast(node); +} + + +any ASTBuilder::visitOC_UpdatingClause(CypherParser::OC_UpdatingClauseContext *ctx) { + + if(ctx->oC_Create()) + { + return visitOC_Create(ctx->oC_Create()); + }else if(ctx->oC_Delete()) + { + return visitOC_Delete(ctx->oC_Delete()); + }else if(ctx->oC_Merge()) + { + return visitOC_Merge(ctx->oC_Merge()); + }else if(ctx->oC_Remove()) + { + return visitOC_Remove(ctx->oC_Remove()); + } + return visitOC_Set(ctx->oC_Set()); +} + +any ASTBuilder::visitOC_ReadingClause(CypherParser::OC_ReadingClauseContext *ctx) { + if(ctx->oC_Match()) + { + return visitOC_Match(ctx->oC_Match()); + }else if(ctx->oC_Unwind()) + { + return visitOC_Unwind(ctx->oC_Unwind()); + }else + { + return visitOC_InQueryCall(ctx->oC_InQueryCall()); + } +} + + +any ASTBuilder::visitOC_Match(CypherParser::OC_MatchContext *ctx) { + auto *node = new ASTInternalNode("MATCH"); + if(ctx->OPTIONAL()) + { + node->addElements(new ASTLeafNoValue("OPTIONAL")); + } + node->addElements(any_cast(visitOC_Pattern(ctx->oC_Pattern()))); + if (ctx->oC_Where()) { + node->addElements(any_cast(visitOC_Where(ctx->oC_Where()))); + } + return static_cast(node); +} + + +any ASTBuilder::visitOC_Unwind(CypherParser::OC_UnwindContext *ctx) { + auto *node = new ASTInternalNode("UNWIND"); + auto *nodeAS = new ASTInternalNode("AS"); + nodeAS->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + nodeAS->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + node->addElements(nodeAS); + return static_cast(node); +} + + +any ASTBuilder::visitOC_Merge(CypherParser::OC_MergeContext *ctx) { + auto *node = new ASTInternalNode("MERGE"); + node->addElements(any_cast(visitOC_PatternPart(ctx->oC_PatternPart()))); + for(CypherParser::OC_MergeActionContext* element : ctx->oC_MergeAction()) + { + node->addElements(any_cast(visitOC_MergeAction(element))); + } + + return static_cast(node); +} + + +any ASTBuilder::visitOC_MergeAction(CypherParser::OC_MergeActionContext *ctx) { + if(ctx->CREATE()) + { + auto *node = new ASTInternalNode("ON_CREATE"); + node->addElements(any_cast(visitOC_Set(ctx->oC_Set()))); + return static_cast(node); + } + auto *node = new ASTInternalNode("ON_MATCH"); + node->addElements(any_cast(visitOC_Set(ctx->oC_Set()))); + return static_cast(node); +} + + +any ASTBuilder::visitOC_Create(CypherParser::OC_CreateContext *ctx) { + auto *node = new ASTInternalNode("CREATE"); + node->addElements(any_cast(visitOC_Pattern(ctx->oC_Pattern()))); + return static_cast(node); +} + + + +any ASTBuilder::visitOC_Set(CypherParser::OC_SetContext *ctx) { + if(ctx->oC_SetItem().size()>1) + { + auto *node = new ASTInternalNode("MULTIPLE_SET"); + for(CypherParser::OC_SetItemContext* element: ctx->oC_SetItem()) + { + node->addElements(any_cast(visitOC_SetItem(element))); + } + return static_cast(node); + } + return visitOC_SetItem(ctx->oC_SetItem()[0]); +} + + +any ASTBuilder::visitOC_SetItem(CypherParser::OC_SetItemContext *ctx) { + if(ctx->oC_PropertyExpression()) + { + auto *node = new ASTInternalNode("SET"); + node->addElements(any_cast(visitOC_PropertyExpression(ctx->oC_PropertyExpression()))); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + return static_cast(node); + } else + { + if(ctx->getText().find("+=") != std::string::npos) + { + auto *node = new ASTInternalNode("SET_+="); + node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + return static_cast(node); + }else if (ctx->getText().find("=") != std::string::npos) + { + auto *node = new ASTInternalNode("SET_="); + node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + return static_cast(node); + } + auto *node = new ASTInternalNode("SET"); + node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + node->addElements(any_cast(visitOC_NodeLabels(ctx->oC_NodeLabels()))); + return static_cast(node); + } +} + + +any ASTBuilder::visitOC_Delete(CypherParser::OC_DeleteContext *ctx) { + auto *deleteNode = new ASTInternalNode("DELETE"); + for(CypherParser::OC_ExpressionContext* element : ctx->oC_Expression()) + { + deleteNode->addElements(any_cast(visitOC_Expression(element))); + } + if(ctx->DETACH()) + { + auto *node = new ASTInternalNode("DETACH"); + node->addElements(deleteNode); + return static_cast(node); + } + return static_cast(deleteNode); +} + + +any ASTBuilder::visitOC_Remove(CypherParser::OC_RemoveContext *ctx) { + if(ctx->oC_RemoveItem().size()>1) + { + auto *node = new ASTInternalNode("REMOVE_LIST"); + for(CypherParser::OC_RemoveItemContext* element : ctx->oC_RemoveItem()) + { + node->addElements(any_cast(visitOC_RemoveItem(element))); + } + return static_cast(node); + } + + return visitOC_RemoveItem(ctx->oC_RemoveItem()[0]); +} + + + +any ASTBuilder::visitOC_RemoveItem(CypherParser::OC_RemoveItemContext *ctx) { + auto *node = new ASTInternalNode("REMOVE"); + if(ctx->oC_Variable()) + { + node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + node->addElements(any_cast(visitOC_NodeLabels(ctx->oC_NodeLabels()))); + return static_cast(node); + } + node->addElements(any_cast(visitOC_PropertyExpression(ctx->oC_PropertyExpression()))); + return static_cast(node); +} + + +any ASTBuilder::visitOC_InQueryCall(CypherParser::OC_InQueryCallContext *ctx) { + auto *node = new ASTInternalNode("CALL"); + node->addElements(any_cast(visitOC_ExplicitProcedureInvocation(ctx->oC_ExplicitProcedureInvocation()))); + + if(ctx->oC_YieldItems()) + { + node->addElements(any_cast(visitOC_YieldItems(ctx->oC_YieldItems()))); + } + return static_cast(node); +} + + +any ASTBuilder::visitOC_StandaloneCall(CypherParser::OC_StandaloneCallContext *ctx) { + if(ctx->oC_ExplicitProcedureInvocation()) + { + auto *node = new ASTInternalNode("CALL"); + node->addElements(any_cast(visitOC_ExplicitProcedureInvocation(ctx->oC_ExplicitProcedureInvocation()))); + if(ctx->oC_YieldItems()) + { + node->addElements(any_cast(visitOC_YieldItems(ctx->oC_YieldItems()))); + }else if(ctx->getText().find('*') != std::string::npos) + { + auto *star = new ASTLeafNoValue("*"); + node->addElements(star); + } + return static_cast(node); + } + + auto *node = new ASTInternalNode("CALL"); + node->addElements(any_cast(visitOC_ImplicitProcedureInvocation(ctx->oC_ImplicitProcedureInvocation()))); + if(ctx->oC_YieldItems()) + { + node->addElements(any_cast(visitOC_YieldItems(ctx->oC_YieldItems()))); + }else if(ctx->getText().find('*') != std::string::npos) + { + auto *star = new ASTLeafNoValue("*"); + node->addElements(star); + } + return static_cast(node); +} + + +any ASTBuilder::visitOC_YieldItems(CypherParser::OC_YieldItemsContext *ctx) { + + auto *node = new ASTInternalNode("YIELD_ITEMS"); + for(CypherParser::OC_YieldItemContext* element : ctx->oC_YieldItem()) + { + node->addElements(any_cast(visitOC_YieldItem(element))); + } + if(ctx->oC_Where()) + { + node->addElements(any_cast(visitOC_Where(ctx->oC_Where()))); + } + return static_cast(node); +} + + +any ASTBuilder::visitOC_YieldItem(CypherParser::OC_YieldItemContext *ctx) { + auto *node = new ASTInternalNode("YIELD"); + if(ctx->oC_ProcedureResultField()) + { + auto *as = new ASTInternalNode("AS"); + as->addElements(any_cast(visitOC_ProcedureResultField(ctx->oC_ProcedureResultField()))); + as->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + node->addElements(as); + } + node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + return static_cast(node); +} + + +any ASTBuilder::visitOC_With(CypherParser::OC_WithContext *ctx) { + auto *node = new ASTInternalNode("WITH"); + node->addElements(any_cast(visitOC_ProjectionBody(ctx->oC_ProjectionBody()))); + if(ctx->oC_Where()) + { + node->addElements(any_cast(visitOC_Where(ctx->oC_Where()))); + } + return static_cast(node); +} + + +any ASTBuilder::visitOC_Return(CypherParser::OC_ReturnContext *ctx) { + return visitOC_ProjectionBody(ctx->oC_ProjectionBody()); +} + + +any ASTBuilder::visitOC_ProjectionBody(CypherParser::OC_ProjectionBodyContext *ctx) { + auto *node = new ASTInternalNode("RETURN"); + if(ctx->DISTINCT()) + { + auto *distinct = new ASTInternalNode("DISTINCT"); + distinct->addElements(any_cast(visitOC_ProjectionItems(ctx->oC_ProjectionItems()))); + node->addElements(distinct); + }else + { + node->addElements(any_cast(visitOC_ProjectionItems(ctx->oC_ProjectionItems()))); + } + if(ctx->oC_Order()) + { + node->addElements(any_cast(visitOC_Order(ctx->oC_Order()))); + } + if(ctx->oC_Skip()) + { + node->addElements(any_cast(visitOC_Skip(ctx->oC_Skip()))); + } + if(ctx->oC_Limit()) + { + node->addElements(any_cast(visitOC_Limit(ctx->oC_Limit()))); + } + return static_cast(node); +} + + +any ASTBuilder::visitOC_ProjectionItems(CypherParser::OC_ProjectionItemsContext *ctx) { + auto *node = new ASTInternalNode("RETURN_BODY"); + if(ctx->children[0]->getText() == "*") + { + node->addElements(new ASTLeafNoValue("*")); + } + for(CypherParser::OC_ProjectionItemContext* element : ctx->oC_ProjectionItem()) + { + node->addElements(any_cast(visitOC_ProjectionItem(element))); + } + return static_cast(node); +} + + +any ASTBuilder::visitOC_ProjectionItem(CypherParser::OC_ProjectionItemContext *ctx) { + if(ctx->oC_Variable()) + { + auto *node = new ASTInternalNode("AS"); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + return static_cast(node); + } + return visitOC_Expression(ctx->oC_Expression()); +} + + +any ASTBuilder::visitOC_Order(CypherParser::OC_OrderContext *ctx) { + auto *node = new ASTInternalNode("ORDERED BY"); + for(CypherParser::OC_SortItemContext* element : ctx->oC_SortItem()) + { + node->addElements(any_cast(visitOC_SortItem(element))); + } + return static_cast(node); +} + + +any ASTBuilder::visitOC_Skip(CypherParser::OC_SkipContext *ctx) { + auto *node = new ASTInternalNode("SKIP"); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + return static_cast(node); +} + + +any ASTBuilder::visitOC_Limit(CypherParser::OC_LimitContext *ctx) { + auto *node = new ASTInternalNode("LIMIT"); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + return static_cast(node); +} + + + +any ASTBuilder::visitOC_SortItem(CypherParser::OC_SortItemContext *ctx) { + if(ctx->ASC() or ctx->ASCENDING()) + { + auto *node = new ASTInternalNode("ASC"); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + return static_cast(node); + }else + { + auto *node = new ASTInternalNode("DESC"); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + return static_cast(node); + } +} + + +any ASTBuilder::visitOC_Where(CypherParser::OC_WhereContext *ctx) { + auto *node = new ASTInternalNode("WHERE"); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + return static_cast(node); +} + + +any ASTBuilder::visitOC_Pattern(CypherParser::OC_PatternContext *ctx) { + auto *node = new ASTInternalNode("PATTERN"); + for(CypherParser::OC_PatternPartContext* element : ctx->oC_PatternPart()) + { + node->addElements(any_cast(visitOC_PatternPart(element))); + } + return static_cast(node); +} + + +any ASTBuilder::visitOC_PatternPart(CypherParser::OC_PatternPartContext *ctx) { + if(ctx->oC_Variable()) + { + auto *node = new ASTInternalNode("="); + + node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + node->addElements(any_cast(visitOC_AnonymousPatternPart(ctx->oC_AnonymousPatternPart()))); + + return static_cast(node); + } + return visitOC_AnonymousPatternPart(ctx->oC_AnonymousPatternPart()); +} + + +any ASTBuilder::visitOC_AnonymousPatternPart(CypherParser::OC_AnonymousPatternPartContext *ctx) { + return visitOC_PatternElement(ctx->oC_PatternElement()); +} + + +any ASTBuilder::visitOC_PatternElement(CypherParser::OC_PatternElementContext *ctx) { + if(ctx->oC_PatternElement()) + { + return visitOC_PatternElement(ctx->oC_PatternElement()); + } + + if(!ctx->oC_PatternElementChain().empty()) + { + auto *node = new ASTInternalNode("PATTERN_ELEMENTS"); + node->addElements(any_cast(visitOC_NodePattern(ctx->oC_NodePattern()))); + for(CypherParser::OC_PatternElementChainContext* element : ctx->oC_PatternElementChain()) + { + node->addElements(any_cast(visitOC_PatternElementChain(element))); + } + return static_cast(node); + } + return visitOC_NodePattern(ctx->oC_NodePattern()); +} + +//finsihed +any ASTBuilder::visitOC_RelationshipsPattern(CypherParser::OC_RelationshipsPatternContext *ctx) { + auto *node = new ASTInternalNode("PATTERN_ELEMENTS"); + node->addElements(any_cast(visitOC_NodePattern(ctx->oC_NodePattern()))); + for(CypherParser::OC_PatternElementChainContext* element : ctx->oC_PatternElementChain()) + { + node->addElements(any_cast(visitOC_PatternElementChain(element))); + } + return static_cast(node); +} + + +any ASTBuilder::visitOC_NodePattern(CypherParser::OC_NodePatternContext *ctx) { + auto *node = new ASTInternalNode("NODE_PATTERN"); + if(ctx->oC_Variable()) + { + node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + } + if(ctx->oC_NodeLabels()) + { + node->addElements(any_cast(visitOC_NodeLabels(ctx->oC_NodeLabels()))); + } + if(ctx->oC_Properties()) + { + node->addElements(any_cast(visitOC_Properties(ctx->oC_Properties()))); + } + return static_cast(node); +} + + +any ASTBuilder::visitOC_PatternElementChain(CypherParser::OC_PatternElementChainContext *ctx) { + auto *node = new ASTInternalNode("PATTERN_ELEMENT_CHAIN"); + node->addElements(any_cast(visitOC_RelationshipPattern(ctx->oC_RelationshipPattern()))); + node->addElements(any_cast(visitOC_NodePattern(ctx->oC_NodePattern()))); + return static_cast(node); +} + + +any ASTBuilder::visitOC_RelationshipPattern(CypherParser::OC_RelationshipPatternContext *ctx) { + auto *node = new ASTInternalNode("RELATIONSHIP_PATTTERN"); + if(ctx->oC_LeftArrowHead() && !ctx->oC_RightArrowHead()) + { + node->addElements(any_cast(visitOC_LeftArrowHead(ctx->oC_LeftArrowHead()))); + }else if(!ctx->oC_LeftArrowHead() && ctx->oC_RightArrowHead()) + { + node->addElements(any_cast(visitOC_RightArrowHead(ctx->oC_RightArrowHead()))); + }else + { + node->addElements(new ASTLeafNoValue("UNIDIRECTION_ARROW")); + } + if(ctx->oC_RelationshipDetail()) + { + node->addElements(any_cast(visitOC_RelationshipDetail(ctx->oC_RelationshipDetail()))); + } + return static_cast(node); +} + + +any ASTBuilder::visitOC_RelationshipDetail(CypherParser::OC_RelationshipDetailContext *ctx) { + auto *node = new ASTInternalNode("RELATIONSHIP_DETAILS"); + if(ctx->oC_Variable()) + { + node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + } + if(ctx->oC_RelationshipTypes()) + { + node->addElements(any_cast(visitOC_RelationshipTypes(ctx->oC_RelationshipTypes()))); + } + if(ctx->oC_RangeLiteral()) + { + node->addElements(any_cast(visitOC_RangeLiteral(ctx->oC_RangeLiteral()))); + } + if(ctx->oC_Properties()) + { + node->addElements(any_cast(visitOC_Properties(ctx->oC_Properties()))); + } + return static_cast(node); ; +} + + +any ASTBuilder::visitOC_Properties(CypherParser::OC_PropertiesContext *ctx) { + if(ctx->oC_Parameter()) + { + return visitOC_Parameter(ctx->oC_Parameter()); + } + return visitOC_MapLiteral(ctx->oC_MapLiteral()); +} + + +any ASTBuilder::visitOC_RelationshipTypes(CypherParser::OC_RelationshipTypesContext *ctx) { + + if(ctx->oC_RelTypeName().size()>1) + { + auto *node = new ASTInternalNode("RELATIONSHIP_TYPES"); + for(CypherParser::OC_RelTypeNameContext* element : ctx->oC_RelTypeName()) + { + node->addElements(any_cast(visitOC_RelTypeName(element))); + } + return static_cast(node); + } + return visitOC_RelTypeName(ctx->oC_RelTypeName()[0]); +} + + +any ASTBuilder::visitOC_NodeLabels(CypherParser::OC_NodeLabelsContext *ctx) { + if(ctx->oC_NodeLabel().size()>1) + { + auto *node = new ASTInternalNode("NODE_LABELS"); + for(CypherParser::OC_NodeLabelContext* element : ctx->oC_NodeLabel()) + { + node->addElements(any_cast(visitOC_NodeLabel(element))); + } + return static_cast(node); + } + return visitOC_NodeLabel(ctx->oC_NodeLabel()[0]); +} + + +any ASTBuilder::visitOC_NodeLabel(CypherParser::OC_NodeLabelContext *ctx) { + auto *node = new ASTInternalNode("NODE_LABEL"); + node->addElements(any_cast(visitOC_LabelName(ctx->oC_LabelName()))); + return static_cast(node); +} + + +any ASTBuilder::visitOC_RangeLiteral(CypherParser::OC_RangeLiteralContext *ctx) { + auto *node = new ASTInternalNode("RANGE"); + if(ctx->oC_IntegerLiteral().size()>1) + { + node->addElements(any_cast(visitOC_IntegerLiteral(ctx->oC_IntegerLiteral()[0]))); + node->addElements(any_cast(visitOC_IntegerLiteral(ctx->oC_IntegerLiteral()[1]))); + return static_cast(node); + } + node->addElements(any_cast(visitOC_IntegerLiteral(ctx->oC_IntegerLiteral()[0]))); + return static_cast(node); +} + + +any ASTBuilder::visitOC_LabelName(CypherParser::OC_LabelNameContext *ctx) { + return visitOC_SchemaName(ctx->oC_SchemaName()); +} + + +any ASTBuilder::visitOC_RelTypeName(CypherParser::OC_RelTypeNameContext *ctx) { + return visitOC_SchemaName(ctx->oC_SchemaName()); +} + + +any ASTBuilder::visitOC_PropertyExpression(CypherParser::OC_PropertyExpressionContext *ctx) { + auto *node = new ASTInternalNode("PROPERTY"); + node->addElements(any_cast(visitOC_Atom(ctx->oC_Atom()))); + for(CypherParser::OC_PropertyLookupContext* element : ctx->oC_PropertyLookup()) + { + node->addElements(any_cast(visitOC_PropertyLookup(element))); + } + return static_cast(node); +} + + +any ASTBuilder::visitOC_Expression(CypherParser::OC_ExpressionContext *ctx) { + return visitOC_OrExpression(ctx->oC_OrExpression()); +} + + +any ASTBuilder::visitOC_OrExpression(CypherParser::OC_OrExpressionContext *ctx) { + if(ctx->oC_XorExpression().size()>1) + { + auto *node = new ASTInternalNode("OR"); + for(CypherParser::OC_XorExpressionContext* element : ctx->oC_XorExpression()) + { + node->addElements(any_cast(visitOC_XorExpression(element))); + } + return static_cast(node); + } + return visitOC_XorExpression(ctx->oC_XorExpression()[0]); +} + + +any ASTBuilder::visitOC_XorExpression(CypherParser::OC_XorExpressionContext *ctx) { + if(ctx->oC_AndExpression().size()>1) + { + auto *node = new ASTInternalNode("XOR"); + for(CypherParser::OC_AndExpressionContext* element : ctx->oC_AndExpression()) + { + node->addElements(any_cast(visitOC_AndExpression(element))); + } + } + return visitOC_AndExpression(ctx->oC_AndExpression()[0]); +} + + +any ASTBuilder::visitOC_AndExpression(CypherParser::OC_AndExpressionContext *ctx) { + if(ctx->oC_NotExpression().size()>1) + { + auto *node = new ASTInternalNode("AND"); + for(CypherParser::OC_NotExpressionContext* element : ctx->oC_NotExpression()) + { + node->addElements(any_cast(visitOC_NotExpression(element))); + } + return static_cast(node); + } + return visitOC_NotExpression(ctx->oC_NotExpression()[0]); +} + + +any ASTBuilder::visitOC_NotExpression(CypherParser::OC_NotExpressionContext *ctx) { + if(!ctx->NOT().empty()) + { + if(ctx->NOT().size() % 2 != 0) + { + auto *node = new ASTInternalNode("NOT"); + node->addElements(any_cast(visitOC_ComparisonExpression(ctx->oC_ComparisonExpression()))); + return static_cast(node); + } + } + return visitOC_ComparisonExpression(ctx->oC_ComparisonExpression()); +} + + + +any ASTBuilder::visitOC_ComparisonExpression(CypherParser::OC_ComparisonExpressionContext *ctx) { + if(!ctx->oC_PartialComparisonExpression().empty()) + { + auto *node = new ASTInternalNode("COMPARISON"); + node->addElements(any_cast(visitOC_StringListNullPredicateExpression(ctx->oC_StringListNullPredicateExpression()))); + for(CypherParser::OC_PartialComparisonExpressionContext* element : ctx->oC_PartialComparisonExpression()) + { + node->addElements(any_cast(visitOC_PartialComparisonExpression(element))); + } + return static_cast(node); + } + return visitOC_StringListNullPredicateExpression(ctx->oC_StringListNullPredicateExpression()); +} + + +any ASTBuilder::visitOC_PartialComparisonExpression(CypherParser::OC_PartialComparisonExpressionContext *ctx) { + if(ctx->getText().find(">") != string::npos) + { + auto *node = new ASTInternalNode(">"); + node->addElements(any_cast(visitOC_StringListNullPredicateExpression(ctx->oC_StringListNullPredicateExpression()))); + return static_cast(node); + }else if(ctx->getText().find("<>") != string::npos) + { + auto *node = new ASTInternalNode("<>"); + node->addElements(any_cast(visitOC_StringListNullPredicateExpression(ctx->oC_StringListNullPredicateExpression()))); + return static_cast(node); + }else if(ctx->getText().find("=") != string::npos) + { + auto *node = new ASTInternalNode("=="); + node->addElements(any_cast(visitOC_StringListNullPredicateExpression(ctx->oC_StringListNullPredicateExpression()))); + return static_cast(node); + }else if(ctx->getText().find("<") != string::npos) + { + auto *node = new ASTInternalNode("<"); + node->addElements(any_cast(visitOC_StringListNullPredicateExpression(ctx->oC_StringListNullPredicateExpression()))); + return static_cast(node); + }else if(ctx->getText().find(">=") != string::npos) + { + auto *node = new ASTInternalNode(">="); + node->addElements(any_cast(visitOC_StringListNullPredicateExpression(ctx->oC_StringListNullPredicateExpression()))); + return static_cast(node); + }else + { + auto *node = new ASTInternalNode("<="); + node->addElements(any_cast(visitOC_StringListNullPredicateExpression(ctx->oC_StringListNullPredicateExpression()))); + return static_cast(node); + } +} + + +any ASTBuilder::visitOC_StringListNullPredicateExpression(CypherParser::OC_StringListNullPredicateExpressionContext *ctx) { + auto *node = new ASTInternalNode("PREDICATE_EXPRESSIONS"); + node->addElements(any_cast(visitOC_AddOrSubtractExpression(ctx->oC_AddOrSubtractExpression()))); + if(!ctx->oC_StringPredicateExpression().empty()) + { + auto *strPredicate = new ASTInternalNode("STRING_PREDICATES"); + for(CypherParser::OC_StringPredicateExpressionContext* element: ctx->oC_StringPredicateExpression()) + { + strPredicate->addElements(any_cast(visitOC_StringPredicateExpression(element))); + } + node->addElements(strPredicate); + } + if(!ctx->oC_ListPredicateExpression().empty()) + { + auto *listPredicate = new ASTInternalNode("LIST_PREDICATES"); + for(CypherParser::OC_ListPredicateExpressionContext* element: ctx->oC_ListPredicateExpression()) + { + listPredicate->addElements(any_cast(visitOC_ListPredicateExpression(element))); + } + node->addElements(listPredicate); + } + if(!ctx->oC_NullPredicateExpression().empty()) + { + auto *nullPredicate = new ASTInternalNode("NULL_PREDICATES"); + for(CypherParser::OC_NullPredicateExpressionContext* element: ctx->oC_NullPredicateExpression()) + { + nullPredicate->addElements(any_cast(visitOC_NullPredicateExpression(element))); + } + node->addElements(nullPredicate); + } + if(node->elements.size()>1) + { + return static_cast(node); + }else + { + return visitOC_AddOrSubtractExpression(ctx->oC_AddOrSubtractExpression()); + } +} + + +any ASTBuilder::visitOC_StringPredicateExpression(CypherParser::OC_StringPredicateExpressionContext *ctx) { + if(ctx->STARTS()) + { + auto *node = new ASTInternalNode("STARTS_WITH"); + node->addElements(any_cast(visitOC_AddOrSubtractExpression(ctx->oC_AddOrSubtractExpression()))); + return static_cast(node); + }else if(ctx->ENDS()) + { + auto *node = new ASTInternalNode("ENDS_WITH"); + node->addElements(any_cast(visitOC_AddOrSubtractExpression(ctx->oC_AddOrSubtractExpression()))); + return static_cast(node); + }else + { + auto *node = new ASTInternalNode("CONTAINS"); + node->addElements(any_cast(visitOC_AddOrSubtractExpression(ctx->oC_AddOrSubtractExpression()))); + return static_cast(node); + } +} + + + +any ASTBuilder::visitOC_ListPredicateExpression(CypherParser::OC_ListPredicateExpressionContext *ctx) { + auto *node = new ASTInternalNode("IN"); + node->addElements(any_cast(visitOC_AddOrSubtractExpression(ctx->oC_AddOrSubtractExpression()))); + return static_cast(node); +} + + +any ASTBuilder::visitOC_NullPredicateExpression(CypherParser::OC_NullPredicateExpressionContext *ctx) { + if(ctx->NOT()) + { + auto *node = new ASTLeafNoValue("IS_NOT_NULL"); + return static_cast(node); + } + auto *node = new ASTLeafNoValue("IS_NULL"); + return static_cast(node); +} + + +any ASTBuilder::visitOC_AddOrSubtractExpression(CypherParser::OC_AddOrSubtractExpressionContext *ctx) { + if(ctx->oC_MultiplyDivideModuloExpression().size()>1) + { + int multIndex =1; + auto *node = new ASTInternalNode("ADD_OR_SUBSTRACT"); + node->addElements(any_cast(visitOC_MultiplyDivideModuloExpression(ctx->oC_MultiplyDivideModuloExpression(0)))); + + for(int i=0; ichildren.size();i++) + { + if(ctx->children[i]->getText() == "+") + { + auto *plus = new ASTInternalNode("+"); + plus->addElements(any_cast(visitOC_MultiplyDivideModuloExpression(ctx->oC_MultiplyDivideModuloExpression(multIndex++)))); + node->addElements(plus); + }else if(ctx->children[i]->getText() == "-") + { + auto *minus = new ASTInternalNode("-"); + minus->addElements(any_cast(visitOC_MultiplyDivideModuloExpression(ctx->oC_MultiplyDivideModuloExpression(multIndex++)))); + node->addElements(minus); + } + } + return static_cast(node); + } + return visitOC_MultiplyDivideModuloExpression(ctx->oC_MultiplyDivideModuloExpression(0)); +} + + +any ASTBuilder::visitOC_MultiplyDivideModuloExpression(CypherParser::OC_MultiplyDivideModuloExpressionContext *ctx) { + if(ctx->oC_PowerOfExpression().size()>1) + { + int powIndex = 1; + auto *node = new ASTInternalNode("MULTIPLY_DIVID_MODULO"); + node->addElements(any_cast(visitOC_PowerOfExpression(ctx->oC_PowerOfExpression(0)))); + + for(int i=0; ichildren.size();i++) + { + if(ctx->children[i]->getText() == "*") + { + auto *plus = new ASTInternalNode("*"); + plus->addElements(any_cast(visitOC_PowerOfExpression(ctx->oC_PowerOfExpression(powIndex++)))); + node->addElements(plus); + }else if(ctx->children[i]->getText() == "/") + { + auto *minus = new ASTInternalNode("/"); + minus->addElements(any_cast(visitOC_PowerOfExpression(ctx->oC_PowerOfExpression(powIndex++)))); + node->addElements(minus); + } + } + return static_cast(node); + } + + return visitOC_PowerOfExpression(ctx->oC_PowerOfExpression(0)); +} + + +any ASTBuilder::visitOC_PowerOfExpression(CypherParser::OC_PowerOfExpressionContext *ctx) { + if(ctx->oC_UnaryAddOrSubtractExpression().size()>1) + { + int unaryIndex = 1; + auto *node = new ASTInternalNode("POWER_OF"); + node->addElements(any_cast(visitOC_UnaryAddOrSubtractExpression(ctx->oC_UnaryAddOrSubtractExpression(0)))); + + for(int i=0; ichildren.size();i++) + { + if(ctx->children[i]->getText() == "^") + { + auto *plus = new ASTInternalNode("^"); + plus->addElements(any_cast(visitOC_UnaryAddOrSubtractExpression(ctx->oC_UnaryAddOrSubtractExpression(unaryIndex++)))); + node->addElements(plus); + } + } + return static_cast(node); + } + return visitOC_UnaryAddOrSubtractExpression(ctx->oC_UnaryAddOrSubtractExpression(0)); +} + + + +any ASTBuilder::visitOC_UnaryAddOrSubtractExpression(CypherParser::OC_UnaryAddOrSubtractExpressionContext *ctx) { + if(ctx->children[0]->getText() == "+") + { + auto *node = new ASTInternalNode("UNARY_+"); + node->addElements(any_cast(visitOC_NonArithmeticOperatorExpression(ctx->oC_NonArithmeticOperatorExpression()))); + return static_cast(node); + }else if(ctx->children[0]->getText() == "-") + { + auto *node = new ASTInternalNode("UNARY_-"); + node->addElements(any_cast(visitOC_NonArithmeticOperatorExpression(ctx->oC_NonArithmeticOperatorExpression()))); + return static_cast(node); + }else + { + return visitOC_NonArithmeticOperatorExpression(ctx->oC_NonArithmeticOperatorExpression()); + } +} + + +any ASTBuilder::visitOC_NonArithmeticOperatorExpression(CypherParser::OC_NonArithmeticOperatorExpressionContext *ctx) { + if(!ctx->oC_ListOperatorExpression().empty() | !ctx->oC_PropertyLookup().empty()) + { + auto *node = new ASTInternalNode("NON_ARITHMETIC_OPERATOR"); + int i = 0; + int j = 0; + for(auto *child : ctx->children) + { + std::string typeName = typeid(*child).name(); + if(typeName.substr(17) == "OC_AtomContextE") + { + node->addElements(any_cast(visitOC_Atom(ctx->oC_Atom()))); + }else if(typeName.substr(17) == "OC_PropertyLookupContextE") + { + node->addElements(any_cast(visitOC_PropertyLookup(ctx->oC_PropertyLookup(i++)))); + }else if(typeName.substr(17) == "OC_ListOperatorExpressionContextE") + { + node->addElements(any_cast(visitOC_ListOperatorExpression(ctx->oC_ListOperatorExpression(j++)))); + }else + { + node->addElements(any_cast(visitOC_NodeLabels(ctx->oC_NodeLabels()))); + } + } + return static_cast(node); + } + return visitOC_Atom(ctx->oC_Atom()); +} + + +any ASTBuilder::visitOC_ListOperatorExpression(CypherParser::OC_ListOperatorExpressionContext *ctx) { + if(ctx->oC_Expression().size() == 2) + { + auto *node = new ASTInternalNode("LIST_INDEX_RANGE"); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression(0)))); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression(1)))); + return static_cast(node); + } + auto *node = new ASTInternalNode("LIST_INDEX"); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression(0)))); + return static_cast(node); +} + + +any ASTBuilder::visitOC_PropertyLookup(CypherParser::OC_PropertyLookupContext *ctx) { + return visitOC_PropertyKeyName(ctx->oC_PropertyKeyName()); +} + + +any ASTBuilder::visitOC_Atom(CypherParser::OC_AtomContext *ctx) { + if(ctx->oC_Literal()) + { + return visitOC_Literal(ctx->oC_Literal()); + }else if(ctx->oC_Parameter()) + { + return visitOC_Parameter(ctx->oC_Parameter()); + }else if(ctx->oC_Quantifier()) + { + return visitOC_Quantifier(ctx->oC_Quantifier()); + }else if(ctx->oC_Variable()) + { + return visitOC_Variable(ctx->oC_Variable()); + }else if(ctx->oC_CaseExpression()) + { + return visitOC_CaseExpression(ctx->oC_CaseExpression()); + }else if(ctx->oC_ExistentialSubquery()) + { + return visitOC_ExistentialSubquery(ctx->oC_ExistentialSubquery()); + }else if(ctx->oC_FunctionInvocation()) + { + return visitOC_FunctionInvocation(ctx->oC_FunctionInvocation()); + }else if(ctx->oC_ListComprehension()) + { + return visitOC_ListComprehension(ctx->oC_ListComprehension()); + }else if(ctx->oC_ParenthesizedExpression()) + { + return visitOC_ParenthesizedExpression(ctx->oC_ParenthesizedExpression()); + }else if(ctx->oC_PatternComprehension()) + { + return visitOC_PatternComprehension(ctx->oC_PatternComprehension()); + }else if(ctx->oC_PatternPredicate()) + { + return visitOC_PatternPredicate(ctx->oC_PatternPredicate()); + }else + { + auto *node = new ASTLeafValue("COUNT", "*"); + return static_cast(node); + } +} + + +any ASTBuilder::visitOC_CaseExpression(CypherParser::OC_CaseExpressionContext *ctx) { + auto *caseNode = new ASTInternalNode("CASE_PATTERN"); + int caseAlt = 0; + for(int i = 0; ichildren.size(); i++) + { + string text = ctx->children[i]->getText(); + std::transform(text.begin(), text.end(), text.begin(), ::toupper); + string type; + if(i+2 < ctx->children.size()) + { + type = typeid(*ctx->children[i+2]).name(); + } + if(text == "CASE" && type.substr(17) == "OC_ExpressionContextE") + { + auto *node = new ASTInternalNode("CASE_EXPRESSION"); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression(0)))); + caseNode->addElements(node); + }else if(text == "ELSE" && ctx->oC_Expression().size()>1) + { + auto *node = new ASTInternalNode("ELSE_EXPRESSION"); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression(1)))); + caseNode->addElements(node); + }else if(text == "ELSE") + { + auto *node = new ASTInternalNode("ELSE_EXPRESSION"); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression(0)))); + caseNode->addElements(node); + }else if(text.find("WHEN") != string::npos) + { + caseNode->addElements(any_cast(visitOC_CaseAlternative(ctx->oC_CaseAlternative(caseAlt++)))); + } + } + return static_cast(caseNode); +} + + +any ASTBuilder::visitOC_CaseAlternative(CypherParser::OC_CaseAlternativeContext *ctx) { + auto *node = new ASTInternalNode("CASE"); + + auto *when = new ASTInternalNode("WHEN"); + when->addElements(any_cast(visitOC_Expression(ctx->oC_Expression(0)))); + + auto *then = new ASTInternalNode("THEN"); + then->addElements(any_cast(visitOC_Expression(ctx->oC_Expression(1)))); + + node->addElements(when); + node->addElements(then); + return static_cast(node); +} + + +any ASTBuilder::visitOC_ListComprehension(CypherParser::OC_ListComprehensionContext *ctx) { + auto *node = new ASTInternalNode("LIST_COMPREHENSION"); + node->addElements(any_cast(visitOC_FilterExpression(ctx->oC_FilterExpression()))); + if(ctx->getText().find('|') != string::npos) + { + auto *result = new ASTInternalNode("FILTER_RESULT"); + result->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + node->addElements(result); + } + return static_cast(node); +} + + +any ASTBuilder::visitOC_PatternComprehension(CypherParser::OC_PatternComprehensionContext *ctx) { + auto *node = new ASTInternalNode("PATTERN_COMPREHENSION"); + if(ctx->oC_Variable()) + { + auto *eual = new ASTInternalNode("="); + eual->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + eual->addElements(any_cast(visitOC_RelationshipsPattern(ctx->oC_RelationshipsPattern()))); + node->addElements(eual); + }else + { + node->addElements(any_cast(visitOC_RelationshipsPattern(ctx->oC_RelationshipsPattern()))); + } + if(ctx->oC_Where()) + { + node->addElements(any_cast(visitOC_Where(ctx->oC_Where()))); + } + auto *result = new ASTInternalNode("FILTER_RESULT"); + result->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + node->addElements(result); + return static_cast(node); +} + + +any ASTBuilder::visitOC_Quantifier(CypherParser::OC_QuantifierContext *ctx) { + if(ctx->ALL()) + { + auto *node = new ASTInternalNode("ALL"); + node->addElements(any_cast(visitOC_FilterExpression(ctx->oC_FilterExpression()))); + return static_cast(node); + }else if(ctx->ANY()) + { + auto *node = new ASTInternalNode("ANY"); + node->addElements(any_cast(visitOC_FilterExpression(ctx->oC_FilterExpression()))); + return static_cast(node); + }else if(ctx->NONE()) + { + auto *node = new ASTInternalNode("NONE"); + node->addElements(any_cast(visitOC_FilterExpression(ctx->oC_FilterExpression()))); + return static_cast(node); + }else + { + auto *node = new ASTInternalNode("SINGLE"); + node->addElements(any_cast(visitOC_FilterExpression(ctx->oC_FilterExpression()))); + return static_cast(node); + } +} + + +any ASTBuilder::visitOC_FilterExpression(CypherParser::OC_FilterExpressionContext *ctx) { + auto *node = new ASTInternalNode("FILTER_EXPRESSION"); + node->addElements(any_cast(visitOC_IdInColl(ctx->oC_IdInColl()))); + if(ctx->oC_Where()) + { + node->addElements(any_cast(visitOC_Where(ctx->oC_Where()))); + } + return static_cast(node); +} + + +any ASTBuilder::visitOC_PatternPredicate(CypherParser::OC_PatternPredicateContext *ctx) { + return visitOC_RelationshipsPattern(ctx->oC_RelationshipsPattern()); +} + + +any ASTBuilder::visitOC_ParenthesizedExpression(CypherParser::OC_ParenthesizedExpressionContext *ctx) { + return visitOC_Expression(ctx->oC_Expression()); +} + + +any ASTBuilder::visitOC_IdInColl(CypherParser::OC_IdInCollContext *ctx) { + auto *node = new ASTInternalNode("LIST_ITERATE"); + node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); + node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); + return static_cast(node); +} + + +any ASTBuilder::visitOC_FunctionInvocation(CypherParser::OC_FunctionInvocationContext *ctx) { + auto *node = new ASTInternalNode("FUNCTION_BODY"); + node->addElements(any_cast(visitOC_FunctionName(ctx->oC_FunctionName()))); + + auto *aug = new ASTInternalNode("ARGUMENTS"); + if(ctx->DISTINCT()) + { + auto *distinct = new ASTInternalNode("DISTINCT"); + for(CypherParser::OC_ExpressionContext* elements : ctx->oC_Expression()) + { + distinct->addElements(any_cast(visitOC_Expression(elements))); + } + aug->addElements(distinct); + node->addElements(aug); + return static_cast(node); + } + + for(CypherParser::OC_ExpressionContext* elements : ctx->oC_Expression()) + { + aug->addElements(any_cast(visitOC_Expression(elements))); + } + if(!aug->elements.empty()) + { + node->addElements(aug); + } + return static_cast(node); +} + + +any ASTBuilder::visitOC_FunctionName(CypherParser::OC_FunctionNameContext *ctx) { + auto *node = new ASTInternalNode("FUNCTION"); + node->addElements(any_cast(visitOC_Namespace(ctx->oC_Namespace()))); + auto *name = new ASTLeafValue("FUNCTION_NAME", any_cast(visitOC_SymbolicName(ctx->oC_SymbolicName()))); + node->addElements(name); + return static_cast(node); +} + + +any ASTBuilder::visitOC_ExistentialSubquery(CypherParser::OC_ExistentialSubqueryContext *ctx) { + auto *node = new ASTInternalNode("EXISTS"); + if(ctx->oC_RegularQuery()) + { + node->addElements(any_cast(visitOC_RegularQuery(ctx->oC_RegularQuery()))); + return static_cast(node); + }else + { + node->addElements(any_cast(visitOC_Pattern(ctx->oC_Pattern()))); + if(ctx->oC_Where()) + { + node->addElements(any_cast(visitOC_Where(ctx->oC_Where()))); + } + return static_cast(node); + } +} + + +any ASTBuilder::visitOC_ExplicitProcedureInvocation(CypherParser::OC_ExplicitProcedureInvocationContext *ctx) { + auto *node = new ASTInternalNode("EXPLICIT_PROCEDURE"); + node->addElements(any_cast(visitOC_ProcedureName(ctx->oC_ProcedureName()))); + if(ctx->oC_Expression().size()>1) + { + auto *arg = new ASTInternalNode("ARGUMENTS"); + for(CypherParser::OC_ExpressionContext* elements : ctx->oC_Expression()) + { + arg->addElements(any_cast(visitOC_Expression(elements))); + } + node->addElements(arg); + return static_cast(node); + } + return static_cast(node); +} + + +any ASTBuilder::visitOC_ImplicitProcedureInvocation(CypherParser::OC_ImplicitProcedureInvocationContext *ctx) { + auto *node = new ASTInternalNode("IMPLICIT_PROCEDURE"); + node->addElements(any_cast(visitOC_ProcedureName(ctx->oC_ProcedureName()))); + return static_cast(node); +} + + +any ASTBuilder::visitOC_ProcedureResultField(CypherParser::OC_ProcedureResultFieldContext *ctx) { + auto *node = new ASTLeafValue("PROCEDURE_RESULT", any_cast(visitOC_SymbolicName(ctx->oC_SymbolicName()))); + return static_cast(node); +} + + +any ASTBuilder::visitOC_ProcedureName(CypherParser::OC_ProcedureNameContext *ctx) { + auto *node = new ASTInternalNode("PROCEDURE"); + node->addElements(any_cast(visitOC_Namespace(ctx->oC_Namespace()))); + auto *name = new ASTLeafValue("PROCEDURE_NAME", any_cast(visitOC_SymbolicName(ctx->oC_SymbolicName()))); + node->addElements(name); + return static_cast(node); +} + + + +any ASTBuilder::visitOC_Namespace(CypherParser::OC_NamespaceContext *ctx) { + auto *node = new ASTInternalNode("NAMESPACE"); + for(CypherParser::OC_SymbolicNameContext* element : ctx->oC_SymbolicName()) + { + auto *name = new ASTLeafNoValue(any_cast(visitOC_SymbolicName(element))); + node->addElements(name); + } + return static_cast(node); +} + + +any ASTBuilder::visitOC_Variable(CypherParser::OC_VariableContext *ctx) { + auto *node = new ASTLeafValue("VARIABLE", any_cast(visitOC_SymbolicName(ctx->oC_SymbolicName()))); + return static_cast(node); +} + + +any ASTBuilder::visitOC_Literal(CypherParser::OC_LiteralContext *ctx) { + if(ctx->oC_BooleanLiteral()) + { + return visitOC_BooleanLiteral(ctx->oC_BooleanLiteral()); + }else if(ctx->oC_ListLiteral()) + { + return visitOC_ListLiteral(ctx->oC_ListLiteral()); + }else if(ctx->oC_MapLiteral()) + { + return visitOC_MapLiteral(ctx->oC_MapLiteral()); + }else if(ctx->oC_NumberLiteral()) + { + return visitOC_NumberLiteral(ctx->oC_NumberLiteral()); + }else if(ctx->NULL_()) + { + auto *node = new ASTLeafNoValue("NULL"); + return static_cast(node); + }else + { + auto *node = new ASTLeafValue("STRING", ctx->getText()); + return static_cast(node); + } +} + + +any ASTBuilder::visitOC_BooleanLiteral(CypherParser::OC_BooleanLiteralContext *ctx) { + if(ctx->TRUE()) + { + auto *node = new ASTLeafValue("BOOLEAN", "TRUE"); + return static_cast(node); + } else + { + auto *node = new ASTLeafValue("BOOLEAN", "FALSE"); + return static_cast(node); + } +} + + +any ASTBuilder::visitOC_NumberLiteral(CypherParser::OC_NumberLiteralContext *ctx) { + if(ctx->oC_DoubleLiteral()) + { + return visitOC_DoubleLiteral(ctx->oC_DoubleLiteral()); + } + return visitOC_IntegerLiteral(ctx->oC_IntegerLiteral()); +} + + +any ASTBuilder::visitOC_IntegerLiteral(CypherParser::OC_IntegerLiteralContext *ctx) { + if(ctx->DecimalInteger()) + { + auto *node = new ASTLeafValue("DECIMAL", ctx->getText()); + return static_cast(node); + } else if(ctx->HexInteger()) + { + auto *node = new ASTLeafValue("HEX", ctx->getText()); + return static_cast(node); + }else + { + auto *node = new ASTLeafValue("OCTAL", ctx->getText()); + return static_cast(node); + } + +} + + +any ASTBuilder::visitOC_DoubleLiteral(CypherParser::OC_DoubleLiteralContext *ctx) { + if(ctx->ExponentDecimalReal()) + { + auto *node = new ASTLeafValue("EXP_DECIMAL", ctx->getText()); + return static_cast(node); + }else + { + auto *node = new ASTLeafValue("REGULAR_DECIMAL", ctx->getText()); + return static_cast(node); + } +} + + +any ASTBuilder::visitOC_ListLiteral(CypherParser::OC_ListLiteralContext *ctx) { + auto *node = new ASTInternalNode("LIST"); + for(CypherParser::OC_ExpressionContext* element: ctx->oC_Expression()) + { + node->addElements(any_cast(visitOC_Expression(element))); + } + return static_cast(node); +} + + +any ASTBuilder::visitOC_MapLiteral(CypherParser::OC_MapLiteralContext *ctx) { + auto *node = new ASTInternalNode("PROPERIES_MAP"); + for(int i=0; ioC_PropertyKeyName().size();i++) + { + auto *propNode = new ASTInternalNode("PROPERTY"); + propNode->addElements(any_cast(visitOC_PropertyKeyName(ctx->oC_PropertyKeyName()[i]))); + propNode->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()[i]))); + node->addElements(propNode); + } + + return static_cast(node); +} + + +any ASTBuilder::visitOC_PropertyKeyName(CypherParser::OC_PropertyKeyNameContext *ctx) { + return visitOC_SchemaName(ctx->oC_SchemaName()); +} + + +any ASTBuilder::visitOC_Parameter(CypherParser::OC_ParameterContext *ctx) { + if(ctx->oC_SymbolicName()) + { + auto *node = new ASTLeafValue("PARAMETER", any_cast(visitOC_SymbolicName(ctx->oC_SymbolicName()))); + return static_cast(node); + }else + { + auto *node = new ASTLeafValue("PARAMETER", ctx->getText()); + return static_cast(node); + } +} + + +any ASTBuilder::visitOC_SchemaName(CypherParser::OC_SchemaNameContext *ctx) { + if(ctx->oC_ReservedWord()) + { + return visitOC_ReservedWord(ctx->oC_ReservedWord()); + } + auto *node = new ASTLeafValue("SYMBOLIC_WORD",any_cast(visitOC_SymbolicName(ctx->oC_SymbolicName()))); + return static_cast(node); +} + + +any ASTBuilder::visitOC_ReservedWord(CypherParser::OC_ReservedWordContext *ctx) { + auto *node = new ASTLeafValue("RESERVED_WORD", ctx->getText()); + return static_cast(node); +} + + +any ASTBuilder::visitOC_SymbolicName(CypherParser::OC_SymbolicNameContext *ctx) { + return ctx->getText(); +} + + +any ASTBuilder::visitOC_LeftArrowHead(CypherParser::OC_LeftArrowHeadContext *ctx) { + return static_cast(new ASTLeafNoValue("LEFT_ARRROW")); +} + + +any ASTBuilder::visitOC_RightArrowHead(CypherParser::OC_RightArrowHeadContext *ctx) { + return static_cast(new ASTLeafNoValue("RIGHT_ARROW"));; +} diff --git a/src/query/processor/cypher/astbuilder/ASTBuilder.h b/src/query/processor/cypher/astbuilder/ASTBuilder.h index 5e7931bf..794deaa0 100644 --- a/src/query/processor/cypher/astbuilder/ASTBuilder.h +++ b/src/query/processor/cypher/astbuilder/ASTBuilder.h @@ -1,1479 +1,219 @@ -// -// Created by thamindu on 7/24/24. -// -#include #include -#include -#include "ASTInternalNode.h" -#include "ASTLeafNoValue.h" -#include "ASTLeafValue.h" #include "/home/ubuntu/software/jasminegraph/code_generated/antlr/CypherBaseVisitor.h" #ifndef AST_BUILDER_H #define AST_BUILDER_H using namespace std; -class CypherASTBuilder : public CypherBaseVisitor { +class ASTBuilder : public CypherBaseVisitor { public: - // finished - std::any visitOC_Cypher(CypherParser::OC_CypherContext *ctx) override { - return visitOC_Statement(ctx->oC_Statement()); - } - - // finished - std::any visitOC_Statement(CypherParser::OC_StatementContext *ctx) override { - return visitOC_Query(ctx->oC_Query()); - } - - //finished - std::any visitOC_Query(CypherParser::OC_QueryContext *ctx) override { - if(ctx->oC_RegularQuery()) - { - return visitOC_RegularQuery(ctx->oC_RegularQuery()); - } - return visitOC_StandaloneCall(ctx->oC_StandaloneCall()); - } - - //finished - std::any visitOC_RegularQuery(CypherParser::OC_RegularQueryContext *ctx) override { - if(!ctx->oC_Union().empty()) - { - auto *node = new ASTInternalNode("UNION"); - node->addElements(any_cast(visitOC_SingleQuery(ctx->oC_SingleQuery()))); - for(CypherParser::OC_UnionContext* element : ctx->oC_Union()) - { - node->addElements(any_cast(visitOC_Union(element))); - } - return static_cast(node); - } - return visitOC_SingleQuery(ctx->oC_SingleQuery()); - } - - //finished - std::any visitOC_Union(CypherParser::OC_UnionContext *ctx) override { - if(ctx->ALL()) - { - auto *node = new ASTInternalNode("ALL"); - node->addElements(any_cast(visitOC_SingleQuery(ctx->oC_SingleQuery()))); - return static_cast(node); - } - return visitOC_SingleQuery(ctx->oC_SingleQuery()); - } - - //finished - std::any visitOC_SingleQuery(CypherParser::OC_SingleQueryContext *ctx) override { - if(ctx->oC_MultiPartQuery()) - { - return visitOC_MultiPartQuery(ctx->oC_MultiPartQuery()); - } - return visitOC_SinglePartQuery(ctx->oC_SinglePartQuery()); - } - - //finished - std::any visitOC_SinglePartQuery(CypherParser::OC_SinglePartQueryContext *ctx) override { - auto *queryNode = new ASTInternalNode("SINGLE_QUERY"); - for (CypherParser::OC_ReadingClauseContext* element : ctx->oC_ReadingClause()) { - queryNode->addElements(any_cast(visitOC_ReadingClause(element))); - } - - for(CypherParser::OC_UpdatingClauseContext* element : ctx->oC_UpdatingClause()){ - queryNode->addElements(any_cast(visitOC_UpdatingClause(element))); - } - - if(ctx->oC_Return()) - { - queryNode->addElements(any_cast(visitOC_Return(ctx->oC_Return()))); - } - return static_cast(queryNode); - } - - - //TODO: try to solve a efficient way - //finished - std::any visitOC_MultiPartQuery(CypherParser::OC_MultiPartQueryContext *ctx) override { - auto *node = new ASTInternalNode("MULTIPLE_QUERY"); - for(CypherParser::OC_WithContext* withElement : ctx->oC_With()) - { - size_t const with = withElement->getStart()->getTokenIndex(); - for(CypherParser::OC_ReadingClauseContext* element : ctx->oC_ReadingClause()) - { - if(element->getStop()->getTokenIndex() < with) - { - node->addElements(any_cast(visitOC_ReadingClause(element))); - } - } - for(CypherParser::OC_UpdatingClauseContext* element : ctx->oC_UpdatingClause()) - { - if(element->getStop()->getTokenIndex() < with) - { - node->addElements(any_cast(visitOC_UpdatingClause(element))); - } - - } - } - node->addElements(any_cast(visitOC_SinglePartQuery(ctx->oC_SinglePartQuery()))); - return static_cast(node); - } - - //finished - std::any visitOC_UpdatingClause(CypherParser::OC_UpdatingClauseContext *ctx) override { - - if(ctx->oC_Create()) - { - return visitOC_Create(ctx->oC_Create()); - }else if(ctx->oC_Delete()) - { - return visitOC_Delete(ctx->oC_Delete()); - }else if(ctx->oC_Merge()) - { - return visitOC_Merge(ctx->oC_Merge()); - }else if(ctx->oC_Remove()) - { - return visitOC_Remove(ctx->oC_Remove()); - } - return visitOC_Set(ctx->oC_Set()); - } - //finished - std::any visitOC_ReadingClause(CypherParser::OC_ReadingClauseContext *ctx) override { - if(ctx->oC_Match()) - { - return visitOC_Match(ctx->oC_Match()); - }else if(ctx->oC_Unwind()) - { - return visitOC_Unwind(ctx->oC_Unwind()); - }else - { - return visitOC_InQueryCall(ctx->oC_InQueryCall()); - } - } - - //finished - std::any visitOC_Match(CypherParser::OC_MatchContext *ctx) override { - auto *node = new ASTInternalNode("MATCH"); - if(ctx->OPTIONAL()) - { - node->addElements(new ASTLeafNoValue("OPTIONAL")); - } - node->addElements(any_cast(visitOC_Pattern(ctx->oC_Pattern()))); - if (ctx->oC_Where()) { - node->addElements(any_cast(visitOC_Where(ctx->oC_Where()))); - } - return static_cast(node); - } - - //finished - std::any visitOC_Unwind(CypherParser::OC_UnwindContext *ctx) override { - auto *node = new ASTInternalNode("UNWIND"); - auto *nodeAS = new ASTInternalNode("AS"); - nodeAS->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); - nodeAS->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); - node->addElements(nodeAS); - return static_cast(node); - } - - //finished - std::any visitOC_Merge(CypherParser::OC_MergeContext *ctx) override { - auto *node = new ASTInternalNode("MERGE"); - node->addElements(any_cast(visitOC_PatternPart(ctx->oC_PatternPart()))); - for(CypherParser::OC_MergeActionContext* element : ctx->oC_MergeAction()) - { - node->addElements(any_cast(visitOC_MergeAction(element))); - } - - return static_cast(node); - } - - //finished - std::any visitOC_MergeAction(CypherParser::OC_MergeActionContext *ctx) override { - if(ctx->CREATE()) - { - auto *node = new ASTInternalNode("ON_CREATE"); - node->addElements(any_cast(visitOC_Set(ctx->oC_Set()))); - return static_cast(node); - } - auto *node = new ASTInternalNode("ON_MATCH"); - node->addElements(any_cast(visitOC_Set(ctx->oC_Set()))); - return static_cast(node); - } - - //finished - std::any visitOC_Create(CypherParser::OC_CreateContext *ctx) override { - auto *node = new ASTInternalNode("CREATE"); - node->addElements(any_cast(visitOC_Pattern(ctx->oC_Pattern()))); - return static_cast(node); - } - - - //finished - std::any visitOC_Set(CypherParser::OC_SetContext *ctx) override { - if(ctx->oC_SetItem().size()>1) - { - auto *node = new ASTInternalNode("MULTIPLE_SET"); - for(CypherParser::OC_SetItemContext* element: ctx->oC_SetItem()) - { - node->addElements(any_cast(visitOC_SetItem(element))); - } - return static_cast(node); - } - return visitOC_SetItem(ctx->oC_SetItem()[0]); - } - - //finished - std::any visitOC_SetItem(CypherParser::OC_SetItemContext *ctx) override { - if(ctx->oC_PropertyExpression()) - { - auto *node = new ASTInternalNode("SET"); - node->addElements(any_cast(visitOC_PropertyExpression(ctx->oC_PropertyExpression()))); - node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); - return static_cast(node); - } else - { - if(ctx->getText().find("+=") != std::string::npos) - { - auto *node = new ASTInternalNode("SET_+="); - node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); - node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); - return static_cast(node); - }else if (ctx->getText().find("=") != std::string::npos) - { - auto *node = new ASTInternalNode("SET_="); - node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); - node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); - return static_cast(node); - } - auto *node = new ASTInternalNode("SET"); - node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); - node->addElements(any_cast(visitOC_NodeLabels(ctx->oC_NodeLabels()))); - return static_cast(node); - } - } - - //finished - std::any visitOC_Delete(CypherParser::OC_DeleteContext *ctx) override { - auto *deleteNode = new ASTInternalNode("DELETE"); - for(CypherParser::OC_ExpressionContext* element : ctx->oC_Expression()) - { - deleteNode->addElements(any_cast(visitOC_Expression(element))); - } - if(ctx->DETACH()) - { - auto *node = new ASTInternalNode("DETACH"); - node->addElements(deleteNode); - return static_cast(node); - } - return static_cast(deleteNode); - } - - //finished - std::any visitOC_Remove(CypherParser::OC_RemoveContext *ctx) override { - if(ctx->oC_RemoveItem().size()>1) - { - auto *node = new ASTInternalNode("REMOVE_LIST"); - for(CypherParser::OC_RemoveItemContext* element : ctx->oC_RemoveItem()) - { - node->addElements(any_cast(visitOC_RemoveItem(element))); - } - return static_cast(node); - } - - return visitOC_RemoveItem(ctx->oC_RemoveItem()[0]); - } - - - //finished - std::any visitOC_RemoveItem(CypherParser::OC_RemoveItemContext *ctx) override { - auto *node = new ASTInternalNode("REMOVE"); - if(ctx->oC_Variable()) - { - node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); - node->addElements(any_cast(visitOC_NodeLabels(ctx->oC_NodeLabels()))); - return static_cast(node); - } - node->addElements(any_cast(visitOC_PropertyExpression(ctx->oC_PropertyExpression()))); - return static_cast(node); - } - - //finished - std::any visitOC_InQueryCall(CypherParser::OC_InQueryCallContext *ctx) override { - auto *node = new ASTInternalNode("CALL"); - node->addElements(any_cast(visitOC_ExplicitProcedureInvocation(ctx->oC_ExplicitProcedureInvocation()))); - - if(ctx->oC_YieldItems()) - { - node->addElements(any_cast(visitOC_YieldItems(ctx->oC_YieldItems()))); - } - return static_cast(node); - } - - //finished - std::any visitOC_StandaloneCall(CypherParser::OC_StandaloneCallContext *ctx) override { - if(ctx->oC_ExplicitProcedureInvocation()) - { - auto *node = new ASTInternalNode("CALL"); - node->addElements(any_cast(visitOC_ExplicitProcedureInvocation(ctx->oC_ExplicitProcedureInvocation()))); - if(ctx->oC_YieldItems()) - { - node->addElements(any_cast(visitOC_YieldItems(ctx->oC_YieldItems()))); - }else if(ctx->getText().find('*') != std::string::npos) - { - auto *star = new ASTLeafNoValue("*"); - node->addElements(star); - } - return static_cast(node); - } - - auto *node = new ASTInternalNode("CALL"); - node->addElements(any_cast(visitOC_ImplicitProcedureInvocation(ctx->oC_ImplicitProcedureInvocation()))); - if(ctx->oC_YieldItems()) - { - node->addElements(any_cast(visitOC_YieldItems(ctx->oC_YieldItems()))); - }else if(ctx->getText().find('*') != std::string::npos) - { - auto *star = new ASTLeafNoValue("*"); - node->addElements(star); - } - return static_cast(node); - } - - //finished - std::any visitOC_YieldItems(CypherParser::OC_YieldItemsContext *ctx) override { - - auto *node = new ASTInternalNode("YIELD_ITEMS"); - for(CypherParser::OC_YieldItemContext* element : ctx->oC_YieldItem()) - { - node->addElements(any_cast(visitOC_YieldItem(element))); - } - if(ctx->oC_Where()) - { - node->addElements(any_cast(visitOC_Where(ctx->oC_Where()))); - } - return static_cast(node); - } - - //finished - std::any visitOC_YieldItem(CypherParser::OC_YieldItemContext *ctx) override { - auto *node = new ASTInternalNode("YIELD"); - if(ctx->oC_ProcedureResultField()) - { - auto *as = new ASTInternalNode("AS"); - as->addElements(any_cast(visitOC_ProcedureResultField(ctx->oC_ProcedureResultField()))); - as->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); - node->addElements(as); - } - node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); - return static_cast(node); - } - - //finished - std::any visitOC_With(CypherParser::OC_WithContext *ctx) override { - auto *node = new ASTInternalNode("WITH"); - node->addElements(any_cast(visitOC_ProjectionBody(ctx->oC_ProjectionBody()))); - if(ctx->oC_Where()) - { - node->addElements(any_cast(visitOC_Where(ctx->oC_Where()))); - } - return static_cast(node); - } - - //finished - std::any visitOC_Return(CypherParser::OC_ReturnContext *ctx) override { - return visitOC_ProjectionBody(ctx->oC_ProjectionBody()); - } - - //finished - std::any visitOC_ProjectionBody(CypherParser::OC_ProjectionBodyContext *ctx) override { - auto *node = new ASTInternalNode("RETURN"); - if(ctx->DISTINCT()) - { - auto *distinct = new ASTInternalNode("DISTINCT"); - distinct->addElements(any_cast(visitOC_ProjectionItems(ctx->oC_ProjectionItems()))); - node->addElements(distinct); - }else - { - node->addElements(any_cast(visitOC_ProjectionItems(ctx->oC_ProjectionItems()))); - } - if(ctx->oC_Order()) - { - node->addElements(any_cast(visitOC_Order(ctx->oC_Order()))); - } - if(ctx->oC_Skip()) - { - node->addElements(any_cast(visitOC_Skip(ctx->oC_Skip()))); - } - if(ctx->oC_Limit()) - { - node->addElements(any_cast(visitOC_Limit(ctx->oC_Limit()))); - } - return static_cast(node); - } - - //finished - std::any visitOC_ProjectionItems(CypherParser::OC_ProjectionItemsContext *ctx) override { - auto *node = new ASTInternalNode("RETURN_BODY"); - if(ctx->children[0]->getText() == "*") - { - node->addElements(new ASTLeafNoValue("*")); - } - for(CypherParser::OC_ProjectionItemContext* element : ctx->oC_ProjectionItem()) - { - node->addElements(any_cast(visitOC_ProjectionItem(element))); - } - return static_cast(node); - } - - //finished - std::any visitOC_ProjectionItem(CypherParser::OC_ProjectionItemContext *ctx) override { - if(ctx->oC_Variable()) - { - auto *node = new ASTInternalNode("AS"); - node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); - node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); - return static_cast(node); - } - return visitOC_Expression(ctx->oC_Expression()); - } - - //finished - std::any visitOC_Order(CypherParser::OC_OrderContext *ctx) override { - auto *node = new ASTInternalNode("ORDERED BY"); - for(CypherParser::OC_SortItemContext* element : ctx->oC_SortItem()) - { - node->addElements(any_cast(visitOC_SortItem(element))); - } - return static_cast(node); - } - - //finished - std::any visitOC_Skip(CypherParser::OC_SkipContext *ctx) override { - auto *node = new ASTInternalNode("SKIP"); - node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); - return static_cast(node); - } - - //finished - std::any visitOC_Limit(CypherParser::OC_LimitContext *ctx) override { - auto *node = new ASTInternalNode("LIMIT"); - node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); - return static_cast(node); - } - - - //finished - std::any visitOC_SortItem(CypherParser::OC_SortItemContext *ctx) override { - if(ctx->ASC() or ctx->ASCENDING()) - { - auto *node = new ASTInternalNode("ASC"); - node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); - return static_cast(node); - }else - { - auto *node = new ASTInternalNode("DESC"); - node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); - return static_cast(node); - } - } - - //finished - std::any visitOC_Where(CypherParser::OC_WhereContext *ctx) override { - auto *node = new ASTInternalNode("WHERE"); - node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); - return static_cast(node); - } - - //finished - std::any visitOC_Pattern(CypherParser::OC_PatternContext *ctx) override { - auto *node = new ASTInternalNode("PATTERN"); - for(CypherParser::OC_PatternPartContext* element : ctx->oC_PatternPart()) - { - node->addElements(any_cast(visitOC_PatternPart(element))); - } - return static_cast(node); - } - - //finished - std::any visitOC_PatternPart(CypherParser::OC_PatternPartContext *ctx) override { - if(ctx->oC_Variable()) - { - auto *node = new ASTInternalNode("="); - - node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); - node->addElements(any_cast(visitOC_AnonymousPatternPart(ctx->oC_AnonymousPatternPart()))); - - return static_cast(node); - } - return visitOC_AnonymousPatternPart(ctx->oC_AnonymousPatternPart()); - } - - //finished - std::any visitOC_AnonymousPatternPart(CypherParser::OC_AnonymousPatternPartContext *ctx) override { - return visitOC_PatternElement(ctx->oC_PatternElement()); - } - - //finished - std::any visitOC_PatternElement(CypherParser::OC_PatternElementContext *ctx) override { - if(ctx->oC_PatternElement()) - { - return visitOC_PatternElement(ctx->oC_PatternElement()); - } - - if(!ctx->oC_PatternElementChain().empty()) - { - auto *node = new ASTInternalNode("PATTERN_ELEMENTS"); - node->addElements(any_cast(visitOC_NodePattern(ctx->oC_NodePattern()))); - for(CypherParser::OC_PatternElementChainContext* element : ctx->oC_PatternElementChain()) - { - node->addElements(any_cast(visitOC_PatternElementChain(element))); - } - return static_cast(node); - } - return visitOC_NodePattern(ctx->oC_NodePattern()); - } - - //finsihed - std::any visitOC_RelationshipsPattern(CypherParser::OC_RelationshipsPatternContext *ctx) override { - auto *node = new ASTInternalNode("PATTERN_ELEMENTS"); - node->addElements(any_cast(visitOC_NodePattern(ctx->oC_NodePattern()))); - for(CypherParser::OC_PatternElementChainContext* element : ctx->oC_PatternElementChain()) - { - node->addElements(any_cast(visitOC_PatternElementChain(element))); - } - return static_cast(node); - } - - //finished - std::any visitOC_NodePattern(CypherParser::OC_NodePatternContext *ctx) override { - auto *node = new ASTInternalNode("NODE_PATTERN"); - if(ctx->oC_Variable()) - { - node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); - } - if(ctx->oC_NodeLabels()) - { - node->addElements(any_cast(visitOC_NodeLabels(ctx->oC_NodeLabels()))); - } - if(ctx->oC_Properties()) - { - node->addElements(any_cast(visitOC_Properties(ctx->oC_Properties()))); - } - return static_cast(node); - } - - //finished - std::any visitOC_PatternElementChain(CypherParser::OC_PatternElementChainContext *ctx) override { - auto *node = new ASTInternalNode("PATTERN_ELEMENT_CHAIN"); - node->addElements(any_cast(visitOC_RelationshipPattern(ctx->oC_RelationshipPattern()))); - node->addElements(any_cast(visitOC_NodePattern(ctx->oC_NodePattern()))); - return static_cast(node); - } - - //finished - std::any visitOC_RelationshipPattern(CypherParser::OC_RelationshipPatternContext *ctx) override { - auto *node = new ASTInternalNode("RELATIONSHIP_PATTTERN"); - if(ctx->oC_LeftArrowHead() && !ctx->oC_RightArrowHead()) - { - node->addElements(any_cast(visitOC_LeftArrowHead(ctx->oC_LeftArrowHead()))); - }else if(!ctx->oC_LeftArrowHead() && ctx->oC_RightArrowHead()) - { - node->addElements(any_cast(visitOC_RightArrowHead(ctx->oC_RightArrowHead()))); - }else - { - node->addElements(new ASTLeafNoValue("UNIDIRECTION_ARROW")); - } - if(ctx->oC_RelationshipDetail()) - { - node->addElements(any_cast(visitOC_RelationshipDetail(ctx->oC_RelationshipDetail()))); - } - return static_cast(node); - } - - //finished - std::any visitOC_RelationshipDetail(CypherParser::OC_RelationshipDetailContext *ctx) override { - auto *node = new ASTInternalNode("RELATIONSHIP_DETAILS"); - if(ctx->oC_Variable()) - { - node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); - } - if(ctx->oC_RelationshipTypes()) - { - node->addElements(any_cast(visitOC_RelationshipTypes(ctx->oC_RelationshipTypes()))); - } - if(ctx->oC_RangeLiteral()) - { - node->addElements(any_cast(visitOC_RangeLiteral(ctx->oC_RangeLiteral()))); - } - if(ctx->oC_Properties()) - { - node->addElements(any_cast(visitOC_Properties(ctx->oC_Properties()))); - } - return static_cast(node); ; - } - - //finished - std::any visitOC_Properties(CypherParser::OC_PropertiesContext *ctx) override { - if(ctx->oC_Parameter()) - { - return visitOC_Parameter(ctx->oC_Parameter()); - } - return visitOC_MapLiteral(ctx->oC_MapLiteral()); - } - - //finished - std::any visitOC_RelationshipTypes(CypherParser::OC_RelationshipTypesContext *ctx) override { - - if(ctx->oC_RelTypeName().size()>1) - { - auto *node = new ASTInternalNode("RELATIONSHIP_TYPES"); - for(CypherParser::OC_RelTypeNameContext* element : ctx->oC_RelTypeName()) - { - node->addElements(any_cast(visitOC_RelTypeName(element))); - } - return static_cast(node); - } - return visitOC_RelTypeName(ctx->oC_RelTypeName()[0]); - } - - //finished - std::any visitOC_NodeLabels(CypherParser::OC_NodeLabelsContext *ctx) override { - if(ctx->oC_NodeLabel().size()>1) - { - auto *node = new ASTInternalNode("NODE_LABELS"); - for(CypherParser::OC_NodeLabelContext* element : ctx->oC_NodeLabel()) - { - node->addElements(any_cast(visitOC_NodeLabel(element))); - } - return static_cast(node); - } - return visitOC_NodeLabel(ctx->oC_NodeLabel()[0]); - } - - //finished - std::any visitOC_NodeLabel(CypherParser::OC_NodeLabelContext *ctx) override { - auto *node = new ASTInternalNode("NODE_LABEL"); - node->addElements(any_cast(visitOC_LabelName(ctx->oC_LabelName()))); - return static_cast(node); - } - - //finished - std::any visitOC_RangeLiteral(CypherParser::OC_RangeLiteralContext *ctx) override { - auto *node = new ASTInternalNode("RANGE"); - if(ctx->oC_IntegerLiteral().size()>1) - { - node->addElements(any_cast(visitOC_IntegerLiteral(ctx->oC_IntegerLiteral()[0]))); - node->addElements(any_cast(visitOC_IntegerLiteral(ctx->oC_IntegerLiteral()[1]))); - return static_cast(node); - } - node->addElements(any_cast(visitOC_IntegerLiteral(ctx->oC_IntegerLiteral()[0]))); - return static_cast(node); - } - - //finished - std::any visitOC_LabelName(CypherParser::OC_LabelNameContext *ctx) override { - return visitOC_SchemaName(ctx->oC_SchemaName()); - } - - //finished - std::any visitOC_RelTypeName(CypherParser::OC_RelTypeNameContext *ctx) override { - return visitOC_SchemaName(ctx->oC_SchemaName()); - } - - //finished - std::any visitOC_PropertyExpression(CypherParser::OC_PropertyExpressionContext *ctx) override { - auto *node = new ASTInternalNode("PROPERTY"); - node->addElements(any_cast(visitOC_Atom(ctx->oC_Atom()))); - for(CypherParser::OC_PropertyLookupContext* element : ctx->oC_PropertyLookup()) - { - node->addElements(any_cast(visitOC_PropertyLookup(element))); - } - return static_cast(node); - } - - //finished - std::any visitOC_Expression(CypherParser::OC_ExpressionContext *ctx) override { - return visitOC_OrExpression(ctx->oC_OrExpression()); - } - - //finished - std::any visitOC_OrExpression(CypherParser::OC_OrExpressionContext *ctx) override { - if(ctx->oC_XorExpression().size()>1) - { - auto *node = new ASTInternalNode("OR"); - for(CypherParser::OC_XorExpressionContext* element : ctx->oC_XorExpression()) - { - node->addElements(any_cast(visitOC_XorExpression(element))); - } - return static_cast(node); - } - return visitOC_XorExpression(ctx->oC_XorExpression()[0]); - } - - //finished - std::any visitOC_XorExpression(CypherParser::OC_XorExpressionContext *ctx) override { - if(ctx->oC_AndExpression().size()>1) - { - auto *node = new ASTInternalNode("XOR"); - for(CypherParser::OC_AndExpressionContext* element : ctx->oC_AndExpression()) - { - node->addElements(any_cast(visitOC_AndExpression(element))); - } - } - return visitOC_AndExpression(ctx->oC_AndExpression()[0]); - } - - //finished - std::any visitOC_AndExpression(CypherParser::OC_AndExpressionContext *ctx) override { - if(ctx->oC_NotExpression().size()>1) - { - auto *node = new ASTInternalNode("AND"); - for(CypherParser::OC_NotExpressionContext* element : ctx->oC_NotExpression()) - { - node->addElements(any_cast(visitOC_NotExpression(element))); - } - return static_cast(node); - } - return visitOC_NotExpression(ctx->oC_NotExpression()[0]); - } - - //finished - std::any visitOC_NotExpression(CypherParser::OC_NotExpressionContext *ctx) override { - if(!ctx->NOT().empty()) - { - if(ctx->NOT().size() % 2 != 0) - { - auto *node = new ASTInternalNode("NOT"); - node->addElements(any_cast(visitOC_ComparisonExpression(ctx->oC_ComparisonExpression()))); - return static_cast(node); - } - } - return visitOC_ComparisonExpression(ctx->oC_ComparisonExpression()); - } - - - //finished - std::any visitOC_ComparisonExpression(CypherParser::OC_ComparisonExpressionContext *ctx) override { - if(!ctx->oC_PartialComparisonExpression().empty()) - { - auto *node = new ASTInternalNode("COMPARISON"); - node->addElements(any_cast(visitOC_StringListNullPredicateExpression(ctx->oC_StringListNullPredicateExpression()))); - for(CypherParser::OC_PartialComparisonExpressionContext* element : ctx->oC_PartialComparisonExpression()) - { - node->addElements(any_cast(visitOC_PartialComparisonExpression(element))); - } - return static_cast(node); - } - return visitOC_StringListNullPredicateExpression(ctx->oC_StringListNullPredicateExpression()); - } - - //finished - std::any visitOC_PartialComparisonExpression(CypherParser::OC_PartialComparisonExpressionContext *ctx) override { - if(ctx->getText().find(">") != string::npos) - { - auto *node = new ASTInternalNode(">"); - node->addElements(any_cast(visitOC_StringListNullPredicateExpression(ctx->oC_StringListNullPredicateExpression()))); - return static_cast(node); - }else if(ctx->getText().find("<>") != string::npos) - { - auto *node = new ASTInternalNode("<>"); - node->addElements(any_cast(visitOC_StringListNullPredicateExpression(ctx->oC_StringListNullPredicateExpression()))); - return static_cast(node); - }else if(ctx->getText().find("=") != string::npos) - { - auto *node = new ASTInternalNode("=="); - node->addElements(any_cast(visitOC_StringListNullPredicateExpression(ctx->oC_StringListNullPredicateExpression()))); - return static_cast(node); - }else if(ctx->getText().find("<") != string::npos) - { - auto *node = new ASTInternalNode("<"); - node->addElements(any_cast(visitOC_StringListNullPredicateExpression(ctx->oC_StringListNullPredicateExpression()))); - return static_cast(node); - }else if(ctx->getText().find(">=") != string::npos) - { - auto *node = new ASTInternalNode(">="); - node->addElements(any_cast(visitOC_StringListNullPredicateExpression(ctx->oC_StringListNullPredicateExpression()))); - return static_cast(node); - }else - { - auto *node = new ASTInternalNode("<="); - node->addElements(any_cast(visitOC_StringListNullPredicateExpression(ctx->oC_StringListNullPredicateExpression()))); - return static_cast(node); - } - } - - //finished - std::any visitOC_StringListNullPredicateExpression(CypherParser::OC_StringListNullPredicateExpressionContext *ctx) override { - auto *node = new ASTInternalNode("PREDICATE_EXPRESSIONS"); - node->addElements(any_cast(visitOC_AddOrSubtractExpression(ctx->oC_AddOrSubtractExpression()))); - if(!ctx->oC_StringPredicateExpression().empty()) - { - auto *strPredicate = new ASTInternalNode("STRING_PREDICATES"); - for(CypherParser::OC_StringPredicateExpressionContext* element: ctx->oC_StringPredicateExpression()) - { - strPredicate->addElements(any_cast(visitOC_StringPredicateExpression(element))); - } - node->addElements(strPredicate); - } - if(!ctx->oC_ListPredicateExpression().empty()) - { - auto *listPredicate = new ASTInternalNode("LIST_PREDICATES"); - for(CypherParser::OC_ListPredicateExpressionContext* element: ctx->oC_ListPredicateExpression()) - { - listPredicate->addElements(any_cast(visitOC_ListPredicateExpression(element))); - } - node->addElements(listPredicate); - } - if(!ctx->oC_NullPredicateExpression().empty()) - { - auto *nullPredicate = new ASTInternalNode("NULL_PREDICATES"); - for(CypherParser::OC_NullPredicateExpressionContext* element: ctx->oC_NullPredicateExpression()) - { - nullPredicate->addElements(any_cast(visitOC_NullPredicateExpression(element))); - } - node->addElements(nullPredicate); - } - if(node->elements.size()>1) - { - return static_cast(node); - }else - { - return visitOC_AddOrSubtractExpression(ctx->oC_AddOrSubtractExpression()); - } - } - - //finished - std::any visitOC_StringPredicateExpression(CypherParser::OC_StringPredicateExpressionContext *ctx) override { - if(ctx->STARTS()) - { - auto *node = new ASTInternalNode("STARTS_WITH"); - node->addElements(any_cast(visitOC_AddOrSubtractExpression(ctx->oC_AddOrSubtractExpression()))); - return static_cast(node); - }else if(ctx->ENDS()) - { - auto *node = new ASTInternalNode("ENDS_WITH"); - node->addElements(any_cast(visitOC_AddOrSubtractExpression(ctx->oC_AddOrSubtractExpression()))); - return static_cast(node); - }else - { - auto *node = new ASTInternalNode("CONTAINS"); - node->addElements(any_cast(visitOC_AddOrSubtractExpression(ctx->oC_AddOrSubtractExpression()))); - return static_cast(node); - } - } - - - //finished - std::any visitOC_ListPredicateExpression(CypherParser::OC_ListPredicateExpressionContext *ctx) override { - auto *node = new ASTInternalNode("IN"); - node->addElements(any_cast(visitOC_AddOrSubtractExpression(ctx->oC_AddOrSubtractExpression()))); - return static_cast(node); - } - - //finished - std::any visitOC_NullPredicateExpression(CypherParser::OC_NullPredicateExpressionContext *ctx) override { - if(ctx->NOT()) - { - auto *node = new ASTLeafNoValue("IS_NOT_NULL"); - return static_cast(node); - } - auto *node = new ASTLeafNoValue("IS_NULL"); - return static_cast(node); - } - - //finished - std::any visitOC_AddOrSubtractExpression(CypherParser::OC_AddOrSubtractExpressionContext *ctx) override { - if(ctx->oC_MultiplyDivideModuloExpression().size()>1) - { - int multIndex =1; - auto *node = new ASTInternalNode("ADD_OR_SUBSTRACT"); - node->addElements(any_cast(visitOC_MultiplyDivideModuloExpression(ctx->oC_MultiplyDivideModuloExpression(0)))); - - for(int i=0; ichildren.size();i++) - { - if(ctx->children[i]->getText() == "+") - { - auto *plus = new ASTInternalNode("+"); - plus->addElements(any_cast(visitOC_MultiplyDivideModuloExpression(ctx->oC_MultiplyDivideModuloExpression(multIndex++)))); - node->addElements(plus); - }else if(ctx->children[i]->getText() == "-") - { - auto *minus = new ASTInternalNode("-"); - minus->addElements(any_cast(visitOC_MultiplyDivideModuloExpression(ctx->oC_MultiplyDivideModuloExpression(multIndex++)))); - node->addElements(minus); - } - } - return static_cast(node); - } - return visitOC_MultiplyDivideModuloExpression(ctx->oC_MultiplyDivideModuloExpression(0)); - } - - //finished - std::any visitOC_MultiplyDivideModuloExpression(CypherParser::OC_MultiplyDivideModuloExpressionContext *ctx) override { - if(ctx->oC_PowerOfExpression().size()>1) - { - int powIndex = 1; - auto *node = new ASTInternalNode("MULTIPLY_DIVID_MODULO"); - node->addElements(any_cast(visitOC_PowerOfExpression(ctx->oC_PowerOfExpression(0)))); - - for(int i=0; ichildren.size();i++) - { - if(ctx->children[i]->getText() == "*") - { - auto *plus = new ASTInternalNode("*"); - plus->addElements(any_cast(visitOC_PowerOfExpression(ctx->oC_PowerOfExpression(powIndex++)))); - node->addElements(plus); - }else if(ctx->children[i]->getText() == "/") - { - auto *minus = new ASTInternalNode("/"); - minus->addElements(any_cast(visitOC_PowerOfExpression(ctx->oC_PowerOfExpression(powIndex++)))); - node->addElements(minus); - } - } - return static_cast(node); - } - - return visitOC_PowerOfExpression(ctx->oC_PowerOfExpression(0)); - } - - //finished - std::any visitOC_PowerOfExpression(CypherParser::OC_PowerOfExpressionContext *ctx) override { - if(ctx->oC_UnaryAddOrSubtractExpression().size()>1) - { - int unaryIndex = 1; - auto *node = new ASTInternalNode("POWER_OF"); - node->addElements(any_cast(visitOC_UnaryAddOrSubtractExpression(ctx->oC_UnaryAddOrSubtractExpression(0)))); - - for(int i=0; ichildren.size();i++) - { - if(ctx->children[i]->getText() == "^") - { - auto *plus = new ASTInternalNode("^"); - plus->addElements(any_cast(visitOC_UnaryAddOrSubtractExpression(ctx->oC_UnaryAddOrSubtractExpression(unaryIndex++)))); - node->addElements(plus); - } - } - return static_cast(node); - } - return visitOC_UnaryAddOrSubtractExpression(ctx->oC_UnaryAddOrSubtractExpression(0)); - } - - - //finished - std::any visitOC_UnaryAddOrSubtractExpression(CypherParser::OC_UnaryAddOrSubtractExpressionContext *ctx) override { - if(ctx->children[0]->getText() == "+") - { - auto *node = new ASTInternalNode("UNARY_+"); - node->addElements(any_cast(visitOC_NonArithmeticOperatorExpression(ctx->oC_NonArithmeticOperatorExpression()))); - return static_cast(node); - }else if(ctx->children[0]->getText() == "-") - { - auto *node = new ASTInternalNode("UNARY_-"); - node->addElements(any_cast(visitOC_NonArithmeticOperatorExpression(ctx->oC_NonArithmeticOperatorExpression()))); - return static_cast(node); - }else - { - return visitOC_NonArithmeticOperatorExpression(ctx->oC_NonArithmeticOperatorExpression()); - } - } - - //finished - std::any visitOC_NonArithmeticOperatorExpression(CypherParser::OC_NonArithmeticOperatorExpressionContext *ctx) override { - if(!ctx->oC_ListOperatorExpression().empty() | !ctx->oC_PropertyLookup().empty()) - { - auto *node = new ASTInternalNode("NON_ARITHMETIC_OPERATOR"); - int i = 0; - int j = 0; - for(auto *child : ctx->children) - { - std::string typeName = typeid(*child).name(); - if(typeName.substr(17) == "OC_AtomContextE") - { - node->addElements(any_cast(visitOC_Atom(ctx->oC_Atom()))); - }else if(typeName.substr(17) == "OC_PropertyLookupContextE") - { - node->addElements(any_cast(visitOC_PropertyLookup(ctx->oC_PropertyLookup(i++)))); - }else if(typeName.substr(17) == "OC_ListOperatorExpressionContextE") - { - node->addElements(any_cast(visitOC_ListOperatorExpression(ctx->oC_ListOperatorExpression(j++)))); - }else - { - node->addElements(any_cast(visitOC_NodeLabels(ctx->oC_NodeLabels()))); - } - } - return static_cast(node); - } - return visitOC_Atom(ctx->oC_Atom()); - } - - //finished - std::any visitOC_ListOperatorExpression(CypherParser::OC_ListOperatorExpressionContext *ctx) override { - if(ctx->oC_Expression().size() == 2) - { - auto *node = new ASTInternalNode("LIST_INDEX_RANGE"); - node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression(0)))); - node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression(1)))); - return static_cast(node); - } - auto *node = new ASTInternalNode("LIST_INDEX"); - node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression(0)))); - return static_cast(node); - } - - //finished - std::any visitOC_PropertyLookup(CypherParser::OC_PropertyLookupContext *ctx) override { - return visitOC_PropertyKeyName(ctx->oC_PropertyKeyName()); - } - - //finished - std::any visitOC_Atom(CypherParser::OC_AtomContext *ctx) override { - if(ctx->oC_Literal()) - { - return visitOC_Literal(ctx->oC_Literal()); - }else if(ctx->oC_Parameter()) - { - return visitOC_Parameter(ctx->oC_Parameter()); - }else if(ctx->oC_Quantifier()) - { - return visitOC_Quantifier(ctx->oC_Quantifier()); - }else if(ctx->oC_Variable()) - { - return visitOC_Variable(ctx->oC_Variable()); - }else if(ctx->oC_CaseExpression()) - { - return visitOC_CaseExpression(ctx->oC_CaseExpression()); - }else if(ctx->oC_ExistentialSubquery()) - { - return visitOC_ExistentialSubquery(ctx->oC_ExistentialSubquery()); - }else if(ctx->oC_FunctionInvocation()) - { - return visitOC_FunctionInvocation(ctx->oC_FunctionInvocation()); - }else if(ctx->oC_ListComprehension()) - { - return visitOC_ListComprehension(ctx->oC_ListComprehension()); - }else if(ctx->oC_ParenthesizedExpression()) - { - return visitOC_ParenthesizedExpression(ctx->oC_ParenthesizedExpression()); - }else if(ctx->oC_PatternComprehension()) - { - return visitOC_PatternComprehension(ctx->oC_PatternComprehension()); - }else if(ctx->oC_PatternPredicate()) - { - return visitOC_PatternPredicate(ctx->oC_PatternPredicate()); - }else - { - auto *node = new ASTLeafValue("COUNT", "*"); - return static_cast(node); - } - } - - //finished - std::any visitOC_CaseExpression(CypherParser::OC_CaseExpressionContext *ctx) override { - auto *caseNode = new ASTInternalNode("CASE_PATTERN"); - int caseAlt = 0; - for(int i = 0; ichildren.size(); i++) - { - string text = ctx->children[i]->getText(); - std::transform(text.begin(), text.end(), text.begin(), ::toupper); - string type; - if(i+2 < ctx->children.size()) - { - type = typeid(*ctx->children[i+2]).name(); - } - if(text == "CASE" && type.substr(17) == "OC_ExpressionContextE") - { - auto *node = new ASTInternalNode("CASE_EXPRESSION"); - node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression(0)))); - caseNode->addElements(node); - }else if(text == "ELSE" && ctx->oC_Expression().size()>1) - { - auto *node = new ASTInternalNode("ELSE_EXPRESSION"); - node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression(1)))); - caseNode->addElements(node); - }else if(text == "ELSE") - { - auto *node = new ASTInternalNode("ELSE_EXPRESSION"); - node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression(0)))); - caseNode->addElements(node); - }else if(text.find("WHEN") != string::npos) - { - caseNode->addElements(any_cast(visitOC_CaseAlternative(ctx->oC_CaseAlternative(caseAlt++)))); - } - } - return static_cast(caseNode); - } - - //finished - std::any visitOC_CaseAlternative(CypherParser::OC_CaseAlternativeContext *ctx) override { - auto *node = new ASTInternalNode("CASE"); - - auto *when = new ASTInternalNode("WHEN"); - when->addElements(any_cast(visitOC_Expression(ctx->oC_Expression(0)))); - - auto *then = new ASTInternalNode("THEN"); - then->addElements(any_cast(visitOC_Expression(ctx->oC_Expression(1)))); - - node->addElements(when); - node->addElements(then); - return static_cast(node); - } - - //finished - std::any visitOC_ListComprehension(CypherParser::OC_ListComprehensionContext *ctx) override { - auto *node = new ASTInternalNode("LIST_COMPREHENSION"); - node->addElements(any_cast(visitOC_FilterExpression(ctx->oC_FilterExpression()))); - if(ctx->getText().find('|') != string::npos) - { - auto *result = new ASTInternalNode("FILTER_RESULT"); - result->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); - node->addElements(result); - } - return static_cast(node); - } - - //finished - std::any visitOC_PatternComprehension(CypherParser::OC_PatternComprehensionContext *ctx) override { - auto *node = new ASTInternalNode("PATTERN_COMPREHENSION"); - if(ctx->oC_Variable()) - { - auto *eual = new ASTInternalNode("="); - eual->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); - eual->addElements(any_cast(visitOC_RelationshipsPattern(ctx->oC_RelationshipsPattern()))); - node->addElements(eual); - }else - { - node->addElements(any_cast(visitOC_RelationshipsPattern(ctx->oC_RelationshipsPattern()))); - } - if(ctx->oC_Where()) - { - node->addElements(any_cast(visitOC_Where(ctx->oC_Where()))); - } - auto *result = new ASTInternalNode("FILTER_RESULT"); - result->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); - node->addElements(result); - return static_cast(node); - } - - //finished - std::any visitOC_Quantifier(CypherParser::OC_QuantifierContext *ctx) override { - if(ctx->ALL()) - { - auto *node = new ASTInternalNode("ALL"); - node->addElements(any_cast(visitOC_FilterExpression(ctx->oC_FilterExpression()))); - return static_cast(node); - }else if(ctx->ANY()) - { - auto *node = new ASTInternalNode("ANY"); - node->addElements(any_cast(visitOC_FilterExpression(ctx->oC_FilterExpression()))); - return static_cast(node); - }else if(ctx->NONE()) - { - auto *node = new ASTInternalNode("NONE"); - node->addElements(any_cast(visitOC_FilterExpression(ctx->oC_FilterExpression()))); - return static_cast(node); - }else - { - auto *node = new ASTInternalNode("SINGLE"); - node->addElements(any_cast(visitOC_FilterExpression(ctx->oC_FilterExpression()))); - return static_cast(node); - } - } - - //finished - std::any visitOC_FilterExpression(CypherParser::OC_FilterExpressionContext *ctx) override { - auto *node = new ASTInternalNode("FILTER_EXPRESSION"); - node->addElements(any_cast(visitOC_IdInColl(ctx->oC_IdInColl()))); - if(ctx->oC_Where()) - { - node->addElements(any_cast(visitOC_Where(ctx->oC_Where()))); - } - return static_cast(node); - } - - //finished - std::any visitOC_PatternPredicate(CypherParser::OC_PatternPredicateContext *ctx) override { - return visitOC_RelationshipsPattern(ctx->oC_RelationshipsPattern()); - } - - //finished - std::any visitOC_ParenthesizedExpression(CypherParser::OC_ParenthesizedExpressionContext *ctx) override { - return visitOC_Expression(ctx->oC_Expression()); - } - - //finished - std::any visitOC_IdInColl(CypherParser::OC_IdInCollContext *ctx) override { - auto *node = new ASTInternalNode("LIST_ITERATE"); - node->addElements(any_cast(visitOC_Variable(ctx->oC_Variable()))); - node->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()))); - return static_cast(node); - } - - //finished - std::any visitOC_FunctionInvocation(CypherParser::OC_FunctionInvocationContext *ctx) override { - auto *node = new ASTInternalNode("FUNCTION_BODY"); - node->addElements(any_cast(visitOC_FunctionName(ctx->oC_FunctionName()))); - - auto *aug = new ASTInternalNode("ARGUMENTS"); - if(ctx->DISTINCT()) - { - auto *distinct = new ASTInternalNode("DISTINCT"); - for(CypherParser::OC_ExpressionContext* elements : ctx->oC_Expression()) - { - distinct->addElements(any_cast(visitOC_Expression(elements))); - } - aug->addElements(distinct); - node->addElements(aug); - return static_cast(node); - } - - for(CypherParser::OC_ExpressionContext* elements : ctx->oC_Expression()) - { - aug->addElements(any_cast(visitOC_Expression(elements))); - } - if(!aug->elements.empty()) - { - node->addElements(aug); - } - return static_cast(node); - } - - //finished - std::any visitOC_FunctionName(CypherParser::OC_FunctionNameContext *ctx) override { - auto *node = new ASTInternalNode("FUNCTION"); - node->addElements(any_cast(visitOC_Namespace(ctx->oC_Namespace()))); - auto *name = new ASTLeafValue("FUNCTION_NAME", any_cast(visitOC_SymbolicName(ctx->oC_SymbolicName()))); - node->addElements(name); - return static_cast(node); - } - - //finished - std::any visitOC_ExistentialSubquery(CypherParser::OC_ExistentialSubqueryContext *ctx) override { - auto *node = new ASTInternalNode("EXISTS"); - if(ctx->oC_RegularQuery()) - { - node->addElements(any_cast(visitOC_RegularQuery(ctx->oC_RegularQuery()))); - return static_cast(node); - }else - { - node->addElements(any_cast(visitOC_Pattern(ctx->oC_Pattern()))); - if(ctx->oC_Where()) - { - node->addElements(any_cast(visitOC_Where(ctx->oC_Where()))); - } - return static_cast(node); - } - } - - //finished - std::any visitOC_ExplicitProcedureInvocation(CypherParser::OC_ExplicitProcedureInvocationContext *ctx) override { - auto *node = new ASTInternalNode("EXPLICIT_PROCEDURE"); - node->addElements(any_cast(visitOC_ProcedureName(ctx->oC_ProcedureName()))); - if(ctx->oC_Expression().size()>1) - { - auto *arg = new ASTInternalNode("ARGUMENTS"); - for(CypherParser::OC_ExpressionContext* elements : ctx->oC_Expression()) - { - arg->addElements(any_cast(visitOC_Expression(elements))); - } - node->addElements(arg); - return static_cast(node); - } - return static_cast(node); - } - - //finished - std::any visitOC_ImplicitProcedureInvocation(CypherParser::OC_ImplicitProcedureInvocationContext *ctx) override { - auto *node = new ASTInternalNode("IMPLICIT_PROCEDURE"); - node->addElements(any_cast(visitOC_ProcedureName(ctx->oC_ProcedureName()))); - return static_cast(node); - } - - //finished - std::any visitOC_ProcedureResultField(CypherParser::OC_ProcedureResultFieldContext *ctx) override { - auto *node = new ASTLeafValue("PROCEDURE_RESULT", any_cast(visitOC_SymbolicName(ctx->oC_SymbolicName()))); - return static_cast(node); - } - - //finished - std::any visitOC_ProcedureName(CypherParser::OC_ProcedureNameContext *ctx) override { - auto *node = new ASTInternalNode("PROCEDURE"); - node->addElements(any_cast(visitOC_Namespace(ctx->oC_Namespace()))); - auto *name = new ASTLeafValue("PROCEDURE_NAME", any_cast(visitOC_SymbolicName(ctx->oC_SymbolicName()))); - node->addElements(name); - return static_cast(node); - } - - - //finished - std::any visitOC_Namespace(CypherParser::OC_NamespaceContext *ctx) override { - auto *node = new ASTInternalNode("NAMESPACE"); - for(CypherParser::OC_SymbolicNameContext* element : ctx->oC_SymbolicName()) - { - auto *name = new ASTLeafNoValue(any_cast(visitOC_SymbolicName(element))); - node->addElements(name); - } - return static_cast(node); - } - - //finished - std::any visitOC_Variable(CypherParser::OC_VariableContext *ctx) override { - auto *node = new ASTLeafValue("VARIABLE", any_cast(visitOC_SymbolicName(ctx->oC_SymbolicName()))); - return static_cast(node); - } - - //finished - std::any visitOC_Literal(CypherParser::OC_LiteralContext *ctx) override { - if(ctx->oC_BooleanLiteral()) - { - return visitOC_BooleanLiteral(ctx->oC_BooleanLiteral()); - }else if(ctx->oC_ListLiteral()) - { - return visitOC_ListLiteral(ctx->oC_ListLiteral()); - }else if(ctx->oC_MapLiteral()) - { - return visitOC_MapLiteral(ctx->oC_MapLiteral()); - }else if(ctx->oC_NumberLiteral()) - { - return visitOC_NumberLiteral(ctx->oC_NumberLiteral()); - }else if(ctx->NULL_()) - { - auto *node = new ASTLeafNoValue("NULL"); - return static_cast(node); - }else - { - auto *node = new ASTLeafValue("STRING", ctx->getText()); - return static_cast(node); - } - } - - //finished - std::any visitOC_BooleanLiteral(CypherParser::OC_BooleanLiteralContext *ctx) override { - if(ctx->TRUE()) - { - auto *node = new ASTLeafValue("BOOLEAN", "TRUE"); - return static_cast(node); - } else - { - auto *node = new ASTLeafValue("BOOLEAN", "FALSE"); - return static_cast(node); - } - } - - //finished - std::any visitOC_NumberLiteral(CypherParser::OC_NumberLiteralContext *ctx) override { - if(ctx->oC_DoubleLiteral()) - { - return visitOC_DoubleLiteral(ctx->oC_DoubleLiteral()); - } - return visitOC_IntegerLiteral(ctx->oC_IntegerLiteral()); - } - - //finished - std::any visitOC_IntegerLiteral(CypherParser::OC_IntegerLiteralContext *ctx) override { - if(ctx->DecimalInteger()) - { - auto *node = new ASTLeafValue("DECIMAL", ctx->getText()); - return static_cast(node); - } else if(ctx->HexInteger()) - { - auto *node = new ASTLeafValue("HEX", ctx->getText()); - return static_cast(node); - }else - { - auto *node = new ASTLeafValue("OCTAL", ctx->getText()); - return static_cast(node); - } - - } - - //finished - std::any visitOC_DoubleLiteral(CypherParser::OC_DoubleLiteralContext *ctx) override { - if(ctx->ExponentDecimalReal()) - { - auto *node = new ASTLeafValue("EXP_DECIMAL", ctx->getText()); - return static_cast(node); - }else - { - auto *node = new ASTLeafValue("REGULAR_DECIMAL", ctx->getText()); - return static_cast(node); - } - } - - //finished - std::any visitOC_ListLiteral(CypherParser::OC_ListLiteralContext *ctx) override { - auto *node = new ASTInternalNode("LIST"); - for(CypherParser::OC_ExpressionContext* element: ctx->oC_Expression()) - { - node->addElements(any_cast(visitOC_Expression(element))); - } - return static_cast(node); - } - - //finished - std::any visitOC_MapLiteral(CypherParser::OC_MapLiteralContext *ctx) override { - auto *node = new ASTInternalNode("PROPERIES_MAP"); - for(int i=0; ioC_PropertyKeyName().size();i++) - { - auto *propNode = new ASTInternalNode("PROPERTY"); - propNode->addElements(any_cast(visitOC_PropertyKeyName(ctx->oC_PropertyKeyName()[i]))); - propNode->addElements(any_cast(visitOC_Expression(ctx->oC_Expression()[i]))); - node->addElements(propNode); - } - - return static_cast(node); - } - - //finished - std::any visitOC_PropertyKeyName(CypherParser::OC_PropertyKeyNameContext *ctx) override { - return visitOC_SchemaName(ctx->oC_SchemaName()); - } - - //finished - std::any visitOC_Parameter(CypherParser::OC_ParameterContext *ctx) override { - if(ctx->oC_SymbolicName()) - { - auto *node = new ASTLeafValue("PARAMETER", any_cast(visitOC_SymbolicName(ctx->oC_SymbolicName()))); - return static_cast(node); - }else - { - auto *node = new ASTLeafValue("PARAMETER", ctx->getText()); - return static_cast(node); - } - } - - //finished - std::any visitOC_SchemaName(CypherParser::OC_SchemaNameContext *ctx) override { - if(ctx->oC_ReservedWord()) - { - return visitOC_ReservedWord(ctx->oC_ReservedWord()); - } - auto *node = new ASTLeafValue("SYMBOLIC_WORD",any_cast(visitOC_SymbolicName(ctx->oC_SymbolicName()))); - return static_cast(node); - } - - //finished - std::any visitOC_ReservedWord(CypherParser::OC_ReservedWordContext *ctx) override { - auto *node = new ASTLeafValue("RESERVED_WORD", ctx->getText()); - return static_cast(node); - } - - //finished - std::any visitOC_SymbolicName(CypherParser::OC_SymbolicNameContext *ctx) override { - return ctx->getText(); - } - - //finished - std::any visitOC_LeftArrowHead(CypherParser::OC_LeftArrowHeadContext *ctx) override { - return static_cast(new ASTLeafNoValue("LEFT_ARRROW")); - } - - //finished - std::any visitOC_RightArrowHead(CypherParser::OC_RightArrowHeadContext *ctx) override { - return static_cast(new ASTLeafNoValue("RIGHT_ARROW"));; - } - - //finished - std::any visitOC_Dash(CypherParser::OC_DashContext *ctx) override { - return visitChildren(ctx); - } -}; + std::any visitOC_Cypher(CypherParser::OC_CypherContext *ctx) override; + + std::any visitOC_Statement(CypherParser::OC_StatementContext *ctx) override; + + std::any visitOC_Query(CypherParser::OC_QueryContext *ctx) override; + + std::any visitOC_RegularQuery(CypherParser::OC_RegularQueryContext *ctx) override ; + + std::any visitOC_Union(CypherParser::OC_UnionContext *ctx) override; + + std::any visitOC_SingleQuery(CypherParser::OC_SingleQueryContext *ctx) override; + + std::any visitOC_SinglePartQuery(CypherParser::OC_SinglePartQueryContext *ctx) override; + + std::any visitOC_MultiPartQuery(CypherParser::OC_MultiPartQueryContext *ctx) override; + + std::any visitOC_UpdatingClause(CypherParser::OC_UpdatingClauseContext *ctx) override ; + + std::any visitOC_ReadingClause(CypherParser::OC_ReadingClauseContext *ctx) override ; + + std::any visitOC_Match(CypherParser::OC_MatchContext *ctx) override ; + + std::any visitOC_Unwind(CypherParser::OC_UnwindContext *ctx) override ; + + std::any visitOC_Merge(CypherParser::OC_MergeContext *ctx) override ; + + std::any visitOC_MergeAction(CypherParser::OC_MergeActionContext *ctx) override ; + + std::any visitOC_Create(CypherParser::OC_CreateContext *ctx) override ; + + std::any visitOC_Set(CypherParser::OC_SetContext *ctx) override ; + + std::any visitOC_SetItem(CypherParser::OC_SetItemContext *ctx) override; + + std::any visitOC_Delete(CypherParser::OC_DeleteContext *ctx) override ; + + std::any visitOC_Remove(CypherParser::OC_RemoveContext *ctx) override ; + + std::any visitOC_RemoveItem(CypherParser::OC_RemoveItemContext *ctx) override ; + + std::any visitOC_InQueryCall(CypherParser::OC_InQueryCallContext *ctx) override ; + + std::any visitOC_StandaloneCall(CypherParser::OC_StandaloneCallContext *ctx) override; + + std::any visitOC_YieldItems(CypherParser::OC_YieldItemsContext *ctx) override ; + + std::any visitOC_YieldItem(CypherParser::OC_YieldItemContext *ctx) override ; + + std::any visitOC_With(CypherParser::OC_WithContext *ctx) override ; + + std::any visitOC_Return(CypherParser::OC_ReturnContext *ctx) override ; + + std::any visitOC_ProjectionBody(CypherParser::OC_ProjectionBodyContext *ctx) override ; + + std::any visitOC_ProjectionItems(CypherParser::OC_ProjectionItemsContext *ctx) override ; + + std::any visitOC_ProjectionItem(CypherParser::OC_ProjectionItemContext *ctx) override ; + + std::any visitOC_Order(CypherParser::OC_OrderContext *ctx) override ; + + std::any visitOC_Skip(CypherParser::OC_SkipContext *ctx) override ; + + std::any visitOC_Limit(CypherParser::OC_LimitContext *ctx) override ; + + std::any visitOC_SortItem(CypherParser::OC_SortItemContext *ctx) override ; + + std::any visitOC_Where(CypherParser::OC_WhereContext *ctx) override ; + + std::any visitOC_Pattern(CypherParser::OC_PatternContext *ctx) override ; + + std::any visitOC_PatternPart(CypherParser::OC_PatternPartContext *ctx) override ; + + std::any visitOC_AnonymousPatternPart(CypherParser::OC_AnonymousPatternPartContext *ctx) override ; + + std::any visitOC_PatternElement(CypherParser::OC_PatternElementContext *ctx) override ; + + std::any visitOC_RelationshipsPattern(CypherParser::OC_RelationshipsPatternContext *ctx) override ; + + std::any visitOC_NodePattern(CypherParser::OC_NodePatternContext *ctx) override ; + + std::any visitOC_PatternElementChain(CypherParser::OC_PatternElementChainContext *ctx) override ; + + std::any visitOC_RelationshipPattern(CypherParser::OC_RelationshipPatternContext *ctx) override ; + + std::any visitOC_RelationshipDetail(CypherParser::OC_RelationshipDetailContext *ctx) override ; + + std::any visitOC_Properties(CypherParser::OC_PropertiesContext *ctx) override ; + + std::any visitOC_RelationshipTypes(CypherParser::OC_RelationshipTypesContext *ctx) override ; + + + std::any visitOC_NodeLabels(CypherParser::OC_NodeLabelsContext *ctx) override ; + std::any visitOC_NodeLabel(CypherParser::OC_NodeLabelContext *ctx) override ; + + std::any visitOC_RangeLiteral(CypherParser::OC_RangeLiteralContext *ctx) override ; + + std::any visitOC_LabelName(CypherParser::OC_LabelNameContext *ctx) override ; + + std::any visitOC_RelTypeName(CypherParser::OC_RelTypeNameContext *ctx) override ; + + std::any visitOC_PropertyExpression(CypherParser::OC_PropertyExpressionContext *ctx) override ; + + std::any visitOC_Expression(CypherParser::OC_ExpressionContext *ctx) override ; + + std::any visitOC_OrExpression(CypherParser::OC_OrExpressionContext *ctx) override ; + + std::any visitOC_XorExpression(CypherParser::OC_XorExpressionContext *ctx) override ; + + std::any visitOC_AndExpression(CypherParser::OC_AndExpressionContext *ctx) override ; + + std::any visitOC_NotExpression(CypherParser::OC_NotExpressionContext *ctx) override ; + + std::any visitOC_ComparisonExpression(CypherParser::OC_ComparisonExpressionContext *ctx) override ; + + std::any visitOC_PartialComparisonExpression(CypherParser::OC_PartialComparisonExpressionContext *ctx) override ; + + + std::any visitOC_StringListNullPredicateExpression(CypherParser::OC_StringListNullPredicateExpressionContext *ctx) override ; + + std::any visitOC_StringPredicateExpression(CypherParser::OC_StringPredicateExpressionContext *ctx) override ; + + std::any visitOC_ListPredicateExpression(CypherParser::OC_ListPredicateExpressionContext *ctx) override ; + + std::any visitOC_NullPredicateExpression(CypherParser::OC_NullPredicateExpressionContext *ctx) override ; + + std::any visitOC_AddOrSubtractExpression(CypherParser::OC_AddOrSubtractExpressionContext *ctx) override ; + + std::any visitOC_MultiplyDivideModuloExpression(CypherParser::OC_MultiplyDivideModuloExpressionContext *ctx) override ; + + std::any visitOC_PowerOfExpression(CypherParser::OC_PowerOfExpressionContext *ctx) override ; + + std::any visitOC_UnaryAddOrSubtractExpression(CypherParser::OC_UnaryAddOrSubtractExpressionContext *ctx) override ; + + std::any visitOC_NonArithmeticOperatorExpression(CypherParser::OC_NonArithmeticOperatorExpressionContext *ctx) override ; + + std::any visitOC_ListOperatorExpression(CypherParser::OC_ListOperatorExpressionContext *ctx) override ; + + std::any visitOC_PropertyLookup(CypherParser::OC_PropertyLookupContext *ctx) override ; + + std::any visitOC_Atom(CypherParser::OC_AtomContext *ctx) override ; + + std::any visitOC_CaseExpression(CypherParser::OC_CaseExpressionContext *ctx) override ; + + std::any visitOC_CaseAlternative(CypherParser::OC_CaseAlternativeContext *ctx) override ; + + std::any visitOC_ListComprehension(CypherParser::OC_ListComprehensionContext *ctx) override ; + + std::any visitOC_PatternComprehension(CypherParser::OC_PatternComprehensionContext *ctx) override ; + + std::any visitOC_Quantifier(CypherParser::OC_QuantifierContext *ctx) override ; + + std::any visitOC_FilterExpression(CypherParser::OC_FilterExpressionContext *ctx) override ; + + std::any visitOC_PatternPredicate(CypherParser::OC_PatternPredicateContext *ctx) override ; + + std::any visitOC_ParenthesizedExpression(CypherParser::OC_ParenthesizedExpressionContext *ctx) override ; + + std::any visitOC_IdInColl(CypherParser::OC_IdInCollContext *ctx) override ; + + std::any visitOC_FunctionInvocation(CypherParser::OC_FunctionInvocationContext *ctx) override ; + + std::any visitOC_FunctionName(CypherParser::OC_FunctionNameContext *ctx) override ; + + std::any visitOC_ExistentialSubquery(CypherParser::OC_ExistentialSubqueryContext *ctx) override ; + + std::any visitOC_ExplicitProcedureInvocation(CypherParser::OC_ExplicitProcedureInvocationContext *ctx) override ; + + std::any visitOC_ImplicitProcedureInvocation(CypherParser::OC_ImplicitProcedureInvocationContext *ctx) override ; + + std::any visitOC_ProcedureResultField(CypherParser::OC_ProcedureResultFieldContext *ctx) override ; + + std::any visitOC_ProcedureName(CypherParser::OC_ProcedureNameContext *ctx) override ; + + std::any visitOC_Namespace(CypherParser::OC_NamespaceContext *ctx) override ; + + std::any visitOC_Variable(CypherParser::OC_VariableContext *ctx) override ; + + std::any visitOC_Literal(CypherParser::OC_LiteralContext *ctx) override ; + + std::any visitOC_BooleanLiteral(CypherParser::OC_BooleanLiteralContext *ctx) override ; + + std::any visitOC_NumberLiteral(CypherParser::OC_NumberLiteralContext *ctx) override ; + + std::any visitOC_IntegerLiteral(CypherParser::OC_IntegerLiteralContext *ctx) override ; + + std::any visitOC_DoubleLiteral(CypherParser::OC_DoubleLiteralContext *ctx) override ; + + std::any visitOC_ListLiteral(CypherParser::OC_ListLiteralContext *ctx) override ; + + std::any visitOC_MapLiteral(CypherParser::OC_MapLiteralContext *ctx) override ; + + std::any visitOC_PropertyKeyName(CypherParser::OC_PropertyKeyNameContext *ctx) override ; + + std::any visitOC_Parameter(CypherParser::OC_ParameterContext *ctx) override ; + + std::any visitOC_SchemaName(CypherParser::OC_SchemaNameContext *ctx) override ; + + std::any visitOC_ReservedWord(CypherParser::OC_ReservedWordContext *ctx) override ; + + std::any visitOC_SymbolicName(CypherParser::OC_SymbolicNameContext *ctx) override ; + + std::any visitOC_LeftArrowHead(CypherParser::OC_LeftArrowHeadContext *ctx) override ; + + std::any visitOC_RightArrowHead(CypherParser::OC_RightArrowHeadContext *ctx) override ; + +}; #endif //AST_BUILDER_H diff --git a/src/query/processor/cypher/astbuilder/ASTInternalNode.cpp b/src/query/processor/cypher/astbuilder/ASTInternalNode.cpp index 4c01043b..96abf638 100644 --- a/src/query/processor/cypher/astbuilder/ASTInternalNode.cpp +++ b/src/query/processor/cypher/astbuilder/ASTInternalNode.cpp @@ -1,5 +1,6 @@ -// -// Created by thamindu on 7/25/24. -// - #include "ASTInternalNode.h" + +void ASTInternalNode::addElements(ASTNode* element) +{ + elements.push_back(element); +} \ No newline at end of file diff --git a/src/query/processor/cypher/astbuilder/ASTInternalNode.h b/src/query/processor/cypher/astbuilder/ASTInternalNode.h index 38c80fcb..93c8dec2 100644 --- a/src/query/processor/cypher/astbuilder/ASTInternalNode.h +++ b/src/query/processor/cypher/astbuilder/ASTInternalNode.h @@ -1,7 +1,4 @@ -// -// Created by thamindu on 7/25/24. -// -#include "ASTStructure.h" +#include "ASTNode.h" #ifndef ASTINTERNALNODE_H #define ASTINTERNALNODE_H @@ -11,19 +8,12 @@ using namespace std; class ASTInternalNode : public ASTNode{ public: - ASTInternalNode(string nodeType) { this->nodeType = nodeType; } - void addElements(ASTNode* element) { - elements.push_back(element); - } - - + void addElements(ASTNode* element) ; }; - - #endif //ASTINTERNALNODE_H diff --git a/src/query/processor/cypher/astbuilder/ASTLeafNoValue.cpp b/src/query/processor/cypher/astbuilder/ASTLeafNoValue.cpp index a3cb7465..b359eb1c 100644 --- a/src/query/processor/cypher/astbuilder/ASTLeafNoValue.cpp +++ b/src/query/processor/cypher/astbuilder/ASTLeafNoValue.cpp @@ -1,5 +1 @@ -// -// Created by thamindu on 7/25/24. -// - #include "ASTLeafNoValue.h" diff --git a/src/query/processor/cypher/astbuilder/ASTLeafNoValue.h b/src/query/processor/cypher/astbuilder/ASTLeafNoValue.h index c1bd4b2b..650ccc4a 100644 --- a/src/query/processor/cypher/astbuilder/ASTLeafNoValue.h +++ b/src/query/processor/cypher/astbuilder/ASTLeafNoValue.h @@ -1,12 +1,7 @@ -// -// Created by thamindu on 7/25/24. -// -#include "ASTStructure.h" +#include "ASTNode.h" #ifndef ASTLEAFNOVALUE_H #define ASTLEAFNOVALUE_H - - class ASTLeafNoValue : public ASTNode { public: ASTLeafNoValue(const std::string& name) diff --git a/src/query/processor/cypher/astbuilder/ASTLeafValue.cpp b/src/query/processor/cypher/astbuilder/ASTLeafValue.cpp index cd21c3ef..76213243 100644 --- a/src/query/processor/cypher/astbuilder/ASTLeafValue.cpp +++ b/src/query/processor/cypher/astbuilder/ASTLeafValue.cpp @@ -1,5 +1 @@ -// -// Created by thamindu on 7/25/24. -// - #include "ASTLeafValue.h" diff --git a/src/query/processor/cypher/astbuilder/ASTLeafValue.h b/src/query/processor/cypher/astbuilder/ASTLeafValue.h index c44e85d0..c1a23fc7 100644 --- a/src/query/processor/cypher/astbuilder/ASTLeafValue.h +++ b/src/query/processor/cypher/astbuilder/ASTLeafValue.h @@ -1,12 +1,7 @@ -// -// Created by thamindu on 7/25/24. -// -#include "ASTStructure.h" +#include "ASTNode.h" #ifndef ASTLEAFVALUE_H #define ASTLEAFVALUE_H - - class ASTLeafValue : public ASTNode { public: @@ -18,6 +13,4 @@ class ASTLeafValue : public ASTNode { }; - - #endif //ASTLEAFVALUE_H diff --git a/src/query/processor/cypher/astbuilder/ASTNode.cpp b/src/query/processor/cypher/astbuilder/ASTNode.cpp new file mode 100644 index 00000000..1c1924c3 --- /dev/null +++ b/src/query/processor/cypher/astbuilder/ASTNode.cpp @@ -0,0 +1,25 @@ +#include "ASTNode.h" +#include +#include +#include + + +using namespace std; + +string ASTNode::print(int depth, string prefix, bool isLast) const +{ + stringstream ss; + + ss << prefix; + ss << (isLast ? "└───" : "├──"); + ss << nodeType << ": " << value << "\n"; + + string result = ss.str(); + prefix += (isLast ? " " : "│ "); + + for (size_t i = 0; i < elements.size(); ++i) { + result += elements[i]->print(depth + 1, prefix, i == elements.size() - 1); + } + + return result; +} diff --git a/src/query/processor/cypher/astbuilder/ASTNode.h b/src/query/processor/cypher/astbuilder/ASTNode.h new file mode 100644 index 00000000..0bc2609a --- /dev/null +++ b/src/query/processor/cypher/astbuilder/ASTNode.h @@ -0,0 +1,24 @@ +#include +#include + + +#ifndef AST_NODE_H +#define AST_NODE_H + +using namespace std; + +class ASTNode { + public: + string nodeType; + vector elements; + string value; + virtual ~ASTNode() = default; + + string print(int depth = 0, string prefix = "", bool isLast = true) const; + +}; + + + + +#endif diff --git a/src/query/processor/cypher/astbuilder/ASTStructure.cpp b/src/query/processor/cypher/astbuilder/ASTStructure.cpp deleted file mode 100644 index eb003bad..00000000 --- a/src/query/processor/cypher/astbuilder/ASTStructure.cpp +++ /dev/null @@ -1,5 +0,0 @@ -// -// Created by thamindu on 7/24/24. -// - -#include "ASTStructure.h" diff --git a/src/query/processor/cypher/astbuilder/ASTStructure.h b/src/query/processor/cypher/astbuilder/ASTStructure.h deleted file mode 100644 index d346e363..00000000 --- a/src/query/processor/cypher/astbuilder/ASTStructure.h +++ /dev/null @@ -1,42 +0,0 @@ -// -// Created by thamindu on 7/24/24. -// -#include -#include -#include -#include -#ifndef AST_STRUCTURE_H -#define AST_STRUCTURE_H - -using namespace std; - -class ASTNode { - public: - string nodeType; - vector elements; - string value; - virtual ~ASTNode() = default; - - string print(int depth = 0, string prefix = "", bool isLast = true) const { - stringstream ss; - - ss << prefix; - ss << (isLast ? "└───" : "├──"); - ss << nodeType << ": " << value << endl; - - string result = ss.str(); - prefix += isLast ? " " : "│ "; - - for (size_t i = 0; i < elements.size(); ++i) { - result += elements[i]->print(depth + 1, prefix, i == elements.size() - 1); - } - - return result; - } - -}; - - - - -#endif //AST_STRUCTURE_H From 6878eb981882a798af779d35aaa7c85256b768db Mon Sep 17 00:00:00 2001 From: thamindu Date: Sat, 17 Aug 2024 11:28:44 +0530 Subject: [PATCH 3/5] add feature cypher ast --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 86cc57af..d3292a15 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM pre:latest +FROM miyurud/jasminegraph-prerequisites:20240101T095619 RUN apt-get update && apt-get install -y libcurl4-openssl-dev sysstat nmon RUN rm -r /usr/lib/python3.8/distutils From ab5e605bb1e8a65adada7f5cd399dc49fcc6b3c3 Mon Sep 17 00:00:00 2001 From: thamindu Date: Fri, 23 Aug 2024 22:23:17 +0530 Subject: [PATCH 4/5] add license and print ast in logger --- src/frontend/JasmineGraphFrontEnd.cpp | 6 +----- .../processor/cypher/astbuilder/ASTBuilder.cpp | 14 ++++++++++++++ src/query/processor/cypher/astbuilder/ASTBuilder.h | 13 +++++++++++++ .../cypher/astbuilder/ASTInternalNode.cpp | 13 +++++++++++++ .../processor/cypher/astbuilder/ASTInternalNode.h | 13 +++++++++++++ .../processor/cypher/astbuilder/ASTLeafNoValue.cpp | 13 +++++++++++++ .../processor/cypher/astbuilder/ASTLeafNoValue.h | 13 +++++++++++++ .../processor/cypher/astbuilder/ASTLeafValue.cpp | 13 +++++++++++++ .../processor/cypher/astbuilder/ASTLeafValue.h | 13 +++++++++++++ src/query/processor/cypher/astbuilder/ASTNode.cpp | 13 +++++++++++++ src/query/processor/cypher/astbuilder/ASTNode.h | 13 +++++++++++++ 11 files changed, 132 insertions(+), 5 deletions(-) diff --git a/src/frontend/JasmineGraphFrontEnd.cpp b/src/frontend/JasmineGraphFrontEnd.cpp index e25af4de..f4fd8111 100644 --- a/src/frontend/JasmineGraphFrontEnd.cpp +++ b/src/frontend/JasmineGraphFrontEnd.cpp @@ -672,11 +672,7 @@ static void cypher_ast_command(int connFd, bool *loop_exit) ASTBuilder ast_builder; auto* ast = any_cast(ast_builder.visitOC_Cypher(parser.oC_Cypher())); string result = ast->print(1); - int result_wrn = write(connFd, result.c_str(), result.length()); - if (result_wrn < 0) { - frontend_logger.error("Error writing to socket"); - *loop_exit = true; - } + frontend_logger.log(result, "log"); } static void add_rdf_command(std::string masterIP, int connFd, SQLiteDBInterface *sqlite, bool *loop_exit_p) { diff --git a/src/query/processor/cypher/astbuilder/ASTBuilder.cpp b/src/query/processor/cypher/astbuilder/ASTBuilder.cpp index f7af1548..ba93184d 100644 --- a/src/query/processor/cypher/astbuilder/ASTBuilder.cpp +++ b/src/query/processor/cypher/astbuilder/ASTBuilder.cpp @@ -1,3 +1,17 @@ +/** +Copyright 2024 JasmineGraph Team +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + */ + + #include "ASTBuilder.h" #include #include diff --git a/src/query/processor/cypher/astbuilder/ASTBuilder.h b/src/query/processor/cypher/astbuilder/ASTBuilder.h index 794deaa0..8aa575d0 100644 --- a/src/query/processor/cypher/astbuilder/ASTBuilder.h +++ b/src/query/processor/cypher/astbuilder/ASTBuilder.h @@ -1,3 +1,16 @@ +/** +Copyright 2024 JasmineGraph Team +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + */ + #include #include "/home/ubuntu/software/jasminegraph/code_generated/antlr/CypherBaseVisitor.h" #ifndef AST_BUILDER_H diff --git a/src/query/processor/cypher/astbuilder/ASTInternalNode.cpp b/src/query/processor/cypher/astbuilder/ASTInternalNode.cpp index 96abf638..aa614e66 100644 --- a/src/query/processor/cypher/astbuilder/ASTInternalNode.cpp +++ b/src/query/processor/cypher/astbuilder/ASTInternalNode.cpp @@ -1,3 +1,16 @@ +/** +Copyright 2024 JasmineGraph Team +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + */ + #include "ASTInternalNode.h" void ASTInternalNode::addElements(ASTNode* element) diff --git a/src/query/processor/cypher/astbuilder/ASTInternalNode.h b/src/query/processor/cypher/astbuilder/ASTInternalNode.h index 93c8dec2..f43eb942 100644 --- a/src/query/processor/cypher/astbuilder/ASTInternalNode.h +++ b/src/query/processor/cypher/astbuilder/ASTInternalNode.h @@ -1,3 +1,16 @@ +/** +Copyright 2024 JasmineGraph Team +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + */ + #include "ASTNode.h" #ifndef ASTINTERNALNODE_H diff --git a/src/query/processor/cypher/astbuilder/ASTLeafNoValue.cpp b/src/query/processor/cypher/astbuilder/ASTLeafNoValue.cpp index b359eb1c..973a01ac 100644 --- a/src/query/processor/cypher/astbuilder/ASTLeafNoValue.cpp +++ b/src/query/processor/cypher/astbuilder/ASTLeafNoValue.cpp @@ -1 +1,14 @@ +/** +Copyright 2024 JasmineGraph Team +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + */ + #include "ASTLeafNoValue.h" diff --git a/src/query/processor/cypher/astbuilder/ASTLeafNoValue.h b/src/query/processor/cypher/astbuilder/ASTLeafNoValue.h index 650ccc4a..64fa4505 100644 --- a/src/query/processor/cypher/astbuilder/ASTLeafNoValue.h +++ b/src/query/processor/cypher/astbuilder/ASTLeafNoValue.h @@ -1,3 +1,16 @@ +/** +Copyright 2024 JasmineGraph Team +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + */ + #include "ASTNode.h" #ifndef ASTLEAFNOVALUE_H #define ASTLEAFNOVALUE_H diff --git a/src/query/processor/cypher/astbuilder/ASTLeafValue.cpp b/src/query/processor/cypher/astbuilder/ASTLeafValue.cpp index 76213243..c058c74e 100644 --- a/src/query/processor/cypher/astbuilder/ASTLeafValue.cpp +++ b/src/query/processor/cypher/astbuilder/ASTLeafValue.cpp @@ -1 +1,14 @@ +/** +Copyright 2024 JasmineGraph Team +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + */ + #include "ASTLeafValue.h" diff --git a/src/query/processor/cypher/astbuilder/ASTLeafValue.h b/src/query/processor/cypher/astbuilder/ASTLeafValue.h index c1a23fc7..5fd854af 100644 --- a/src/query/processor/cypher/astbuilder/ASTLeafValue.h +++ b/src/query/processor/cypher/astbuilder/ASTLeafValue.h @@ -1,3 +1,16 @@ +/** +Copyright 2024 JasmineGraph Team +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + */ + #include "ASTNode.h" #ifndef ASTLEAFVALUE_H #define ASTLEAFVALUE_H diff --git a/src/query/processor/cypher/astbuilder/ASTNode.cpp b/src/query/processor/cypher/astbuilder/ASTNode.cpp index 1c1924c3..29a447e9 100644 --- a/src/query/processor/cypher/astbuilder/ASTNode.cpp +++ b/src/query/processor/cypher/astbuilder/ASTNode.cpp @@ -1,3 +1,16 @@ +/** +Copyright 2024 JasmineGraph Team +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + */ + #include "ASTNode.h" #include #include diff --git a/src/query/processor/cypher/astbuilder/ASTNode.h b/src/query/processor/cypher/astbuilder/ASTNode.h index 0bc2609a..9ca48420 100644 --- a/src/query/processor/cypher/astbuilder/ASTNode.h +++ b/src/query/processor/cypher/astbuilder/ASTNode.h @@ -1,3 +1,16 @@ +/** +Copyright 2024 JasmineGraph Team +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + */ + #include #include From 6a86ee4b255c78848cc0b4427c2e9ceb689ab80b Mon Sep 17 00:00:00 2001 From: thamindu Date: Wed, 28 Aug 2024 19:52:41 +0530 Subject: [PATCH 5/5] fix issue on a TODO comment --- .../cypher/astbuilder/ASTBuilder.cpp | 52 ++++++++++++------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/src/query/processor/cypher/astbuilder/ASTBuilder.cpp b/src/query/processor/cypher/astbuilder/ASTBuilder.cpp index ba93184d..a3fc2a77 100644 --- a/src/query/processor/cypher/astbuilder/ASTBuilder.cpp +++ b/src/query/processor/cypher/astbuilder/ASTBuilder.cpp @@ -301,30 +301,42 @@ any ASTBuilder::visitOC_SinglePartQuery(CypherParser::OC_SinglePartQueryContext } -//TODO: try to solve a efficient way - -any ASTBuilder::visitOC_MultiPartQuery(CypherParser::OC_MultiPartQueryContext *ctx) { - auto *node = new ASTInternalNode("MULTIPLE_QUERY"); - for(CypherParser::OC_WithContext* withElement : ctx->oC_With()) - { - size_t const with = withElement->getStart()->getTokenIndex(); - for(CypherParser::OC_ReadingClauseContext* element : ctx->oC_ReadingClause()) - { - if(element->getStop()->getTokenIndex() < with) - { - node->addElements(any_cast(visitOC_ReadingClause(element))); +any ASTBuilder::visitOC_MultiPartQuery(CypherParser::OC_MultiPartQueryContext *ctx) { + auto *node = new ASTInternalNode("MULTI_PART_QUERY"); + auto *newNode = new ASTInternalNode("SINGLE_QUERY"); + + int withIndex = 0; + int readIndex = 0; + int updateIndex = 0; + + for (int i = 0; i < ctx->children.size(); i++) { + auto *child = ctx->children[i]; + string typeName = typeid(*child).name(); + string grammarName = typeName.substr(17); + + if (i + 1 < ctx->children.size()) { + auto *nextChild = ctx->children[i + 1]; + string nextTypeName = typeid(*nextChild).name(); + string nextGrammarName = nextTypeName.substr(17); + + if (grammarName == "OC_WithContextE" && nextGrammarName == "OC_SinglePartQueryContextE") { + newNode->addElements(any_cast(visitOC_With(ctx->oC_With(withIndex++)))); + node->addElements(newNode); + break; + } else if (grammarName == "OC_WithContextE") { + newNode->addElements(any_cast(visitOC_With(ctx->oC_With(withIndex++)))); + node->addElements(newNode); + newNode = new ASTInternalNode("SINGLE_QUERY"); + } else if (grammarName == "OC_ReadingClauseContextE") { + newNode->addElements(any_cast(visitOC_ReadingClause(ctx->oC_ReadingClause(readIndex++)))); + } else if (grammarName == "OC_UpdatingClauseContextE") { + newNode->addElements(any_cast(visitOC_UpdatingClause(ctx->oC_UpdatingClause(updateIndex++)))); } } - for(CypherParser::OC_UpdatingClauseContext* element : ctx->oC_UpdatingClause()) - { - if(element->getStop()->getTokenIndex() < with) - { - node->addElements(any_cast(visitOC_UpdatingClause(element))); - } - - } } + node->addElements(any_cast(visitOC_SinglePartQuery(ctx->oC_SinglePartQuery()))); + return static_cast(node); }