diff --git a/docker-compose.arm64.yml b/docker-compose.arm64.yml
index a71fee4..feda6f9 100755
--- a/docker-compose.arm64.yml
+++ b/docker-compose.arm64.yml
@@ -6,11 +6,11 @@ services:
args:
EMBED_MODEL: "true" # Include bge-m3.gguf in image
tags:
- - timothyswt/nornicdb-arm64-metal-bge:latest
- image: timothyswt/nornicdb-arm64-metal-bge:latest
+ - timothyswt/nornicdb-arm64-metal-bge-heimdall:latest
+ image: timothyswt/nornicdb-arm64-metal-bge-heimdall:latest
container_name: nornicdb
volumes:
- - ./data/nornicdb:/data
+ - ./data/welcome-season:/data
ports:
- "7474:7474" # HTTP API & Browser UI
- "7687:7687" # Bolt protocol (Neo4j compatible)
@@ -18,11 +18,16 @@ services:
- NORNICDB_DATA_DIR=/data
- NORNICDB_HTTP_PORT=7474
- NORNICDB_BOLT_PORT=7687
+ - NORNICDB_EXECUTOR_MODE=nornic
+ # - NORNICDB_HEIMDALL_ENABLED=true
# Embedding configuration - llama.cpp OpenAI-compatible API
- NORNICDB_EMBEDDING_PROVIDER=local
- NORNICDB_NO_AUTH=${NORNICDB_NO_AUTH:-true}
- NORNICDB_ADMIN_PASSWORD=${NEO4J_PASSWORD:-password}
- GOGC=50
+ # Memory management - use low-memory mode for containers
+ # - NORNICDB_LOW_MEMORY=true
+ # - GOGC=100
restart: unless-stopped
healthcheck:
test:
@@ -33,197 +38,357 @@ services:
start_period: 10s
networks:
- mcp_network
- deploy:
- resources:
- limits:
- memory: 1GB
- reservations:
- memory: 256M
- copilot-api:
- image: timothyswt/copilot-api-arm64:latest
- container_name: copilot_api_server
- ports:
- - "4141:4141" # Fixed: copilot-api listens on 4141, not 3000
- volumes:
- - ./copilot-data:/root/.local/share/copilot-api # Persist GitHub token
- environment:
- - NODE_ENV=production
- # Remove PORT=3000, the app uses 4141 by default
- restart: unless-stopped
- healthcheck:
- # Use CMD-SHELL so shell operators (||) work and allow a proper HTTP probe
- test: ["CMD-SHELL", "wget --spider -q http://localhost:4141/ || exit 1"]
- interval: 30s
- timeout: 10s
- retries: 5
- start_period: 15s
- networks:
- - mcp_network
+ # copilot-api:
+ # image: timothyswt/copilot-api-arm64:latest
+ # container_name: copilot_api_server
+ # ports:
+ # - "4141:4141" # Fixed: copilot-api listens on 4141, not 3000
+ # volumes:
+ # - ./copilot-data:/root/.local/share/copilot-api # Persist GitHub token
+ # environment:
+ # - NODE_ENV=production
+ # # Remove PORT=3000, the app uses 4141 by default
+ # restart: unless-stopped
+ # healthcheck:
+ # # Use CMD-SHELL so shell operators (||) work and allow a proper HTTP probe
+ # test: ["CMD-SHELL", "wget --spider -q http://localhost:4141/ || exit 1"]
+ # interval: 30s
+ # timeout: 10s
+ # retries: 5
+ # start_period: 15s
+ # networks:
+ # - mcp_network
+ # copilot-api:
+ # image: timothyswt/copilot-api-arm64:latest
+ # container_name: copilot_api_server
+ # ports:
+ # - "4141:4141" # Fixed: copilot-api listens on 4141, not 3000
+ # volumes:
+ # - ./copilot-data:/root/.local/share/copilot-api # Persist GitHub token
+ # environment:
+ # - NODE_ENV=production
+ # # Remove PORT=3000, the app uses 4141 by default
+ # restart: unless-stopped
+ # healthcheck:
+ # # Use CMD-SHELL so shell operators (||) work and allow a proper HTTP probe
+ # test: ["CMD-SHELL", "wget --spider -q http://localhost:4141/ || exit 1"]
+ # interval: 30s
+ # timeout: 10s
+ # retries: 5
+ # start_period: 15s
+ # networks:
+ # - mcp_network
# Vision-Language server for multimodal embeddings (images + text)
# Uncomment to enable image embeddings, or swap with llama-server above
- llama-vl-server:
- image: timothyswt/llama-cpp-server-arm64-qwen2.5-vl-7b:latest
- container_name: llama_vl_server
- ports:
- - "11435:8080" # Different external port: 11435 -> Internal 8080
- environment:
- # Server Configuration
- - LLAMA_ARG_HOST=0.0.0.0
- - LLAMA_ARG_PORT=8080
- - LLAMA_ARG_CTX_SIZE=8192
- - LLAMA_ARG_N_PARALLEL=4
+ # llama-vl-server:
+ # image: timothyswt/llama-cpp-server-arm64-qwen2.5-vl-7b:latest
+ # container_name: llama_vl_server
+ # ports:
+ # - "11435:8080" # Different external port: 11435 -> Internal 8080
+ # environment:
+ # # Server Configuration
+ # - LLAMA_ARG_HOST=0.0.0.0
+ # - LLAMA_ARG_PORT=8080
+ # - LLAMA_ARG_CTX_SIZE=8192
+ # - LLAMA_ARG_N_PARALLEL=4
+ # llama-vl-server:
+ # image: timothyswt/llama-cpp-server-arm64-qwen2.5-vl-7b:latest
+ # container_name: llama_vl_server
+ # ports:
+ # - "11435:8080" # Different external port: 11435 -> Internal 8080
+ # environment:
+ # # Server Configuration
+ # - LLAMA_ARG_HOST=0.0.0.0
+ # - LLAMA_ARG_PORT=8080
+ # - LLAMA_ARG_CTX_SIZE=8192
+ # - LLAMA_ARG_N_PARALLEL=4
- # Embeddings-specific
- - LLAMA_ARG_EMBEDDINGS=true
- - LLAMA_ARG_POOLING=mean
+ # # Embeddings-specific
+ # - LLAMA_ARG_EMBEDDINGS=true
+ # - LLAMA_ARG_POOLING=mean
+ # # Embeddings-specific
+ # - LLAMA_ARG_EMBEDDINGS=true
+ # - LLAMA_ARG_POOLING=mean
- # Performance
- - LLAMA_ARG_THREADS=-1
- - LLAMA_ARG_NO_MMAP=false
- restart: unless-stopped
- healthcheck:
- test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
- interval: 30s
- timeout: 10s
- retries: 3
- start_period: 30s
- networks:
- - mcp_network
- mimir-server:
- build:
- context: .
- dockerfile: Dockerfile
- tags:
- - timothyswt/mimir-server:latest
- image: timothyswt/mimir-server:latest
- container_name: mimir_server
- restart: unless-stopped
- environment:
- # Database Configuration
- - NEO4J_URI=bolt://nornicdb:7687
- - NEO4J_USER=admin
- - NEO4J_PASSWORD=${NEO4J_PASSWORD:-admin}
-
- # Server Configuration
- - NODE_ENV=production
- - PORT=3000
- # - NODE_TLS_REJECT_UNAUTHORIZED=${NODE_TLS_REJECT_UNAUTHORIZED:-1}
-
- # Workspace Configuration
- - WORKSPACE_ROOT=/workspace
- - HOST_WORKSPACE_ROOT=${HOST_WORKSPACE_ROOT:-~/src} # Pass through from host
- - HOST_HOME=${HOME} # Host's home directory for expanding ~ in HOST_WORKSPACE_ROOT
-
- # LLM API Configuration
- - MIMIR_DEFAULT_PROVIDER=${MIMIR_DEFAULT_PROVIDER:-copilot}
- - MIMIR_LLM_API=${MIMIR_LLM_API:-http://copilot-api:4141}
- - MIMIR_LLM_API_PATH=${MIMIR_LLM_API_PATH:-/v1/chat/completions}
- - MIMIR_LLM_API_MODELS_PATH=${MIMIR_LLM_API_MODELS_PATH:-/v1/models}
- - MIMIR_LLM_API_KEY=${MIMIR_LLM_API_KEY:-dummy-key}
-
- # Provider and Model Configuration (100% dynamic - no config file needed)
- - MIMIR_DEFAULT_MODEL=${MIMIR_DEFAULT_MODEL:-gpt-4.1}
-
- # Per-Agent Model Configuration (optional overrides)
- - MIMIR_PM_MODEL=${MIMIR_PM_MODEL:-}
- - MIMIR_WORKER_MODEL=${MIMIR_WORKER_MODEL:-}
- - MIMIR_QC_MODEL=${MIMIR_QC_MODEL:-}
-
- # Context Window Configuration
- - MIMIR_DEFAULT_CONTEXT_WINDOW=${MIMIR_DEFAULT_CONTEXT_WINDOW:-128000}
-
- # Image/VL Embeddings Configuration (Vision-Language models)
- # Image Embeddings Control (disabled by default for safety)
- - MIMIR_EMBEDDINGS_IMAGES=${MIMIR_EMBEDDINGS_IMAGES:-true} # Default: disabled
- - MIMIR_EMBEDDINGS_IMAGES_DESCRIBE_MODE=${MIMIR_EMBEDDINGS_IMAGES_DESCRIBE_MODE:-true} # Default: VL description mode
- # Qwen2.5-VL Configuration (for llama.cpp server)
- - MIMIR_EMBEDDINGS_VL_PROVIDER=${MIMIR_EMBEDDINGS_VL_PROVIDER:-llama.cpp}
- - MIMIR_EMBEDDINGS_VL_API=${MIMIR_EMBEDDINGS_VL_API:-http://llama-vl-server:8080}
- - MIMIR_EMBEDDINGS_VL_API_PATH=${MIMIR_EMBEDDINGS_VL_API_PATH:-/v1/chat/completions}
- - MIMIR_EMBEDDINGS_VL_API_KEY=${MIMIR_EMBEDDINGS_VL_API_KEY:-dummy-key}
- - MIMIR_EMBEDDINGS_VL_MODEL=${MIMIR_EMBEDDINGS_VL_MODEL:-qwen2.5-vl}
- - MIMIR_EMBEDDINGS_VL_CONTEXT_SIZE=${MIMIR_EMBEDDINGS_VL_CONTEXT_SIZE:-131072} # 128K tokens (7b/72b)
- - MIMIR_EMBEDDINGS_VL_MAX_TOKENS=${MIMIR_EMBEDDINGS_VL_MAX_TOKENS:-2048} # Max description length
- - MIMIR_EMBEDDINGS_VL_TEMPERATURE=${MIMIR_EMBEDDINGS_VL_TEMPERATURE:-0.7}
- - MIMIR_EMBEDDINGS_VL_DIMENSIONS=${MIMIR_EMBEDDINGS_VL_DIMENSIONS:-768} # Falls back to text model dims
- - MIMIR_EMBEDDINGS_VL_TIMEOUT=${MIMIR_EMBEDDINGS_VL_TIMEOUT:-180000} # 3 minutes (VL processing is slow)
- # Indexing Configuration
- - MIMIR_INDEXING_THREADS=${MIMIR_INDEXING_THREADS:-1}
-
- # Feature Flags
- - MIMIR_FEATURE_PM_MODEL_SUGGESTIONS=${MIMIR_FEATURE_PM_MODEL_SUGGESTIONS:-true}
- - MIMIR_AUTO_INDEX_DOCS=${MIMIR_AUTO_INDEX_DOCS:-true}
-
- # Agent Execution Limits
- - MIMIR_AGENT_RECURSION_LIMIT=${MIMIR_AGENT_RECURSION_LIMIT:-100}
-
- # Security Configuration
- - MIMIR_ENABLE_SECURITY=${MIMIR_ENABLE_SECURITY:-false}
- - MIMIR_DEV_USER_ADMIN=${MIMIR_DEV_USER_ADMIN}
- - MIMIR_DEV_USER_DEVELOPER=${MIMIR_DEV_USER_DEVELOPER}
- - MIMIR_DEV_USER_ANALYST=${MIMIR_DEV_USER_ANALYST}
- - MIMIR_DEV_USER_VIEWER=${MIMIR_DEV_USER_VIEWER}
- - MIMIR_JWT_SECRET=${MIMIR_JWT_SECRET}
- # OAuth Configuration (explicit endpoint URLs - provider-specific)
- - MIMIR_AUTH_PROVIDER=${MIMIR_AUTH_PROVIDER}
- - MIMIR_OAUTH_AUTHORIZATION_URL=${MIMIR_OAUTH_AUTHORIZATION_URL} # Full authorization endpoint URL
- - MIMIR_OAUTH_TOKEN_URL=${MIMIR_OAUTH_TOKEN_URL} # Full token endpoint URL
- - MIMIR_OAUTH_USERINFO_URL=${MIMIR_OAUTH_USERINFO_URL} # Full userinfo endpoint URL
- - MIMIR_OAUTH_CLIENT_ID=${MIMIR_OAUTH_CLIENT_ID}
- - MIMIR_OAUTH_CLIENT_SECRET=${MIMIR_OAUTH_CLIENT_SECRET}
- - MIMIR_OAUTH_CALLBACK_URL=${MIMIR_OAUTH_CALLBACK_URL}
- - MIMIR_OAUTH_ALLOW_HTTP=${MIMIR_OAUTH_ALLOW_HTTP}
-
- # Advanced Configuration
- - MIMIR_PARALLEL_EXECUTION=${MIMIR_PARALLEL_EXECUTION:-false}
- - MIMIR_INSTALL_DIR=${MIMIR_INSTALL_DIR:-/app}
- - MIMIR_AGENTS_DIR=${MIMIR_AGENTS_DIR:-/app/docs/agents}
- # Embeddings API Configuration
-
- # - MIMIR_EMBEDDINGS_PROVIDER=${MIMIR_EMBEDDINGS_PROVIDER:-openai}
- # - MIMIR_EMBEDDINGS_API=${MIMIR_EMBEDDINGS_API:-http://llama-server:8080}
- # - MIMIR_EMBEDDINGS_API_PATH=${MIMIR_EMBEDDINGS_API_PATH:-/v1/embeddings}
- # - MIMIR_EMBEDDINGS_API_MODELS_PATH=${MIMIR_EMBEDDINGS_API_MODELS_PATH:-/v1/models}
- # - MIMIR_EMBEDDINGS_API_KEY=${MIMIR_EMBEDDINGS_API_KEY:-dummy-key}
- # Embeddings Configuration
- # - MIMIR_EMBEDDINGS_ENABLED=${MIMIR_EMBEDDINGS_ENABLED:-true}
- # - MIMIR_EMBEDDINGS_MODEL=${MIMIR_EMBEDDINGS_MODEL:-bge-m3}
- # - MIMIR_EMBEDDINGS_DIMENSIONS=${MIMIR_EMBEDDINGS_DIMENSIONS:-1024}
- # - MIMIR_EMBEDDINGS_CHUNK_SIZE=${MIMIR_EMBEDDINGS_CHUNK_SIZE:-768}
- # - MIMIR_EMBEDDINGS_CHUNK_OVERLAP=${MIMIR_EMBEDDINGS_CHUNK_OVERLAP:-100}
- # - MIMIR_EMBEDDINGS_DELAY_MS=${MIMIR_EMBEDDINGS_DELAY_MS:-0}
- # - MIMIR_EMBEDDINGS_MAX_RETRIES=${MIMIR_EMBEDDINGS_MAX_RETRIES:-3}
-
-
- # PCTX Integration (Code Mode for 90-98% token reduction)
- - PCTX_URL=${PCTX_URL:-http://host.docker.internal:8080}
- - PCTX_ENABLED=${PCTX_ENABLED:-false}
+ # # Performance
+ # - LLAMA_ARG_THREADS=-1
+ # - LLAMA_ARG_NO_MMAP=false
+ # restart: unless-stopped
+ # healthcheck:
+ # test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
+ # interval: 30s
+ # timeout: 10s
+ # retries: 3
+ # start_period: 30s
+ # networks:
+ # - mcp_network
+ # mimir-server:
+ # build:
+ # context: .
+ # dockerfile: Dockerfile
+ # tags:
+ # - timothyswt/mimir-server:latest
+ # image: timothyswt/mimir-server:latest
+ # container_name: mimir_server
+ # restart: unless-stopped
+ # environment:
+ # # Database Configuration
+ # - NEO4J_URI=bolt://nornicdb:7687
+ # - NEO4J_USER=admin
+ # - NEO4J_PASSWORD=${NEO4J_PASSWORD:-admin}
+ # # Performance
+ # - LLAMA_ARG_THREADS=-1
+ # - LLAMA_ARG_NO_MMAP=false
+ # restart: unless-stopped
+ # healthcheck:
+ # test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
+ # interval: 30s
+ # timeout: 10s
+ # retries: 3
+ # start_period: 30s
+ # networks:
+ # - mcp_network
+ # mimir-server:
+ # build:
+ # context: .
+ # dockerfile: Dockerfile
+ # tags:
+ # - timothyswt/mimir-server:latest
+ # image: timothyswt/mimir-server:latest
+ # container_name: mimir_server
+ # restart: unless-stopped
+ # environment:
+ # # Database Configuration
+ # - NEO4J_URI=bolt://nornicdb:7687
+ # - NEO4J_USER=admin
+ # - NEO4J_PASSWORD=${NEO4J_PASSWORD:-admin}
- volumes:
- - ./data:/app/data
- - ./logs:/app/logs
- - ${HOST_WORKSPACE_ROOT:-~/src}:${WORKSPACE_ROOT:-/workspace}
- ports:
- - "9042:3000"
- healthcheck:
- test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000/health', (res) => process.exit(res.statusCode === 200 ? 0 : 1)).on('error', () => process.exit(1))"]
- interval: 30s
- timeout: 10s
- retries: 3
- start_period: 10s
- depends_on:
- # neo4j:
- # condition: service_healthy
- nornicdb:
- condition: service_healthy
- copilot-api:
- condition: service_healthy
- # llama-server:
- # condition: service_healthy
- # llama-vl-server:
- # condition: service_healthy
- networks:
- - mcp_network
+ # # Server Configuration
+ # - NODE_ENV=production
+ # - PORT=3000
+ # # - NODE_TLS_REJECT_UNAUTHORIZED=${NODE_TLS_REJECT_UNAUTHORIZED:-1}
+ # # Server Configuration
+ # - NODE_ENV=production
+ # - PORT=3000
+ # # - NODE_TLS_REJECT_UNAUTHORIZED=${NODE_TLS_REJECT_UNAUTHORIZED:-1}
+
+ # # Workspace Configuration
+ # - WORKSPACE_ROOT=/workspace
+ # - HOST_WORKSPACE_ROOT=${HOST_WORKSPACE_ROOT:-~/src} # Pass through from host
+ # - HOST_HOME=${HOME} # Host's home directory for expanding ~ in HOST_WORKSPACE_ROOT
+ # # Workspace Configuration
+ # - WORKSPACE_ROOT=/workspace
+ # - HOST_WORKSPACE_ROOT=${HOST_WORKSPACE_ROOT:-~/src} # Pass through from host
+ # - HOST_HOME=${HOME} # Host's home directory for expanding ~ in HOST_WORKSPACE_ROOT
+
+ # # LLM API Configuration
+ # - MIMIR_DEFAULT_PROVIDER=${MIMIR_DEFAULT_PROVIDER:-copilot}
+ # - MIMIR_LLM_API=${MIMIR_LLM_API:-http://copilot-api:4141}
+ # - MIMIR_LLM_API_PATH=${MIMIR_LLM_API_PATH:-/v1/chat/completions}
+ # - MIMIR_LLM_API_MODELS_PATH=${MIMIR_LLM_API_MODELS_PATH:-/v1/models}
+ # - MIMIR_LLM_API_KEY=${MIMIR_LLM_API_KEY:-dummy-key}
+ # # LLM API Configuration
+ # - MIMIR_DEFAULT_PROVIDER=${MIMIR_DEFAULT_PROVIDER:-copilot}
+ # - MIMIR_LLM_API=${MIMIR_LLM_API:-http://copilot-api:4141}
+ # - MIMIR_LLM_API_PATH=${MIMIR_LLM_API_PATH:-/v1/chat/completions}
+ # - MIMIR_LLM_API_MODELS_PATH=${MIMIR_LLM_API_MODELS_PATH:-/v1/models}
+ # - MIMIR_LLM_API_KEY=${MIMIR_LLM_API_KEY:-dummy-key}
+
+ # # Provider and Model Configuration (100% dynamic - no config file needed)
+ # - MIMIR_DEFAULT_MODEL=${MIMIR_DEFAULT_MODEL:-gpt-4.1}
+ # # Provider and Model Configuration (100% dynamic - no config file needed)
+ # - MIMIR_DEFAULT_MODEL=${MIMIR_DEFAULT_MODEL:-gpt-4.1}
+
+ # # Per-Agent Model Configuration (optional overrides)
+ # - MIMIR_PM_MODEL=${MIMIR_PM_MODEL:-}
+ # - MIMIR_WORKER_MODEL=${MIMIR_WORKER_MODEL:-}
+ # - MIMIR_QC_MODEL=${MIMIR_QC_MODEL:-}
+ # # Per-Agent Model Configuration (optional overrides)
+ # - MIMIR_PM_MODEL=${MIMIR_PM_MODEL:-}
+ # - MIMIR_WORKER_MODEL=${MIMIR_WORKER_MODEL:-}
+ # - MIMIR_QC_MODEL=${MIMIR_QC_MODEL:-}
+
+ # # Context Window Configuration
+ # - MIMIR_DEFAULT_CONTEXT_WINDOW=${MIMIR_DEFAULT_CONTEXT_WINDOW:-128000}
+ # # Context Window Configuration
+ # - MIMIR_DEFAULT_CONTEXT_WINDOW=${MIMIR_DEFAULT_CONTEXT_WINDOW:-128000}
+
+ # # Image/VL Embeddings Configuration (Vision-Language models)
+ # # Image Embeddings Control (disabled by default for safety)
+ # - MIMIR_EMBEDDINGS_IMAGES=${MIMIR_EMBEDDINGS_IMAGES:-true} # Default: disabled
+ # - MIMIR_EMBEDDINGS_IMAGES_DESCRIBE_MODE=${MIMIR_EMBEDDINGS_IMAGES_DESCRIBE_MODE:-true} # Default: VL description mode
+ # # Qwen2.5-VL Configuration (for llama.cpp server)
+ # - MIMIR_EMBEDDINGS_VL_PROVIDER=${MIMIR_EMBEDDINGS_VL_PROVIDER:-llama.cpp}
+ # - MIMIR_EMBEDDINGS_VL_API=${MIMIR_EMBEDDINGS_VL_API:-http://llama-vl-server:8080}
+ # - MIMIR_EMBEDDINGS_VL_API_PATH=${MIMIR_EMBEDDINGS_VL_API_PATH:-/v1/chat/completions}
+ # - MIMIR_EMBEDDINGS_VL_API_KEY=${MIMIR_EMBEDDINGS_VL_API_KEY:-dummy-key}
+ # - MIMIR_EMBEDDINGS_VL_MODEL=${MIMIR_EMBEDDINGS_VL_MODEL:-qwen2.5-vl}
+ # - MIMIR_EMBEDDINGS_VL_CONTEXT_SIZE=${MIMIR_EMBEDDINGS_VL_CONTEXT_SIZE:-131072} # 128K tokens (7b/72b)
+ # - MIMIR_EMBEDDINGS_VL_MAX_TOKENS=${MIMIR_EMBEDDINGS_VL_MAX_TOKENS:-2048} # Max description length
+ # - MIMIR_EMBEDDINGS_VL_TEMPERATURE=${MIMIR_EMBEDDINGS_VL_TEMPERATURE:-0.7}
+ # - MIMIR_EMBEDDINGS_VL_DIMENSIONS=${MIMIR_EMBEDDINGS_VL_DIMENSIONS:-768} # Falls back to text model dims
+ # - MIMIR_EMBEDDINGS_VL_TIMEOUT=${MIMIR_EMBEDDINGS_VL_TIMEOUT:-180000} # 3 minutes (VL processing is slow)
+ # # Indexing Configuration
+ # - MIMIR_INDEXING_THREADS=${MIMIR_INDEXING_THREADS:-1}
+ # # Image/VL Embeddings Configuration (Vision-Language models)
+ # # Image Embeddings Control (disabled by default for safety)
+ # - MIMIR_EMBEDDINGS_IMAGES=${MIMIR_EMBEDDINGS_IMAGES:-true} # Default: disabled
+ # - MIMIR_EMBEDDINGS_IMAGES_DESCRIBE_MODE=${MIMIR_EMBEDDINGS_IMAGES_DESCRIBE_MODE:-true} # Default: VL description mode
+ # # Qwen2.5-VL Configuration (for llama.cpp server)
+ # - MIMIR_EMBEDDINGS_VL_PROVIDER=${MIMIR_EMBEDDINGS_VL_PROVIDER:-llama.cpp}
+ # - MIMIR_EMBEDDINGS_VL_API=${MIMIR_EMBEDDINGS_VL_API:-http://llama-vl-server:8080}
+ # - MIMIR_EMBEDDINGS_VL_API_PATH=${MIMIR_EMBEDDINGS_VL_API_PATH:-/v1/chat/completions}
+ # - MIMIR_EMBEDDINGS_VL_API_KEY=${MIMIR_EMBEDDINGS_VL_API_KEY:-dummy-key}
+ # - MIMIR_EMBEDDINGS_VL_MODEL=${MIMIR_EMBEDDINGS_VL_MODEL:-qwen2.5-vl}
+ # - MIMIR_EMBEDDINGS_VL_CONTEXT_SIZE=${MIMIR_EMBEDDINGS_VL_CONTEXT_SIZE:-131072} # 128K tokens (7b/72b)
+ # - MIMIR_EMBEDDINGS_VL_MAX_TOKENS=${MIMIR_EMBEDDINGS_VL_MAX_TOKENS:-2048} # Max description length
+ # - MIMIR_EMBEDDINGS_VL_TEMPERATURE=${MIMIR_EMBEDDINGS_VL_TEMPERATURE:-0.7}
+ # - MIMIR_EMBEDDINGS_VL_DIMENSIONS=${MIMIR_EMBEDDINGS_VL_DIMENSIONS:-768} # Falls back to text model dims
+ # - MIMIR_EMBEDDINGS_VL_TIMEOUT=${MIMIR_EMBEDDINGS_VL_TIMEOUT:-180000} # 3 minutes (VL processing is slow)
+ # # Indexing Configuration
+ # - MIMIR_INDEXING_THREADS=${MIMIR_INDEXING_THREADS:-1}
+
+ # # Feature Flags
+ # - MIMIR_FEATURE_PM_MODEL_SUGGESTIONS=${MIMIR_FEATURE_PM_MODEL_SUGGESTIONS:-true}
+ # - MIMIR_AUTO_INDEX_DOCS=${MIMIR_AUTO_INDEX_DOCS:-true}
+ # # Feature Flags
+ # - MIMIR_FEATURE_PM_MODEL_SUGGESTIONS=${MIMIR_FEATURE_PM_MODEL_SUGGESTIONS:-true}
+ # - MIMIR_AUTO_INDEX_DOCS=${MIMIR_AUTO_INDEX_DOCS:-true}
+
+ # # Agent Execution Limits
+ # - MIMIR_AGENT_RECURSION_LIMIT=${MIMIR_AGENT_RECURSION_LIMIT:-100}
+ # # Agent Execution Limits
+ # - MIMIR_AGENT_RECURSION_LIMIT=${MIMIR_AGENT_RECURSION_LIMIT:-100}
+
+ # # Security Configuration
+ # - MIMIR_ENABLE_SECURITY=${MIMIR_ENABLE_SECURITY:-false}
+ # - MIMIR_DEV_USER_ADMIN=${MIMIR_DEV_USER_ADMIN}
+ # - MIMIR_DEV_USER_DEVELOPER=${MIMIR_DEV_USER_DEVELOPER}
+ # - MIMIR_DEV_USER_ANALYST=${MIMIR_DEV_USER_ANALYST}
+ # - MIMIR_DEV_USER_VIEWER=${MIMIR_DEV_USER_VIEWER}
+ # - MIMIR_JWT_SECRET=${MIMIR_JWT_SECRET}
+ # # OAuth Configuration (explicit endpoint URLs - provider-specific)
+ # - MIMIR_AUTH_PROVIDER=${MIMIR_AUTH_PROVIDER}
+ # - MIMIR_OAUTH_AUTHORIZATION_URL=${MIMIR_OAUTH_AUTHORIZATION_URL} # Full authorization endpoint URL
+ # - MIMIR_OAUTH_TOKEN_URL=${MIMIR_OAUTH_TOKEN_URL} # Full token endpoint URL
+ # - MIMIR_OAUTH_USERINFO_URL=${MIMIR_OAUTH_USERINFO_URL} # Full userinfo endpoint URL
+ # - MIMIR_OAUTH_CLIENT_ID=${MIMIR_OAUTH_CLIENT_ID}
+ # - MIMIR_OAUTH_CLIENT_SECRET=${MIMIR_OAUTH_CLIENT_SECRET}
+ # - MIMIR_OAUTH_CALLBACK_URL=${MIMIR_OAUTH_CALLBACK_URL}
+ # - MIMIR_OAUTH_ALLOW_HTTP=${MIMIR_OAUTH_ALLOW_HTTP}
+ # # Security Configuration
+ # - MIMIR_ENABLE_SECURITY=${MIMIR_ENABLE_SECURITY:-false}
+ # - MIMIR_DEV_USER_ADMIN=${MIMIR_DEV_USER_ADMIN}
+ # - MIMIR_DEV_USER_DEVELOPER=${MIMIR_DEV_USER_DEVELOPER}
+ # - MIMIR_DEV_USER_ANALYST=${MIMIR_DEV_USER_ANALYST}
+ # - MIMIR_DEV_USER_VIEWER=${MIMIR_DEV_USER_VIEWER}
+ # - MIMIR_JWT_SECRET=${MIMIR_JWT_SECRET}
+ # # OAuth Configuration (explicit endpoint URLs - provider-specific)
+ # - MIMIR_AUTH_PROVIDER=${MIMIR_AUTH_PROVIDER}
+ # - MIMIR_OAUTH_AUTHORIZATION_URL=${MIMIR_OAUTH_AUTHORIZATION_URL} # Full authorization endpoint URL
+ # - MIMIR_OAUTH_TOKEN_URL=${MIMIR_OAUTH_TOKEN_URL} # Full token endpoint URL
+ # - MIMIR_OAUTH_USERINFO_URL=${MIMIR_OAUTH_USERINFO_URL} # Full userinfo endpoint URL
+ # - MIMIR_OAUTH_CLIENT_ID=${MIMIR_OAUTH_CLIENT_ID}
+ # - MIMIR_OAUTH_CLIENT_SECRET=${MIMIR_OAUTH_CLIENT_SECRET}
+ # - MIMIR_OAUTH_CALLBACK_URL=${MIMIR_OAUTH_CALLBACK_URL}
+ # - MIMIR_OAUTH_ALLOW_HTTP=${MIMIR_OAUTH_ALLOW_HTTP}
+
+ # # Advanced Configuration
+ # - MIMIR_PARALLEL_EXECUTION=${MIMIR_PARALLEL_EXECUTION:-false}
+ # - MIMIR_INSTALL_DIR=${MIMIR_INSTALL_DIR:-/app}
+ # - MIMIR_AGENTS_DIR=${MIMIR_AGENTS_DIR:-/app/docs/agents}
+ # # Embeddings API Configuration
+ # # Advanced Configuration
+ # - MIMIR_PARALLEL_EXECUTION=${MIMIR_PARALLEL_EXECUTION:-false}
+ # - MIMIR_INSTALL_DIR=${MIMIR_INSTALL_DIR:-/app}
+ # - MIMIR_AGENTS_DIR=${MIMIR_AGENTS_DIR:-/app/docs/agents}
+ # # Embeddings API Configuration
+
+ # # - MIMIR_EMBEDDINGS_PROVIDER=${MIMIR_EMBEDDINGS_PROVIDER:-openai}
+ # # - MIMIR_EMBEDDINGS_API=${MIMIR_EMBEDDINGS_API:-http://llama-server:8080}
+ # # - MIMIR_EMBEDDINGS_API_PATH=${MIMIR_EMBEDDINGS_API_PATH:-/v1/embeddings}
+ # # - MIMIR_EMBEDDINGS_API_MODELS_PATH=${MIMIR_EMBEDDINGS_API_MODELS_PATH:-/v1/models}
+ # # - MIMIR_EMBEDDINGS_API_KEY=${MIMIR_EMBEDDINGS_API_KEY:-dummy-key}
+ # # Embeddings Configuration
+ # # - MIMIR_EMBEDDINGS_ENABLED=${MIMIR_EMBEDDINGS_ENABLED:-true}
+ # # - MIMIR_EMBEDDINGS_MODEL=${MIMIR_EMBEDDINGS_MODEL:-}
+ # # - MIMIR_EMBEDDINGS_DIMENSIONS=${MIMIR_EMBEDDINGS_DIMENSIONS:-1024}
+ # # - MIMIR_EMBEDDINGS_CHUNK_SIZE=${MIMIR_EMBEDDINGS_CHUNK_SIZE:-768}
+ # # - MIMIR_EMBEDDINGS_CHUNK_OVERLAP=${MIMIR_EMBEDDINGS_CHUNK_OVERLAP:-100}
+ # # - MIMIR_EMBEDDINGS_DELAY_MS=${MIMIR_EMBEDDINGS_DELAY_MS:-0}
+ # # - MIMIR_EMBEDDINGS_MAX_RETRIES=${MIMIR_EMBEDDINGS_MAX_RETRIES:-3}
+ # # - MIMIR_EMBEDDINGS_PROVIDER=${MIMIR_EMBEDDINGS_PROVIDER:-openai}
+ # # - MIMIR_EMBEDDINGS_API=${MIMIR_EMBEDDINGS_API:-http://llama-server:8080}
+ # # - MIMIR_EMBEDDINGS_API_PATH=${MIMIR_EMBEDDINGS_API_PATH:-/v1/embeddings}
+ # # - MIMIR_EMBEDDINGS_API_MODELS_PATH=${MIMIR_EMBEDDINGS_API_MODELS_PATH:-/v1/models}
+ # # - MIMIR_EMBEDDINGS_API_KEY=${MIMIR_EMBEDDINGS_API_KEY:-dummy-key}
+ # # Embeddings Configuration
+ # # - MIMIR_EMBEDDINGS_ENABLED=${MIMIR_EMBEDDINGS_ENABLED:-true}
+ # # - MIMIR_EMBEDDINGS_MODEL=${MIMIR_EMBEDDINGS_MODEL:-mxbai-embed-large}
+ # # - MIMIR_EMBEDDINGS_DIMENSIONS=${MIMIR_EMBEDDINGS_DIMENSIONS:-1024}
+ # # - MIMIR_EMBEDDINGS_CHUNK_SIZE=${MIMIR_EMBEDDINGS_CHUNK_SIZE:-768}
+ # # - MIMIR_EMBEDDINGS_CHUNK_OVERLAP=${MIMIR_EMBEDDINGS_CHUNK_OVERLAP:-100}
+ # # - MIMIR_EMBEDDINGS_DELAY_MS=${MIMIR_EMBEDDINGS_DELAY_MS:-0}
+ # # - MIMIR_EMBEDDINGS_MAX_RETRIES=${MIMIR_EMBEDDINGS_MAX_RETRIES:-3}
+
+
+ # # PCTX Integration (Code Mode for 90-98% token reduction)
+ # - PCTX_URL=${PCTX_URL:-http://host.docker.internal:8080}
+ # - PCTX_ENABLED=${PCTX_ENABLED:-false}
+ # # PCTX Integration (Code Mode for 90-98% token reduction)
+ # - PCTX_URL=${PCTX_URL:-http://host.docker.internal:8080}
+ # - PCTX_ENABLED=${PCTX_ENABLED:-false}
+
+ # volumes:
+ # - ./data:/app/data
+ # - ./logs:/app/logs
+ # - ${HOST_WORKSPACE_ROOT:-~/src}:${WORKSPACE_ROOT:-/workspace}
+ # ports:
+ # - "9042:3000"
+ # healthcheck:
+ # test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000/health', (res) => process.exit(res.statusCode === 200 ? 0 : 1)).on('error', () => process.exit(1))"]
+ # interval: 30s
+ # timeout: 10s
+ # retries: 3
+ # start_period: 10s
+ # depends_on:
+ # # neo4j:
+ # # condition: service_healthy
+ # nornicdb:
+ # condition: service_healthy
+ # copilot-api:
+ # condition: service_healthy
+ # # llama-server:
+ # # condition: service_healthy
+ # # llama-vl-server:
+ # # condition: service_healthy
+ # networks:
+ # - mcp_network
+ # volumes:
+ # - ./data:/app/data
+ # - ./logs:/app/logs
+ # - ${HOST_WORKSPACE_ROOT:-~/src}:${WORKSPACE_ROOT:-/workspace}
+ # ports:
+ # - "9042:3000"
+ # healthcheck:
+ # test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000/health', (res) => process.exit(res.statusCode === 200 ? 0 : 1)).on('error', () => process.exit(1))"]
+ # interval: 30s
+ # timeout: 10s
+ # retries: 3
+ # start_period: 10s
+ # depends_on:
+ # # neo4j:
+ # # condition: service_healthy
+ # nornicdb:
+ # condition: service_healthy
+ # copilot-api:
+ # condition: service_healthy
+ # # llama-server:
+ # # condition: service_healthy
+ # # llama-vl-server:
+ # # condition: service_healthy
+ # networks:
+ # - mcp_network
networks:
mcp_network:
diff --git a/nornicdb/docs/EXECUTOR_MODES.md b/nornicdb/docs/EXECUTOR_MODES.md
new file mode 100644
index 0000000..377cfa1
--- /dev/null
+++ b/nornicdb/docs/EXECUTOR_MODES.md
@@ -0,0 +1,312 @@
+# Cypher Executor Modes: Architecture Overview
+
+> **Environment Variable:** `NORNICDB_EXECUTOR_MODE`
+> **Options:** `nornic` | `antlr` | `hybrid` (default)
+
+## Architecture Diagram
+
+```mermaid
+%%{init: {'theme': 'dark', 'themeVariables': { 'primaryColor': '#1f6feb', 'primaryTextColor': '#c9d1d9', 'primaryBorderColor': '#30363d', 'lineColor': '#8b949e', 'secondaryColor': '#238636', 'tertiaryColor': '#21262d', 'background': '#0d1117', 'mainBkg': '#161b22', 'textColor': '#c9d1d9'}}}%%
+
+flowchart TB
+ subgraph ENV["π§ Configuration"]
+ direction LR
+ E1["NORNICDB_EXECUTOR_MODE"]
+ E2["nornic | antlr | hybrid"]
+ end
+
+ Q[/"Cypher Query"/]
+
+ Q --> FACTORY["NewCypherExecutor()"]
+
+ FACTORY --> |"mode=nornic"| NORNIC
+ FACTORY --> |"mode=antlr"| ANTLR
+ FACTORY --> |"mode=hybrid"| HYBRID
+
+ subgraph NORNIC["β‘ Nornic Mode"]
+ direction TB
+ N1["String Parser"]
+ N2["Regex + indexOf"]
+ N3["Direct Execution"]
+ N1 --> N2 --> N3
+ end
+
+ subgraph ANTLR["π³ ANTLR Mode"]
+ direction TB
+ A1["ANTLR Lexer"]
+ A2["ANTLR Parser"]
+ A3["Full AST"]
+ A4["AST Walker"]
+ A1 --> A2 --> A3 --> A4
+ end
+
+ subgraph HYBRID["π Hybrid Mode (Default)"]
+ direction TB
+ H1["Query Arrives"]
+ H2["String Executor
(Fast Path)"]
+ H3["Background Worker"]
+ H4["AST Cache"]
+
+ H1 --> H2
+ H1 -.-> |"async"| H3
+ H3 --> H4
+
+ style H2 fill:#238636,stroke:#3fb950
+ style H3 fill:#1f6feb,stroke:#58a6ff
+ style H4 fill:#6e40c9,stroke:#a371f7
+ end
+
+ NORNIC --> RESULT[("Result")]
+ ANTLR --> RESULT
+ HYBRID --> RESULT
+
+ HYBRID -.-> |"cached AST for
LLM features"| LLM["π€ LLM Integration"]
+
+ style ENV fill:#21262d,stroke:#30363d
+ style NORNIC fill:#161b22,stroke:#f85149
+ style ANTLR fill:#161b22,stroke:#a371f7
+ style HYBRID fill:#161b22,stroke:#3fb950
+ style RESULT fill:#238636,stroke:#3fb950
+ style LLM fill:#1f6feb,stroke:#58a6ff
+```
+
+## Query Flow Comparison
+
+```mermaid
+%%{init: {'theme': 'dark', 'themeVariables': { 'primaryColor': '#1f6feb', 'primaryTextColor': '#c9d1d9', 'primaryBorderColor': '#30363d', 'lineColor': '#8b949e', 'secondaryColor': '#238636', 'tertiaryColor': '#21262d'}}}%%
+
+sequenceDiagram
+ participant C as Client
+ participant N as Nornic
+ participant A as ANTLR
+ participant H as Hybrid
+ participant S as Storage
+ participant Cache as AST Cache
+
+ rect rgb(22, 27, 34)
+ Note over C,S: Nornic Mode (fastest)
+ C->>N: MATCH (n) RETURN n
+ N->>N: String parse (~0.1Β΅s)
+ N->>S: Execute
+ S-->>C: Results (~0.4Β΅s total)
+ end
+
+ rect rgb(22, 27, 34)
+ Note over C,S: ANTLR Mode (richest AST)
+ C->>A: MATCH (n) RETURN n
+ A->>A: Lexer + Parser (~15Β΅s)
+ A->>A: Build full AST
+ A->>A: Walk AST (~50Β΅s)
+ A->>S: Execute
+ S-->>C: Results (~70Β΅s total)
+ end
+
+ rect rgb(22, 27, 34)
+ Note over C,Cache: Hybrid Mode (best of both)
+ C->>H: MATCH (n) RETURN n
+ par Fast Path
+ H->>H: String parse
+ H->>S: Execute
+ S-->>C: Results (~0.4Β΅s)
+ and Background
+ H-->>Cache: Queue AST build
+ Cache->>Cache: ANTLR parse (async)
+ end
+ Note over Cache: AST ready for LLM features
+ end
+```
+
+## Mode Comparison
+
+| Feature | β‘ Nornic | π³ ANTLR | π Hybrid |
+|---------|----------|----------|-----------|
+| **Throughput** | 3,000-4,200 hz | 0.8-2,100 hz | 3,000-4,200 hz |
+| **Benchmark Time** | 17.5s | 35.3s | 17.5s |
+| **Worst Case Slowdown** | - | 4,753x | - |
+| **Full AST Available** | β No | β
Yes | β
Yes (async) |
+| **LLM Query Manipulation** | β Limited | β
Full support | β
Full support |
+| **Memory Usage** | Lowest | Highest | Medium |
+| **Query Validation** | Basic | Complete | Complete (async) |
+| **Best For** | Max speed | Dev/Analysis | **Production + LLM** |
+
+## Detailed Pros & Cons
+
+### β‘ Nornic Mode (`NORNICDB_EXECUTOR_MODE=nornic`)
+
+**Pros:**
+- π **Fastest execution** - 420ns/op average
+- πΎ **Lowest memory** - No AST allocation
+- π§ **Battle-tested** - Original implementation
+- β‘ **Zero parsing overhead** - Direct string manipulation
+
+**Cons:**
+- π€ **No LLM integration** - Can't safely manipulate queries
+- π **Limited introspection** - No structured query analysis
+- π **Harder to debug** - No AST to inspect
+- π **No query optimization** - Can't analyze query structure
+
+**Use When:**
+- Maximum performance is critical
+- No LLM features needed
+- Simple query patterns
+
+---
+
+### π³ ANTLR Mode (`NORNICDB_EXECUTOR_MODE=antlr`)
+
+**Pros:**
+- π³ **Full AST** - Complete parse tree for every query
+- π€ **LLM-ready** - Safe query manipulation/correction
+- π **Rich introspection** - Analyze any query structure
+- β
**Strict validation** - Grammar-enforced syntax checking
+- π οΈ **Extensible** - Easy to add new Cypher features
+
+**Cons:**
+- π’ **Slowest execution** - ~165x slower than Nornic
+- πΎ **High memory** - Full parse tree allocation
+- π **Parse overhead** - Every query fully parsed
+- β±οΈ **Not for hot paths** - Too slow for high-throughput
+
+**Use When:**
+- Development and debugging
+- Query analysis tools
+- LLM features are the priority over speed
+- Building query optimization pipelines
+
+---
+
+### π Hybrid Mode (`NORNICDB_EXECUTOR_MODE=hybrid`) **β DEFAULT**
+
+**Pros:**
+- β‘ **Fast execution** - Same speed as Nornic (~3% overhead)
+- π³ **AST available** - Built asynchronously in background
+- π€ **LLM-ready** - Cached AST for manipulation features
+- π― **Best of both** - Production speed + rich features
+- π **Stats tracking** - Monitor cache hits/misses
+
+**Cons:**
+- πΎ **Medium memory** - Caches grow over time
+- π **Async complexity** - AST not immediately available
+- β±οΈ **Cold start** - First query doesn't have cached AST
+- π§Ή **Cache management** - May need periodic cleanup
+
+**Use When:**
+- **Production deployments** (recommended default)
+- Need both speed and LLM features
+- Can tolerate async AST availability
+- Want monitoring/stats capabilities
+
+---
+
+## Performance Benchmarks
+
+### Micro-benchmarks (M3 Max)
+
+```
+BenchmarkNornic_Execute-16 2,832,133 420.6 ns/op 128 B/op 4 allocs/op
+BenchmarkHybrid_Execute-16 2,711,396 428.4 ns/op 128 B/op 4 allocs/op
+BenchmarkANTLR_Execute-16 16,851 70,234.0 ns/op 45312 B/op 892 allocs/op
+```
+
+### Real-World Benchmarks (Northwind Database)
+
+| Query | β‘ Nornic (hz) | π Hybrid (hz) | π³ ANTLR (hz) | ANTLR Slowdown |
+|-------|---------------|----------------|---------------|----------------|
+| Count all nodes | 3,272 | 3,312 | 45 | **73x slower** |
+| Count all relationships | 3,693 | 3,750 | 50 | **74x slower** |
+| Find customer by ID | 4,213 | 4,009 | 2,153 | 2x slower |
+| Products in Beverages category | 4,176 | 4,034 | 1,282 | 3x slower |
+| Products supplied by Exotic Liquids | 4,023 | 4,133 | 53 | **76x slower** |
+| SupplierβCategory through products | 3,225 | 3,342 | 22 | **147x slower** |
+| Products with/without orders | 3,881 | 3,967 | **0.82** | **4,753x slower** |
+| Create and delete relationship | 3,974 | 3,956 | 62 | **64x slower** |
+
+**Total benchmark time:**
+- β‘ Nornic: **17.5 seconds**
+- π Hybrid: **17.5 seconds**
+- π³ ANTLR: **35.3 seconds** (2x slower)
+
+### Key Findings
+
+1. **Hybrid = Nornic performance** - Zero measurable overhead in real workloads
+2. **ANTLR is 50-5000x slower** depending on query complexity
+3. **ANTLR catastrophic on complex queries** - Some queries take 1,224ms vs 0.25ms
+4. **Hybrid is the clear winner** - Same speed as Nornic + AST for LLM features
+
+## Configuration Examples
+
+```bash
+# Production (default) - fast + LLM ready
+export NORNICDB_EXECUTOR_MODE=hybrid
+
+# Maximum speed - no LLM features
+export NORNICDB_EXECUTOR_MODE=nornic
+
+# Development/Analysis - full AST always
+export NORNICDB_EXECUTOR_MODE=antlr
+```
+
+## Startup Banner
+
+When NornicDB starts, you'll see:
+
+```
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β π§ CYPHER EXECUTOR MODE: hybrid β
+β Hybrid executor - fast string execution + background AST building β
+β β
+β Set NORNICDB_EXECUTOR_MODE to: nornic | antlr | hybrid β
+βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+```
+
+## LLM Integration Architecture
+
+```mermaid
+%%{init: {'theme': 'dark', 'themeVariables': { 'primaryColor': '#1f6feb', 'primaryTextColor': '#c9d1d9', 'primaryBorderColor': '#30363d', 'lineColor': '#8b949e', 'secondaryColor': '#238636', 'tertiaryColor': '#21262d'}}}%%
+
+flowchart LR
+ subgraph USER["User Input"]
+ Q1["Malformed Query"]
+ Q2["Natural Language"]
+ end
+
+ subgraph LLM["π€ LLM Processing"]
+ direction TB
+ L1["Query Correction"]
+ L2["AST Analysis"]
+ L3["Safe Manipulation"]
+ end
+
+ subgraph HYBRID["π Hybrid Executor"]
+ direction TB
+ AST["Cached AST"]
+ EXEC["Fast Execution"]
+ end
+
+ Q1 --> L1
+ Q2 --> L1
+ L1 --> L2
+ AST --> L2
+ L2 --> L3
+ L3 --> EXEC
+ EXEC --> R[("Results")]
+
+ style USER fill:#21262d,stroke:#f85149
+ style LLM fill:#1f6feb,stroke:#58a6ff
+ style HYBRID fill:#238636,stroke:#3fb950
+ style R fill:#238636,stroke:#3fb950
+```
+
+## Related Files
+
+- `pkg/config/executor_mode.go` - Configuration
+- `pkg/cypher/executor_factory.go` - Factory function
+- `pkg/cypher/hybrid_executor.go` - Hybrid implementation
+- `pkg/cypher/ast_executor.go` - ANTLR implementation
+- `pkg/cypher/executor.go` - Nornic (string) implementation
+
+---
+
+**Questions?** Open an issue or check the test files for usage examples:
+- `pkg/cypher/executor_mode_test.go` - Comprehensive mode tests
+- `pkg/cypher/hybrid_executor_test.go` - Hybrid-specific tests
diff --git a/nornicdb/go.mod b/nornicdb/go.mod
index 55ca8fc..f714573 100644
--- a/nornicdb/go.mod
+++ b/nornicdb/go.mod
@@ -11,6 +11,7 @@ require (
)
require (
+ github.com/antlr4-go/antlr/v4 v4.13.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dgraph-io/ristretto/v2 v2.2.0 // indirect
@@ -27,6 +28,7 @@ require (
go.opentelemetry.io/otel v1.37.0 // indirect
go.opentelemetry.io/otel/metric v1.37.0 // indirect
go.opentelemetry.io/otel/trace v1.37.0 // indirect
+ golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect
golang.org/x/net v0.41.0 // indirect
golang.org/x/sys v0.34.0 // indirect
google.golang.org/protobuf v1.36.6 // indirect
diff --git a/nornicdb/go.sum b/nornicdb/go.sum
index 216e960..868ec37 100644
--- a/nornicdb/go.sum
+++ b/nornicdb/go.sum
@@ -1,3 +1,5 @@
+github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ=
+github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
@@ -51,6 +53,8 @@ go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mx
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM=
golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U=
+golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM=
+golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
diff --git a/nornicdb/pkg/config/executor_mode.go b/nornicdb/pkg/config/executor_mode.go
new file mode 100644
index 0000000..d632796
--- /dev/null
+++ b/nornicdb/pkg/config/executor_mode.go
@@ -0,0 +1,94 @@
+// Package config - Executor mode configuration for NornicDB.
+//
+// Controls which Cypher executor implementation is used:
+// - nornic: Fast string-based parser (original implementation)
+// - antlr: Full ANTLR AST-based parser (slower, richer AST)
+// - hybrid: Fast execution + background AST building (default)
+//
+// Environment variable:
+//
+// NORNICDB_EXECUTOR_MODE=hybrid (default)
+// NORNICDB_EXECUTOR_MODE=nornic
+// NORNICDB_EXECUTOR_MODE=antlr
+package config
+
+import (
+ "os"
+ "strings"
+ "sync/atomic"
+)
+
+// ExecutorMode represents the Cypher executor implementation to use
+type ExecutorMode string
+
+const (
+ // ExecutorModeNornic uses the fast string-based parser
+ ExecutorModeNornic ExecutorMode = "nornic"
+
+ // ExecutorModeANTLR uses the full ANTLR AST-based parser
+ ExecutorModeANTLR ExecutorMode = "antlr"
+
+ // ExecutorModeHybrid uses fast execution + background AST building
+ ExecutorModeHybrid ExecutorMode = "hybrid"
+
+ // EnvExecutorMode is the environment variable key
+ EnvExecutorMode = "NORNICDB_EXECUTOR_MODE"
+)
+
+// Default executor mode
+var executorMode atomic.Value
+
+func init() {
+ // Default to hybrid
+ executorMode.Store(ExecutorModeHybrid)
+
+ // Load from environment
+ if env := os.Getenv(EnvExecutorMode); env != "" {
+ mode := ExecutorMode(strings.ToLower(strings.TrimSpace(env)))
+ switch mode {
+ case ExecutorModeNornic, ExecutorModeANTLR, ExecutorModeHybrid:
+ executorMode.Store(mode)
+ default:
+ // Invalid value, keep default (hybrid)
+ }
+ }
+}
+
+// GetExecutorMode returns the current executor mode
+func GetExecutorMode() ExecutorMode {
+ return executorMode.Load().(ExecutorMode)
+}
+
+// SetExecutorMode sets the executor mode (for testing)
+func SetExecutorMode(mode ExecutorMode) {
+ switch mode {
+ case ExecutorModeNornic, ExecutorModeANTLR, ExecutorModeHybrid:
+ executorMode.Store(mode)
+ default:
+ // Invalid, ignore
+ }
+}
+
+// IsExecutorModeNornic returns true if using the string-based parser
+func IsExecutorModeNornic() bool {
+ return GetExecutorMode() == ExecutorModeNornic
+}
+
+// IsExecutorModeANTLR returns true if using the ANTLR parser
+func IsExecutorModeANTLR() bool {
+ return GetExecutorMode() == ExecutorModeANTLR
+}
+
+// IsExecutorModeHybrid returns true if using the hybrid executor
+func IsExecutorModeHybrid() bool {
+ return GetExecutorMode() == ExecutorModeHybrid
+}
+
+// WithExecutorMode temporarily sets executor mode, returns restore function
+func WithExecutorMode(mode ExecutorMode) func() {
+ prev := GetExecutorMode()
+ SetExecutorMode(mode)
+ return func() {
+ SetExecutorMode(prev)
+ }
+}
diff --git a/nornicdb/pkg/cypher/ab_test.go b/nornicdb/pkg/cypher/ab_test.go
new file mode 100644
index 0000000..360ee0a
--- /dev/null
+++ b/nornicdb/pkg/cypher/ab_test.go
@@ -0,0 +1,288 @@
+// Package cypher - A/B testing between string-based and AST-based executors.
+package cypher
+
+import (
+ "context"
+ "fmt"
+ "testing"
+ "time"
+
+ "github.com/orneryd/nornicdb/pkg/storage"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+// setupABExecutors creates both executor types for testing
+func setupABExecutors(t *testing.T) (*StorageExecutor, *ASTExecutor, *storage.MemoryEngine) {
+ store := storage.NewMemoryEngine()
+ stringExec := NewStorageExecutor(store)
+ astExec := NewASTExecutor(store)
+ return stringExec, astExec, store
+}
+
+// setupABTestData creates common test data
+func setupABTestData(t *testing.T, exec CypherExecutor, ctx context.Context) {
+ queries := []string{
+ "CREATE (a:Person {name: 'Alice', age: 30})",
+ "CREATE (b:Person {name: 'Bob', age: 25})",
+ "CREATE (c:Person {name: 'Charlie', age: 35})",
+ "CREATE (d:Company {name: 'TechCorp'})",
+ "MATCH (a:Person {name: 'Alice'}), (b:Person {name: 'Bob'}) CREATE (a)-[:KNOWS]->(b)",
+ "MATCH (b:Person {name: 'Bob'}), (c:Person {name: 'Charlie'}) CREATE (b)-[:KNOWS]->(c)",
+ "MATCH (a:Person {name: 'Alice'}), (d:Company {name: 'TechCorp'}) CREATE (a)-[:WORKS_AT]->(d)",
+ }
+ for _, q := range queries {
+ _, err := exec.Execute(ctx, q, nil)
+ require.NoError(t, err, "Setup query failed: %s", q)
+ }
+}
+
+// TestAB_BasicQueries tests that both executors produce the same results
+func TestAB_BasicQueries(t *testing.T) {
+ stringExec, astExec, _ := setupABExecutors(t)
+ ctx := context.Background()
+
+ // Setup data using string executor (known working)
+ setupABTestData(t, stringExec, ctx)
+
+ // Also setup in AST executor's view (they share storage)
+ queries := []struct {
+ name string
+ query string
+ params map[string]interface{}
+ }{
+ {"match_all", "MATCH (n) RETURN count(n)", nil},
+ {"match_label", "MATCH (p:Person) RETURN p.name ORDER BY p.name", nil},
+ {"match_where", "MATCH (p:Person) WHERE p.age > 25 RETURN p.name", nil},
+ {"match_relationship", "MATCH (a)-[:KNOWS]->(b) RETURN a.name, b.name", nil},
+ {"return_literal", "RETURN 1 + 2 AS sum", nil},
+ {"return_string", "RETURN 'hello' AS greeting", nil},
+ {"match_with_param", "MATCH (p:Person {name: $name}) RETURN p.age", map[string]interface{}{"name": "Alice"}},
+ }
+
+ for _, tc := range queries {
+ t.Run(tc.name, func(t *testing.T) {
+ // Run on string executor
+ stringResult, stringErr := stringExec.Execute(ctx, tc.query, tc.params)
+
+ // Run on AST executor
+ astResult, astErr := astExec.Execute(ctx, tc.query, tc.params)
+
+ // Compare errors
+ if stringErr != nil {
+ t.Logf("String executor error: %v", stringErr)
+ }
+ if astErr != nil {
+ t.Logf("AST executor error: %v", astErr)
+ }
+
+ // If string succeeds, AST should too (or vice versa)
+ if stringErr == nil && astErr == nil {
+ // Compare row counts
+ assert.Equal(t, len(stringResult.Rows), len(astResult.Rows),
+ "Row count mismatch: string=%d, ast=%d", len(stringResult.Rows), len(astResult.Rows))
+
+ // Compare column counts
+ assert.Equal(t, len(stringResult.Columns), len(astResult.Columns),
+ "Column count mismatch")
+ }
+ })
+ }
+}
+
+// BenchmarkAB_StringExecutor benchmarks the string-based executor
+func BenchmarkAB_StringExecutor(b *testing.B) {
+ store := storage.NewMemoryEngine()
+ exec := NewStorageExecutor(store)
+ ctx := context.Background()
+
+ // Setup data
+ setupBenchmarkData(b, exec, ctx)
+
+ queries := []struct {
+ name string
+ query string
+ }{
+ {"simple_match", "MATCH (n:Person) RETURN n.name"},
+ {"count", "MATCH (n) RETURN count(n)"},
+ {"where_filter", "MATCH (n:Person) WHERE n.age > 25 RETURN n"},
+ {"relationship", "MATCH (a)-[:KNOWS]->(b) RETURN a.name, b.name"},
+ {"aggregation", "MATCH (n:Person) RETURN avg(n.age)"},
+ }
+
+ for _, tc := range queries {
+ b.Run(tc.name, func(b *testing.B) {
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ exec.Execute(ctx, tc.query, nil)
+ }
+ })
+ }
+}
+
+// BenchmarkAB_ASTExecutor benchmarks the AST-based executor
+func BenchmarkAB_ASTExecutor(b *testing.B) {
+ store := storage.NewMemoryEngine()
+ exec := NewASTExecutor(store)
+ ctx := context.Background()
+
+ // Setup data (using string executor since AST may not support CREATE yet)
+ stringExec := NewStorageExecutor(store)
+ setupBenchmarkData(b, stringExec, ctx)
+
+ queries := []struct {
+ name string
+ query string
+ }{
+ {"simple_match", "MATCH (n:Person) RETURN n.name"},
+ {"count", "MATCH (n) RETURN count(n)"},
+ {"where_filter", "MATCH (n:Person) WHERE n.age > 25 RETURN n"},
+ {"relationship", "MATCH (a)-[:KNOWS]->(b) RETURN a.name, b.name"},
+ {"aggregation", "MATCH (n:Person) RETURN avg(n.age)"},
+ }
+
+ for _, tc := range queries {
+ b.Run(tc.name, func(b *testing.B) {
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ exec.Execute(ctx, tc.query, nil)
+ }
+ })
+ }
+}
+
+func setupBenchmarkData(b interface{ Errorf(string, ...interface{}) }, exec CypherExecutor, ctx context.Context) {
+ // Create 100 person nodes
+ for i := 0; i < 100; i++ {
+ query := fmt.Sprintf("CREATE (p:Person {name: 'Person%d', age: %d})", i, 20+i%50)
+ exec.Execute(ctx, query, nil)
+ }
+
+ // Create some relationships
+ for i := 0; i < 50; i++ {
+ query := fmt.Sprintf("MATCH (a:Person {name: 'Person%d'}), (b:Person {name: 'Person%d'}) CREATE (a)-[:KNOWS]->(b)", i, (i+1)%100)
+ exec.Execute(ctx, query, nil)
+ }
+}
+
+// TestAB_PerformanceComparison runs a performance comparison between executors
+func TestAB_PerformanceComparison(t *testing.T) {
+ if testing.Short() {
+ t.Skip("Skipping performance test in short mode")
+ }
+
+ stringExec, astExec, _ := setupABExecutors(t)
+ ctx := context.Background()
+
+ // Setup larger dataset
+ for i := 0; i < 50; i++ {
+ query := fmt.Sprintf("CREATE (p:Person {name: 'Person%d', age: %d})", i, 20+i%50)
+ stringExec.Execute(ctx, query, nil)
+ }
+
+ testQueries := []string{
+ "MATCH (n:Person) RETURN count(n)",
+ "MATCH (n:Person) WHERE n.age > 30 RETURN n.name",
+ "RETURN 1 + 2 + 3 + 4 + 5",
+ }
+
+ iterations := 100
+
+ for _, query := range testQueries {
+ t.Run(query[:20], func(t *testing.T) {
+ // Warmup
+ for i := 0; i < 10; i++ {
+ stringExec.Execute(ctx, query, nil)
+ astExec.Execute(ctx, query, nil)
+ }
+
+ // Benchmark string executor
+ stringStart := time.Now()
+ for i := 0; i < iterations; i++ {
+ stringExec.Execute(ctx, query, nil)
+ }
+ stringDuration := time.Since(stringStart)
+
+ // Benchmark AST executor
+ astStart := time.Now()
+ for i := 0; i < iterations; i++ {
+ astExec.Execute(ctx, query, nil)
+ }
+ astDuration := time.Since(astStart)
+
+ stringAvg := float64(stringDuration.Microseconds()) / float64(iterations)
+ astAvg := float64(astDuration.Microseconds()) / float64(iterations)
+
+ speedup := stringAvg / astAvg
+ winner := "STRING"
+ if speedup > 1 {
+ winner = "AST"
+ }
+
+ t.Logf("Query: %s", query)
+ t.Logf(" String: %.2f Β΅s/op", stringAvg)
+ t.Logf(" AST: %.2f Β΅s/op", astAvg)
+ t.Logf(" Winner: %s (%.2fx)", winner, speedup)
+ })
+ }
+}
+
+// TestAB_ResultEquivalence verifies both executors return equivalent results
+func TestAB_ResultEquivalence(t *testing.T) {
+ stringExec, astExec, _ := setupABExecutors(t)
+ ctx := context.Background()
+
+ // Setup identical data
+ setupABTestData(t, stringExec, ctx)
+
+ testCases := []struct {
+ name string
+ query string
+ params map[string]interface{}
+ }{
+ {"literal_int", "RETURN 42", nil},
+ {"literal_string", "RETURN 'hello'", nil},
+ {"arithmetic", "RETURN 10 + 5 * 2", nil},
+ {"match_count", "MATCH (n) RETURN count(n)", nil},
+ {"match_property", "MATCH (p:Person) RETURN p.name ORDER BY p.name LIMIT 1", nil},
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ stringResult, stringErr := stringExec.Execute(ctx, tc.query, tc.params)
+ astResult, astErr := astExec.Execute(ctx, tc.query, tc.params)
+
+ // Both should succeed or both should fail
+ if (stringErr == nil) != (astErr == nil) {
+ t.Errorf("Error mismatch: string=%v, ast=%v", stringErr, astErr)
+ return
+ }
+
+ if stringErr != nil {
+ return // Both errored, that's fine
+ }
+
+ // Compare results
+ if len(stringResult.Rows) != len(astResult.Rows) {
+ t.Errorf("Row count mismatch: string=%d, ast=%d",
+ len(stringResult.Rows), len(astResult.Rows))
+ return
+ }
+
+ // For single-value returns, compare the actual values
+ if len(stringResult.Rows) == 1 && len(stringResult.Rows[0]) == 1 {
+ stringVal := stringResult.Rows[0][0]
+ astVal := astResult.Rows[0][0]
+
+ // Allow for type differences (int64 vs float64)
+ stringStr := fmt.Sprintf("%v", stringVal)
+ astStr := fmt.Sprintf("%v", astVal)
+
+ if stringStr != astStr {
+ t.Logf("Value difference: string=%v (%T), ast=%v (%T)",
+ stringVal, stringVal, astVal, astVal)
+ }
+ }
+ })
+ }
+}
diff --git a/nornicdb/pkg/cypher/antlr/CypherLexer.g4 b/nornicdb/pkg/cypher/antlr/CypherLexer.g4
new file mode 100644
index 0000000..46615e0
--- /dev/null
+++ b/nornicdb/pkg/cypher/antlr/CypherLexer.g4
@@ -0,0 +1,203 @@
+/*
+ [The "BSD licence"]
+ Copyright (c) 2022 Boris Zhguchev
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// $antlr-format alignTrailingComments true, columnLimit 150, maxEmptyLinesToKeep 1, reflowComments false, useTab false
+// $antlr-format allowShortRulesOnASingleLine true, allowShortBlocksOnASingleLine true, minEmptyLines 0, alignSemicolons ownLine
+// $antlr-format alignColons trailing, singleLineOverrulesHangingColon true, alignLexerCommands true, alignLabels true, alignTrailers true
+
+lexer grammar CypherLexer;
+channels {
+ COMMENTS
+}
+options {
+ caseInsensitive = true;
+}
+
+ASSIGN : '=';
+ADD_ASSIGN : '+=';
+LE : '<=';
+GE : '>=';
+GT : '>';
+LT : '<';
+NOT_EQUAL : '<>' | '!=';
+REGEX_MATCH: '=~';
+RANGE : '..';
+SEMI : ';';
+DOT : '.';
+COMMA : ',';
+LPAREN : '(';
+RPAREN : ')';
+LBRACE : '{';
+RBRACE : '}';
+LBRACK : '[';
+RBRACK : ']';
+SUB : '-';
+PLUS : '+';
+DIV : '/';
+MOD : '%';
+CARET : '^';
+MULT : '*';
+ESC : '`';
+COLON : ':';
+STICK : '|';
+DOLLAR : '$';
+
+CALL : 'CALL';
+YIELD : 'YIELD';
+FILTER : 'FILTER';
+EXTRACT : 'EXTRACT';
+COUNT : 'COUNT';
+SUM : 'SUM';
+AVG : 'AVG';
+MIN : 'MIN';
+MAX : 'MAX';
+COLLECT : 'COLLECT';
+ANY : 'ANY';
+NONE : 'NONE';
+SINGLE : 'SINGLE';
+ALL : 'ALL';
+ASC : 'ASC';
+ASCENDING : 'ASCENDING';
+BY : 'BY';
+CREATE : 'CREATE';
+DELETE : 'DELETE';
+DESC : 'DESC';
+DESCENDING : 'DESCENDING';
+DETACH : 'DETACH';
+EXISTS : 'EXISTS';
+LIMIT : 'LIMIT';
+MATCH : 'MATCH';
+MERGE : 'MERGE';
+ON : 'ON';
+OPTIONAL : 'OPTIONAL';
+ORDER : 'ORDER';
+REMOVE : 'REMOVE';
+RETURN : 'RETURN';
+SET : 'SET';
+SKIP_W : 'SKIP';
+WHERE : 'WHERE';
+WITH : 'WITH';
+UNION : 'UNION';
+UNWIND : 'UNWIND';
+AND : 'AND';
+AS : 'AS';
+CONTAINS : 'CONTAINS';
+DISTINCT : 'DISTINCT';
+ENDS : 'ENDS';
+IN : 'IN';
+IS : 'IS';
+NOT : 'NOT';
+OR : 'OR';
+STARTS : 'STARTS';
+XOR : 'XOR';
+FALSE : 'FALSE';
+TRUE : 'TRUE';
+NULL_W : 'NULL';
+CONSTRAINT : 'CONSTRAINT';
+DO : 'DO';
+FOR : 'FOR';
+REQUIRE : 'REQUIRE';
+UNIQUE : 'UNIQUE';
+CASE : 'CASE';
+WHEN : 'WHEN';
+THEN : 'THEN';
+ELSE : 'ELSE';
+END : 'END';
+MANDATORY : 'MANDATORY';
+SCALAR : 'SCALAR';
+OF : 'OF';
+ADD : 'ADD';
+DROP : 'DROP';
+INDEX : 'INDEX';
+INDEXES : 'INDEXES';
+VECTOR : 'VECTOR';
+EXPLAIN : 'EXPLAIN';
+PROFILE : 'PROFILE';
+SHOW : 'SHOW';
+CONSTRAINTS: 'CONSTRAINTS';
+PROCEDURES : 'PROCEDURES';
+FUNCTIONS : 'FUNCTIONS';
+DATABASE : 'DATABASE';
+DATABASES : 'DATABASES';
+FULLTEXT : 'FULLTEXT';
+OPTIONS : 'OPTIONS';
+EACH : 'EACH';
+IF : 'IF';
+TRANSACTIONS: 'TRANSACTIONS';
+ROWS : 'ROWS';
+ASSERT : 'ASSERT';
+KEY : 'KEY';
+NODE : 'NODE';
+SHORTESTPATH: 'shortestPath';
+ALLSHORTESTPATHS: 'allShortestPaths';
+
+// FLOAT must come before INTEGER so 2.00 isn't matched as INTEGER
+// Note: We use [0-9]+ for fractional part to allow numbers like 0.05
+FLOAT : SUB? (([0-9]+ '.' [0-9]+ | '.' [0-9]+) ExponentPart? [fd]? | [0-9]+ (ExponentPart [fd]? | [fd]));
+
+// Integer literal - must be before ID to have priority
+INTEGER : SUB? DecimalInteger;
+
+// DIGIT - hex, octal, or single digit (for array indices, etc)
+DIGIT : HexInteger | OctalInteger | [0-9];
+
+// ID must come after numbers so they aren't matched as IDs
+ID: Letter LetterOrDigit*;
+
+ESC_LITERAL : '`' .*? '`';
+// Single-quoted strings can contain any characters except unescaped quotes
+CHAR_LITERAL : '\'' (~['\\\r\n] | EscapeSequence)* '\'';
+// Double-quoted strings can contain any characters except unescaped quotes
+STRING_LITERAL : '"' (~["\\\r\n] | EscapeSequence)* '"';
+
+WS : [ \t\r\n\u000C]+ -> channel(HIDDEN);
+COMMENT : '/*' .*? '*/' -> channel(COMMENTS);
+LINE_COMMENT : '//' ~[\r\n]* -> channel(COMMENTS);
+// ERRCHAR catches unrecognized characters - keeps them visible to trigger errors
+ERRCHAR : .;
+
+fragment EscapeSequence:
+ '\\' [btnfr"'\\.u/]
+ | '\\' ([0-3]? [0-7])? [0-7]
+ | '\\' 'u'+ HexDigit HexDigit HexDigit HexDigit
+;
+
+fragment ExponentPart: [e] [+-]? DecimalInteger;
+
+fragment HexInteger : '0' [xX] HexDigit+;
+fragment HexDigit : [0-9a-fA-F];
+fragment OctalInteger: '0' [oO]? [0-7]+;
+fragment DecimalInteger: '0' | [1-9] [0-9]*;
+
+fragment LetterOrDigit: Letter | [0-9];
+
+Letter:
+ [a-z_]
+ | ~[\u0000-\u007F\uD800-\uDBFF] // covers all characters above 0x7F which are not a surrogate
+ | [\uD800-\uDBFF] [\uDC00-\uDFFF]
+; // covers UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF
\ No newline at end of file
diff --git a/nornicdb/pkg/cypher/antlr/CypherLexer.interp b/nornicdb/pkg/cypher/antlr/CypherLexer.interp
new file mode 100644
index 0000000..24039b1
--- /dev/null
+++ b/nornicdb/pkg/cypher/antlr/CypherLexer.interp
@@ -0,0 +1,411 @@
+token literal names:
+null
+'='
+'+='
+'<='
+'>='
+'>'
+'<'
+null
+'=~'
+'..'
+';'
+'.'
+','
+'('
+')'
+'{'
+'}'
+'['
+']'
+'-'
+'+'
+'/'
+'%'
+'^'
+'*'
+'`'
+':'
+'|'
+'$'
+'CALL'
+'YIELD'
+'FILTER'
+'EXTRACT'
+'COUNT'
+'SUM'
+'AVG'
+'MIN'
+'MAX'
+'COLLECT'
+'ANY'
+'NONE'
+'SINGLE'
+'ALL'
+'ASC'
+'ASCENDING'
+'BY'
+'CREATE'
+'DELETE'
+'DESC'
+'DESCENDING'
+'DETACH'
+'EXISTS'
+'LIMIT'
+'MATCH'
+'MERGE'
+'ON'
+'OPTIONAL'
+'ORDER'
+'REMOVE'
+'RETURN'
+'SET'
+'SKIP'
+'WHERE'
+'WITH'
+'UNION'
+'UNWIND'
+'AND'
+'AS'
+'CONTAINS'
+'DISTINCT'
+'ENDS'
+'IN'
+'IS'
+'NOT'
+'OR'
+'STARTS'
+'XOR'
+'FALSE'
+'TRUE'
+'NULL'
+'CONSTRAINT'
+'DO'
+'FOR'
+'REQUIRE'
+'UNIQUE'
+'CASE'
+'WHEN'
+'THEN'
+'ELSE'
+'END'
+'MANDATORY'
+'SCALAR'
+'OF'
+'ADD'
+'DROP'
+'INDEX'
+'INDEXES'
+'VECTOR'
+'EXPLAIN'
+'PROFILE'
+'SHOW'
+'CONSTRAINTS'
+'PROCEDURES'
+'FUNCTIONS'
+'DATABASE'
+'DATABASES'
+'FULLTEXT'
+'OPTIONS'
+'EACH'
+'IF'
+'TRANSACTIONS'
+'ROWS'
+'ASSERT'
+'KEY'
+'NODE'
+'shortestPath'
+'allShortestPaths'
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+
+token symbolic names:
+null
+ASSIGN
+ADD_ASSIGN
+LE
+GE
+GT
+LT
+NOT_EQUAL
+REGEX_MATCH
+RANGE
+SEMI
+DOT
+COMMA
+LPAREN
+RPAREN
+LBRACE
+RBRACE
+LBRACK
+RBRACK
+SUB
+PLUS
+DIV
+MOD
+CARET
+MULT
+ESC
+COLON
+STICK
+DOLLAR
+CALL
+YIELD
+FILTER
+EXTRACT
+COUNT
+SUM
+AVG
+MIN
+MAX
+COLLECT
+ANY
+NONE
+SINGLE
+ALL
+ASC
+ASCENDING
+BY
+CREATE
+DELETE
+DESC
+DESCENDING
+DETACH
+EXISTS
+LIMIT
+MATCH
+MERGE
+ON
+OPTIONAL
+ORDER
+REMOVE
+RETURN
+SET
+SKIP_W
+WHERE
+WITH
+UNION
+UNWIND
+AND
+AS
+CONTAINS
+DISTINCT
+ENDS
+IN
+IS
+NOT
+OR
+STARTS
+XOR
+FALSE
+TRUE
+NULL_W
+CONSTRAINT
+DO
+FOR
+REQUIRE
+UNIQUE
+CASE
+WHEN
+THEN
+ELSE
+END
+MANDATORY
+SCALAR
+OF
+ADD
+DROP
+INDEX
+INDEXES
+VECTOR
+EXPLAIN
+PROFILE
+SHOW
+CONSTRAINTS
+PROCEDURES
+FUNCTIONS
+DATABASE
+DATABASES
+FULLTEXT
+OPTIONS
+EACH
+IF
+TRANSACTIONS
+ROWS
+ASSERT
+KEY
+NODE
+SHORTESTPATH
+ALLSHORTESTPATHS
+FLOAT
+INTEGER
+DIGIT
+ID
+ESC_LITERAL
+CHAR_LITERAL
+STRING_LITERAL
+WS
+COMMENT
+LINE_COMMENT
+ERRCHAR
+Letter
+
+rule names:
+ASSIGN
+ADD_ASSIGN
+LE
+GE
+GT
+LT
+NOT_EQUAL
+REGEX_MATCH
+RANGE
+SEMI
+DOT
+COMMA
+LPAREN
+RPAREN
+LBRACE
+RBRACE
+LBRACK
+RBRACK
+SUB
+PLUS
+DIV
+MOD
+CARET
+MULT
+ESC
+COLON
+STICK
+DOLLAR
+CALL
+YIELD
+FILTER
+EXTRACT
+COUNT
+SUM
+AVG
+MIN
+MAX
+COLLECT
+ANY
+NONE
+SINGLE
+ALL
+ASC
+ASCENDING
+BY
+CREATE
+DELETE
+DESC
+DESCENDING
+DETACH
+EXISTS
+LIMIT
+MATCH
+MERGE
+ON
+OPTIONAL
+ORDER
+REMOVE
+RETURN
+SET
+SKIP_W
+WHERE
+WITH
+UNION
+UNWIND
+AND
+AS
+CONTAINS
+DISTINCT
+ENDS
+IN
+IS
+NOT
+OR
+STARTS
+XOR
+FALSE
+TRUE
+NULL_W
+CONSTRAINT
+DO
+FOR
+REQUIRE
+UNIQUE
+CASE
+WHEN
+THEN
+ELSE
+END
+MANDATORY
+SCALAR
+OF
+ADD
+DROP
+INDEX
+INDEXES
+VECTOR
+EXPLAIN
+PROFILE
+SHOW
+CONSTRAINTS
+PROCEDURES
+FUNCTIONS
+DATABASE
+DATABASES
+FULLTEXT
+OPTIONS
+EACH
+IF
+TRANSACTIONS
+ROWS
+ASSERT
+KEY
+NODE
+SHORTESTPATH
+ALLSHORTESTPATHS
+FLOAT
+INTEGER
+DIGIT
+ID
+ESC_LITERAL
+CHAR_LITERAL
+STRING_LITERAL
+WS
+COMMENT
+LINE_COMMENT
+ERRCHAR
+EscapeSequence
+ExponentPart
+HexInteger
+HexDigit
+OctalInteger
+DecimalInteger
+LetterOrDigit
+Letter
+
+channel names:
+DEFAULT_TOKEN_CHANNEL
+HIDDEN
+null
+null
+COMMENTS
+
+mode names:
+DEFAULT_MODE
+
+atn:
+[4, 0, 128, 1084, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7, 57, 2, 58, 7, 58, 2, 59, 7, 59, 2, 60, 7, 60, 2, 61, 7, 61, 2, 62, 7, 62, 2, 63, 7, 63, 2, 64, 7, 64, 2, 65, 7, 65, 2, 66, 7, 66, 2, 67, 7, 67, 2, 68, 7, 68, 2, 69, 7, 69, 2, 70, 7, 70, 2, 71, 7, 71, 2, 72, 7, 72, 2, 73, 7, 73, 2, 74, 7, 74, 2, 75, 7, 75, 2, 76, 7, 76, 2, 77, 7, 77, 2, 78, 7, 78, 2, 79, 7, 79, 2, 80, 7, 80, 2, 81, 7, 81, 2, 82, 7, 82, 2, 83, 7, 83, 2, 84, 7, 84, 2, 85, 7, 85, 2, 86, 7, 86, 2, 87, 7, 87, 2, 88, 7, 88, 2, 89, 7, 89, 2, 90, 7, 90, 2, 91, 7, 91, 2, 92, 7, 92, 2, 93, 7, 93, 2, 94, 7, 94, 2, 95, 7, 95, 2, 96, 7, 96, 2, 97, 7, 97, 2, 98, 7, 98, 2, 99, 7, 99, 2, 100, 7, 100, 2, 101, 7, 101, 2, 102, 7, 102, 2, 103, 7, 103, 2, 104, 7, 104, 2, 105, 7, 105, 2, 106, 7, 106, 2, 107, 7, 107, 2, 108, 7, 108, 2, 109, 7, 109, 2, 110, 7, 110, 2, 111, 7, 111, 2, 112, 7, 112, 2, 113, 7, 113, 2, 114, 7, 114, 2, 115, 7, 115, 2, 116, 7, 116, 2, 117, 7, 117, 2, 118, 7, 118, 2, 119, 7, 119, 2, 120, 7, 120, 2, 121, 7, 121, 2, 122, 7, 122, 2, 123, 7, 123, 2, 124, 7, 124, 2, 125, 7, 125, 2, 126, 7, 126, 2, 127, 7, 127, 2, 128, 7, 128, 2, 129, 7, 129, 2, 130, 7, 130, 2, 131, 7, 131, 2, 132, 7, 132, 2, 133, 7, 133, 2, 134, 7, 134, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 6, 3, 6, 291, 8, 6, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 10, 1, 10, 1, 11, 1, 11, 1, 12, 1, 12, 1, 13, 1, 13, 1, 14, 1, 14, 1, 15, 1, 15, 1, 16, 1, 16, 1, 17, 1, 17, 1, 18, 1, 18, 1, 19, 1, 19, 1, 20, 1, 20, 1, 21, 1, 21, 1, 22, 1, 22, 1, 23, 1, 23, 1, 24, 1, 24, 1, 25, 1, 25, 1, 26, 1, 26, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 33, 1, 33, 1, 33, 1, 33, 1, 34, 1, 34, 1, 34, 1, 34, 1, 35, 1, 35, 1, 35, 1, 35, 1, 36, 1, 36, 1, 36, 1, 36, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 38, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 41, 1, 41, 1, 41, 1, 41, 1, 42, 1, 42, 1, 42, 1, 42, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 44, 1, 44, 1, 44, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 54, 1, 54, 1, 54, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 59, 1, 59, 1, 59, 1, 59, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 65, 1, 65, 1, 65, 1, 65, 1, 66, 1, 66, 1, 66, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 70, 1, 70, 1, 70, 1, 71, 1, 71, 1, 71, 1, 72, 1, 72, 1, 72, 1, 72, 1, 73, 1, 73, 1, 73, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 75, 1, 75, 1, 75, 1, 75, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 77, 1, 77, 1, 77, 1, 77, 1, 77, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 80, 1, 80, 1, 80, 1, 81, 1, 81, 1, 81, 1, 81, 1, 82, 1, 82, 1, 82, 1, 82, 1, 82, 1, 82, 1, 82, 1, 82, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 84, 1, 84, 1, 84, 1, 84, 1, 84, 1, 85, 1, 85, 1, 85, 1, 85, 1, 85, 1, 86, 1, 86, 1, 86, 1, 86, 1, 86, 1, 87, 1, 87, 1, 87, 1, 87, 1, 87, 1, 88, 1, 88, 1, 88, 1, 88, 1, 89, 1, 89, 1, 89, 1, 89, 1, 89, 1, 89, 1, 89, 1, 89, 1, 89, 1, 89, 1, 90, 1, 90, 1, 90, 1, 90, 1, 90, 1, 90, 1, 90, 1, 91, 1, 91, 1, 91, 1, 92, 1, 92, 1, 92, 1, 92, 1, 93, 1, 93, 1, 93, 1, 93, 1, 93, 1, 94, 1, 94, 1, 94, 1, 94, 1, 94, 1, 94, 1, 95, 1, 95, 1, 95, 1, 95, 1, 95, 1, 95, 1, 95, 1, 95, 1, 96, 1, 96, 1, 96, 1, 96, 1, 96, 1, 96, 1, 96, 1, 97, 1, 97, 1, 97, 1, 97, 1, 97, 1, 97, 1, 97, 1, 97, 1, 98, 1, 98, 1, 98, 1, 98, 1, 98, 1, 98, 1, 98, 1, 98, 1, 99, 1, 99, 1, 99, 1, 99, 1, 99, 1, 100, 1, 100, 1, 100, 1, 100, 1, 100, 1, 100, 1, 100, 1, 100, 1, 100, 1, 100, 1, 100, 1, 100, 1, 101, 1, 101, 1, 101, 1, 101, 1, 101, 1, 101, 1, 101, 1, 101, 1, 101, 1, 101, 1, 101, 1, 102, 1, 102, 1, 102, 1, 102, 1, 102, 1, 102, 1, 102, 1, 102, 1, 102, 1, 102, 1, 103, 1, 103, 1, 103, 1, 103, 1, 103, 1, 103, 1, 103, 1, 103, 1, 103, 1, 104, 1, 104, 1, 104, 1, 104, 1, 104, 1, 104, 1, 104, 1, 104, 1, 104, 1, 104, 1, 105, 1, 105, 1, 105, 1, 105, 1, 105, 1, 105, 1, 105, 1, 105, 1, 105, 1, 106, 1, 106, 1, 106, 1, 106, 1, 106, 1, 106, 1, 106, 1, 106, 1, 107, 1, 107, 1, 107, 1, 107, 1, 107, 1, 108, 1, 108, 1, 108, 1, 109, 1, 109, 1, 109, 1, 109, 1, 109, 1, 109, 1, 109, 1, 109, 1, 109, 1, 109, 1, 109, 1, 109, 1, 109, 1, 110, 1, 110, 1, 110, 1, 110, 1, 110, 1, 111, 1, 111, 1, 111, 1, 111, 1, 111, 1, 111, 1, 111, 1, 112, 1, 112, 1, 112, 1, 112, 1, 113, 1, 113, 1, 113, 1, 113, 1, 113, 1, 114, 1, 114, 1, 114, 1, 114, 1, 114, 1, 114, 1, 114, 1, 114, 1, 114, 1, 114, 1, 114, 1, 114, 1, 114, 1, 115, 1, 115, 1, 115, 1, 115, 1, 115, 1, 115, 1, 115, 1, 115, 1, 115, 1, 115, 1, 115, 1, 115, 1, 115, 1, 115, 1, 115, 1, 115, 1, 115, 1, 116, 3, 116, 897, 8, 116, 1, 116, 4, 116, 900, 8, 116, 11, 116, 12, 116, 901, 1, 116, 1, 116, 4, 116, 906, 8, 116, 11, 116, 12, 116, 907, 1, 116, 1, 116, 4, 116, 912, 8, 116, 11, 116, 12, 116, 913, 3, 116, 916, 8, 116, 1, 116, 3, 116, 919, 8, 116, 1, 116, 3, 116, 922, 8, 116, 1, 116, 4, 116, 925, 8, 116, 11, 116, 12, 116, 926, 1, 116, 1, 116, 3, 116, 931, 8, 116, 1, 116, 3, 116, 934, 8, 116, 3, 116, 936, 8, 116, 1, 117, 3, 117, 939, 8, 117, 1, 117, 1, 117, 1, 118, 1, 118, 1, 118, 3, 118, 946, 8, 118, 1, 119, 1, 119, 5, 119, 950, 8, 119, 10, 119, 12, 119, 953, 9, 119, 1, 120, 1, 120, 5, 120, 957, 8, 120, 10, 120, 12, 120, 960, 9, 120, 1, 120, 1, 120, 1, 121, 1, 121, 1, 121, 5, 121, 967, 8, 121, 10, 121, 12, 121, 970, 9, 121, 1, 121, 1, 121, 1, 122, 1, 122, 1, 122, 5, 122, 977, 8, 122, 10, 122, 12, 122, 980, 9, 122, 1, 122, 1, 122, 1, 123, 4, 123, 985, 8, 123, 11, 123, 12, 123, 986, 1, 123, 1, 123, 1, 124, 1, 124, 1, 124, 1, 124, 5, 124, 995, 8, 124, 10, 124, 12, 124, 998, 9, 124, 1, 124, 1, 124, 1, 124, 1, 124, 1, 124, 1, 125, 1, 125, 1, 125, 1, 125, 5, 125, 1009, 8, 125, 10, 125, 12, 125, 1012, 9, 125, 1, 125, 1, 125, 1, 126, 1, 126, 1, 127, 1, 127, 1, 127, 1, 127, 3, 127, 1022, 8, 127, 1, 127, 3, 127, 1025, 8, 127, 1, 127, 1, 127, 1, 127, 4, 127, 1030, 8, 127, 11, 127, 12, 127, 1031, 1, 127, 1, 127, 1, 127, 1, 127, 1, 127, 3, 127, 1039, 8, 127, 1, 128, 1, 128, 3, 128, 1043, 8, 128, 1, 128, 1, 128, 1, 129, 1, 129, 1, 129, 4, 129, 1050, 8, 129, 11, 129, 12, 129, 1051, 1, 130, 1, 130, 1, 131, 1, 131, 3, 131, 1058, 8, 131, 1, 131, 4, 131, 1061, 8, 131, 11, 131, 12, 131, 1062, 1, 132, 1, 132, 1, 132, 5, 132, 1068, 8, 132, 10, 132, 12, 132, 1071, 9, 132, 3, 132, 1073, 8, 132, 1, 133, 1, 133, 3, 133, 1077, 8, 133, 1, 134, 1, 134, 1, 134, 1, 134, 3, 134, 1083, 8, 134, 2, 958, 996, 0, 135, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, 9, 19, 10, 21, 11, 23, 12, 25, 13, 27, 14, 29, 15, 31, 16, 33, 17, 35, 18, 37, 19, 39, 20, 41, 21, 43, 22, 45, 23, 47, 24, 49, 25, 51, 26, 53, 27, 55, 28, 57, 29, 59, 30, 61, 31, 63, 32, 65, 33, 67, 34, 69, 35, 71, 36, 73, 37, 75, 38, 77, 39, 79, 40, 81, 41, 83, 42, 85, 43, 87, 44, 89, 45, 91, 46, 93, 47, 95, 48, 97, 49, 99, 50, 101, 51, 103, 52, 105, 53, 107, 54, 109, 55, 111, 56, 113, 57, 115, 58, 117, 59, 119, 60, 121, 61, 123, 62, 125, 63, 127, 64, 129, 65, 131, 66, 133, 67, 135, 68, 137, 69, 139, 70, 141, 71, 143, 72, 145, 73, 147, 74, 149, 75, 151, 76, 153, 77, 155, 78, 157, 79, 159, 80, 161, 81, 163, 82, 165, 83, 167, 84, 169, 85, 171, 86, 173, 87, 175, 88, 177, 89, 179, 90, 181, 91, 183, 92, 185, 93, 187, 94, 189, 95, 191, 96, 193, 97, 195, 98, 197, 99, 199, 100, 201, 101, 203, 102, 205, 103, 207, 104, 209, 105, 211, 106, 213, 107, 215, 108, 217, 109, 219, 110, 221, 111, 223, 112, 225, 113, 227, 114, 229, 115, 231, 116, 233, 117, 235, 118, 237, 119, 239, 120, 241, 121, 243, 122, 245, 123, 247, 124, 249, 125, 251, 126, 253, 127, 255, 0, 257, 0, 259, 0, 261, 0, 263, 0, 265, 0, 267, 0, 269, 128, 1, 0, 40, 2, 0, 67, 67, 99, 99, 2, 0, 65, 65, 97, 97, 2, 0, 76, 76, 108, 108, 2, 0, 89, 89, 121, 121, 2, 0, 73, 73, 105, 105, 2, 0, 69, 69, 101, 101, 2, 0, 68, 68, 100, 100, 2, 0, 70, 70, 102, 102, 2, 0, 84, 84, 116, 116, 2, 0, 82, 82, 114, 114, 2, 0, 88, 88, 120, 120, 2, 0, 79, 79, 111, 111, 2, 0, 85, 85, 117, 117, 2, 0, 78, 78, 110, 110, 2, 0, 83, 83, 115, 115, 2, 0, 77, 77, 109, 109, 2, 0, 86, 86, 118, 118, 2, 0, 71, 71, 103, 103, 2, 0, 66, 66, 98, 98, 2, 0, 72, 72, 104, 104, 2, 0, 80, 80, 112, 112, 2, 0, 75, 75, 107, 107, 2, 0, 87, 87, 119, 119, 2, 0, 81, 81, 113, 113, 1, 0, 48, 57, 4, 0, 68, 68, 70, 70, 100, 100, 102, 102, 4, 0, 10, 10, 13, 13, 39, 39, 92, 92, 4, 0, 10, 10, 13, 13, 34, 34, 92, 92, 3, 0, 9, 10, 12, 13, 32, 32, 2, 0, 10, 10, 13, 13, 14, 0, 34, 34, 39, 39, 46, 47, 66, 66, 70, 70, 78, 78, 82, 82, 84, 85, 92, 92, 98, 98, 102, 102, 110, 110, 114, 114, 116, 117, 1, 0, 48, 51, 1, 0, 48, 55, 2, 0, 43, 43, 45, 45, 3, 0, 48, 57, 65, 70, 97, 102, 1, 0, 49, 57, 3, 0, 65, 90, 95, 95, 97, 122, 2, 0, 0, 127, 55296, 56319, 1, 0, 55296, 56319, 1, 0, 56320, 57343, 1114, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 43, 1, 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 51, 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0, 0, 57, 1, 0, 0, 0, 0, 59, 1, 0, 0, 0, 0, 61, 1, 0, 0, 0, 0, 63, 1, 0, 0, 0, 0, 65, 1, 0, 0, 0, 0, 67, 1, 0, 0, 0, 0, 69, 1, 0, 0, 0, 0, 71, 1, 0, 0, 0, 0, 73, 1, 0, 0, 0, 0, 75, 1, 0, 0, 0, 0, 77, 1, 0, 0, 0, 0, 79, 1, 0, 0, 0, 0, 81, 1, 0, 0, 0, 0, 83, 1, 0, 0, 0, 0, 85, 1, 0, 0, 0, 0, 87, 1, 0, 0, 0, 0, 89, 1, 0, 0, 0, 0, 91, 1, 0, 0, 0, 0, 93, 1, 0, 0, 0, 0, 95, 1, 0, 0, 0, 0, 97, 1, 0, 0, 0, 0, 99, 1, 0, 0, 0, 0, 101, 1, 0, 0, 0, 0, 103, 1, 0, 0, 0, 0, 105, 1, 0, 0, 0, 0, 107, 1, 0, 0, 0, 0, 109, 1, 0, 0, 0, 0, 111, 1, 0, 0, 0, 0, 113, 1, 0, 0, 0, 0, 115, 1, 0, 0, 0, 0, 117, 1, 0, 0, 0, 0, 119, 1, 0, 0, 0, 0, 121, 1, 0, 0, 0, 0, 123, 1, 0, 0, 0, 0, 125, 1, 0, 0, 0, 0, 127, 1, 0, 0, 0, 0, 129, 1, 0, 0, 0, 0, 131, 1, 0, 0, 0, 0, 133, 1, 0, 0, 0, 0, 135, 1, 0, 0, 0, 0, 137, 1, 0, 0, 0, 0, 139, 1, 0, 0, 0, 0, 141, 1, 0, 0, 0, 0, 143, 1, 0, 0, 0, 0, 145, 1, 0, 0, 0, 0, 147, 1, 0, 0, 0, 0, 149, 1, 0, 0, 0, 0, 151, 1, 0, 0, 0, 0, 153, 1, 0, 0, 0, 0, 155, 1, 0, 0, 0, 0, 157, 1, 0, 0, 0, 0, 159, 1, 0, 0, 0, 0, 161, 1, 0, 0, 0, 0, 163, 1, 0, 0, 0, 0, 165, 1, 0, 0, 0, 0, 167, 1, 0, 0, 0, 0, 169, 1, 0, 0, 0, 0, 171, 1, 0, 0, 0, 0, 173, 1, 0, 0, 0, 0, 175, 1, 0, 0, 0, 0, 177, 1, 0, 0, 0, 0, 179, 1, 0, 0, 0, 0, 181, 1, 0, 0, 0, 0, 183, 1, 0, 0, 0, 0, 185, 1, 0, 0, 0, 0, 187, 1, 0, 0, 0, 0, 189, 1, 0, 0, 0, 0, 191, 1, 0, 0, 0, 0, 193, 1, 0, 0, 0, 0, 195, 1, 0, 0, 0, 0, 197, 1, 0, 0, 0, 0, 199, 1, 0, 0, 0, 0, 201, 1, 0, 0, 0, 0, 203, 1, 0, 0, 0, 0, 205, 1, 0, 0, 0, 0, 207, 1, 0, 0, 0, 0, 209, 1, 0, 0, 0, 0, 211, 1, 0, 0, 0, 0, 213, 1, 0, 0, 0, 0, 215, 1, 0, 0, 0, 0, 217, 1, 0, 0, 0, 0, 219, 1, 0, 0, 0, 0, 221, 1, 0, 0, 0, 0, 223, 1, 0, 0, 0, 0, 225, 1, 0, 0, 0, 0, 227, 1, 0, 0, 0, 0, 229, 1, 0, 0, 0, 0, 231, 1, 0, 0, 0, 0, 233, 1, 0, 0, 0, 0, 235, 1, 0, 0, 0, 0, 237, 1, 0, 0, 0, 0, 239, 1, 0, 0, 0, 0, 241, 1, 0, 0, 0, 0, 243, 1, 0, 0, 0, 0, 245, 1, 0, 0, 0, 0, 247, 1, 0, 0, 0, 0, 249, 1, 0, 0, 0, 0, 251, 1, 0, 0, 0, 0, 253, 1, 0, 0, 0, 0, 269, 1, 0, 0, 0, 1, 271, 1, 0, 0, 0, 3, 273, 1, 0, 0, 0, 5, 276, 1, 0, 0, 0, 7, 279, 1, 0, 0, 0, 9, 282, 1, 0, 0, 0, 11, 284, 1, 0, 0, 0, 13, 290, 1, 0, 0, 0, 15, 292, 1, 0, 0, 0, 17, 295, 1, 0, 0, 0, 19, 298, 1, 0, 0, 0, 21, 300, 1, 0, 0, 0, 23, 302, 1, 0, 0, 0, 25, 304, 1, 0, 0, 0, 27, 306, 1, 0, 0, 0, 29, 308, 1, 0, 0, 0, 31, 310, 1, 0, 0, 0, 33, 312, 1, 0, 0, 0, 35, 314, 1, 0, 0, 0, 37, 316, 1, 0, 0, 0, 39, 318, 1, 0, 0, 0, 41, 320, 1, 0, 0, 0, 43, 322, 1, 0, 0, 0, 45, 324, 1, 0, 0, 0, 47, 326, 1, 0, 0, 0, 49, 328, 1, 0, 0, 0, 51, 330, 1, 0, 0, 0, 53, 332, 1, 0, 0, 0, 55, 334, 1, 0, 0, 0, 57, 336, 1, 0, 0, 0, 59, 341, 1, 0, 0, 0, 61, 347, 1, 0, 0, 0, 63, 354, 1, 0, 0, 0, 65, 362, 1, 0, 0, 0, 67, 368, 1, 0, 0, 0, 69, 372, 1, 0, 0, 0, 71, 376, 1, 0, 0, 0, 73, 380, 1, 0, 0, 0, 75, 384, 1, 0, 0, 0, 77, 392, 1, 0, 0, 0, 79, 396, 1, 0, 0, 0, 81, 401, 1, 0, 0, 0, 83, 408, 1, 0, 0, 0, 85, 412, 1, 0, 0, 0, 87, 416, 1, 0, 0, 0, 89, 426, 1, 0, 0, 0, 91, 429, 1, 0, 0, 0, 93, 436, 1, 0, 0, 0, 95, 443, 1, 0, 0, 0, 97, 448, 1, 0, 0, 0, 99, 459, 1, 0, 0, 0, 101, 466, 1, 0, 0, 0, 103, 473, 1, 0, 0, 0, 105, 479, 1, 0, 0, 0, 107, 485, 1, 0, 0, 0, 109, 491, 1, 0, 0, 0, 111, 494, 1, 0, 0, 0, 113, 503, 1, 0, 0, 0, 115, 509, 1, 0, 0, 0, 117, 516, 1, 0, 0, 0, 119, 523, 1, 0, 0, 0, 121, 527, 1, 0, 0, 0, 123, 532, 1, 0, 0, 0, 125, 538, 1, 0, 0, 0, 127, 543, 1, 0, 0, 0, 129, 549, 1, 0, 0, 0, 131, 556, 1, 0, 0, 0, 133, 560, 1, 0, 0, 0, 135, 563, 1, 0, 0, 0, 137, 572, 1, 0, 0, 0, 139, 581, 1, 0, 0, 0, 141, 586, 1, 0, 0, 0, 143, 589, 1, 0, 0, 0, 145, 592, 1, 0, 0, 0, 147, 596, 1, 0, 0, 0, 149, 599, 1, 0, 0, 0, 151, 606, 1, 0, 0, 0, 153, 610, 1, 0, 0, 0, 155, 616, 1, 0, 0, 0, 157, 621, 1, 0, 0, 0, 159, 626, 1, 0, 0, 0, 161, 637, 1, 0, 0, 0, 163, 640, 1, 0, 0, 0, 165, 644, 1, 0, 0, 0, 167, 652, 1, 0, 0, 0, 169, 659, 1, 0, 0, 0, 171, 664, 1, 0, 0, 0, 173, 669, 1, 0, 0, 0, 175, 674, 1, 0, 0, 0, 177, 679, 1, 0, 0, 0, 179, 683, 1, 0, 0, 0, 181, 693, 1, 0, 0, 0, 183, 700, 1, 0, 0, 0, 185, 703, 1, 0, 0, 0, 187, 707, 1, 0, 0, 0, 189, 712, 1, 0, 0, 0, 191, 718, 1, 0, 0, 0, 193, 726, 1, 0, 0, 0, 195, 733, 1, 0, 0, 0, 197, 741, 1, 0, 0, 0, 199, 749, 1, 0, 0, 0, 201, 754, 1, 0, 0, 0, 203, 766, 1, 0, 0, 0, 205, 777, 1, 0, 0, 0, 207, 787, 1, 0, 0, 0, 209, 796, 1, 0, 0, 0, 211, 806, 1, 0, 0, 0, 213, 815, 1, 0, 0, 0, 215, 823, 1, 0, 0, 0, 217, 828, 1, 0, 0, 0, 219, 831, 1, 0, 0, 0, 221, 844, 1, 0, 0, 0, 223, 849, 1, 0, 0, 0, 225, 856, 1, 0, 0, 0, 227, 860, 1, 0, 0, 0, 229, 865, 1, 0, 0, 0, 231, 878, 1, 0, 0, 0, 233, 896, 1, 0, 0, 0, 235, 938, 1, 0, 0, 0, 237, 945, 1, 0, 0, 0, 239, 947, 1, 0, 0, 0, 241, 954, 1, 0, 0, 0, 243, 963, 1, 0, 0, 0, 245, 973, 1, 0, 0, 0, 247, 984, 1, 0, 0, 0, 249, 990, 1, 0, 0, 0, 251, 1004, 1, 0, 0, 0, 253, 1015, 1, 0, 0, 0, 255, 1038, 1, 0, 0, 0, 257, 1040, 1, 0, 0, 0, 259, 1046, 1, 0, 0, 0, 261, 1053, 1, 0, 0, 0, 263, 1055, 1, 0, 0, 0, 265, 1072, 1, 0, 0, 0, 267, 1076, 1, 0, 0, 0, 269, 1082, 1, 0, 0, 0, 271, 272, 5, 61, 0, 0, 272, 2, 1, 0, 0, 0, 273, 274, 5, 43, 0, 0, 274, 275, 5, 61, 0, 0, 275, 4, 1, 0, 0, 0, 276, 277, 5, 60, 0, 0, 277, 278, 5, 61, 0, 0, 278, 6, 1, 0, 0, 0, 279, 280, 5, 62, 0, 0, 280, 281, 5, 61, 0, 0, 281, 8, 1, 0, 0, 0, 282, 283, 5, 62, 0, 0, 283, 10, 1, 0, 0, 0, 284, 285, 5, 60, 0, 0, 285, 12, 1, 0, 0, 0, 286, 287, 5, 60, 0, 0, 287, 291, 5, 62, 0, 0, 288, 289, 5, 33, 0, 0, 289, 291, 5, 61, 0, 0, 290, 286, 1, 0, 0, 0, 290, 288, 1, 0, 0, 0, 291, 14, 1, 0, 0, 0, 292, 293, 5, 61, 0, 0, 293, 294, 5, 126, 0, 0, 294, 16, 1, 0, 0, 0, 295, 296, 5, 46, 0, 0, 296, 297, 5, 46, 0, 0, 297, 18, 1, 0, 0, 0, 298, 299, 5, 59, 0, 0, 299, 20, 1, 0, 0, 0, 300, 301, 5, 46, 0, 0, 301, 22, 1, 0, 0, 0, 302, 303, 5, 44, 0, 0, 303, 24, 1, 0, 0, 0, 304, 305, 5, 40, 0, 0, 305, 26, 1, 0, 0, 0, 306, 307, 5, 41, 0, 0, 307, 28, 1, 0, 0, 0, 308, 309, 5, 123, 0, 0, 309, 30, 1, 0, 0, 0, 310, 311, 5, 125, 0, 0, 311, 32, 1, 0, 0, 0, 312, 313, 5, 91, 0, 0, 313, 34, 1, 0, 0, 0, 314, 315, 5, 93, 0, 0, 315, 36, 1, 0, 0, 0, 316, 317, 5, 45, 0, 0, 317, 38, 1, 0, 0, 0, 318, 319, 5, 43, 0, 0, 319, 40, 1, 0, 0, 0, 320, 321, 5, 47, 0, 0, 321, 42, 1, 0, 0, 0, 322, 323, 5, 37, 0, 0, 323, 44, 1, 0, 0, 0, 324, 325, 5, 94, 0, 0, 325, 46, 1, 0, 0, 0, 326, 327, 5, 42, 0, 0, 327, 48, 1, 0, 0, 0, 328, 329, 5, 96, 0, 0, 329, 50, 1, 0, 0, 0, 330, 331, 5, 58, 0, 0, 331, 52, 1, 0, 0, 0, 332, 333, 5, 124, 0, 0, 333, 54, 1, 0, 0, 0, 334, 335, 5, 36, 0, 0, 335, 56, 1, 0, 0, 0, 336, 337, 7, 0, 0, 0, 337, 338, 7, 1, 0, 0, 338, 339, 7, 2, 0, 0, 339, 340, 7, 2, 0, 0, 340, 58, 1, 0, 0, 0, 341, 342, 7, 3, 0, 0, 342, 343, 7, 4, 0, 0, 343, 344, 7, 5, 0, 0, 344, 345, 7, 2, 0, 0, 345, 346, 7, 6, 0, 0, 346, 60, 1, 0, 0, 0, 347, 348, 7, 7, 0, 0, 348, 349, 7, 4, 0, 0, 349, 350, 7, 2, 0, 0, 350, 351, 7, 8, 0, 0, 351, 352, 7, 5, 0, 0, 352, 353, 7, 9, 0, 0, 353, 62, 1, 0, 0, 0, 354, 355, 7, 5, 0, 0, 355, 356, 7, 10, 0, 0, 356, 357, 7, 8, 0, 0, 357, 358, 7, 9, 0, 0, 358, 359, 7, 1, 0, 0, 359, 360, 7, 0, 0, 0, 360, 361, 7, 8, 0, 0, 361, 64, 1, 0, 0, 0, 362, 363, 7, 0, 0, 0, 363, 364, 7, 11, 0, 0, 364, 365, 7, 12, 0, 0, 365, 366, 7, 13, 0, 0, 366, 367, 7, 8, 0, 0, 367, 66, 1, 0, 0, 0, 368, 369, 7, 14, 0, 0, 369, 370, 7, 12, 0, 0, 370, 371, 7, 15, 0, 0, 371, 68, 1, 0, 0, 0, 372, 373, 7, 1, 0, 0, 373, 374, 7, 16, 0, 0, 374, 375, 7, 17, 0, 0, 375, 70, 1, 0, 0, 0, 376, 377, 7, 15, 0, 0, 377, 378, 7, 4, 0, 0, 378, 379, 7, 13, 0, 0, 379, 72, 1, 0, 0, 0, 380, 381, 7, 15, 0, 0, 381, 382, 7, 1, 0, 0, 382, 383, 7, 10, 0, 0, 383, 74, 1, 0, 0, 0, 384, 385, 7, 0, 0, 0, 385, 386, 7, 11, 0, 0, 386, 387, 7, 2, 0, 0, 387, 388, 7, 2, 0, 0, 388, 389, 7, 5, 0, 0, 389, 390, 7, 0, 0, 0, 390, 391, 7, 8, 0, 0, 391, 76, 1, 0, 0, 0, 392, 393, 7, 1, 0, 0, 393, 394, 7, 13, 0, 0, 394, 395, 7, 3, 0, 0, 395, 78, 1, 0, 0, 0, 396, 397, 7, 13, 0, 0, 397, 398, 7, 11, 0, 0, 398, 399, 7, 13, 0, 0, 399, 400, 7, 5, 0, 0, 400, 80, 1, 0, 0, 0, 401, 402, 7, 14, 0, 0, 402, 403, 7, 4, 0, 0, 403, 404, 7, 13, 0, 0, 404, 405, 7, 17, 0, 0, 405, 406, 7, 2, 0, 0, 406, 407, 7, 5, 0, 0, 407, 82, 1, 0, 0, 0, 408, 409, 7, 1, 0, 0, 409, 410, 7, 2, 0, 0, 410, 411, 7, 2, 0, 0, 411, 84, 1, 0, 0, 0, 412, 413, 7, 1, 0, 0, 413, 414, 7, 14, 0, 0, 414, 415, 7, 0, 0, 0, 415, 86, 1, 0, 0, 0, 416, 417, 7, 1, 0, 0, 417, 418, 7, 14, 0, 0, 418, 419, 7, 0, 0, 0, 419, 420, 7, 5, 0, 0, 420, 421, 7, 13, 0, 0, 421, 422, 7, 6, 0, 0, 422, 423, 7, 4, 0, 0, 423, 424, 7, 13, 0, 0, 424, 425, 7, 17, 0, 0, 425, 88, 1, 0, 0, 0, 426, 427, 7, 18, 0, 0, 427, 428, 7, 3, 0, 0, 428, 90, 1, 0, 0, 0, 429, 430, 7, 0, 0, 0, 430, 431, 7, 9, 0, 0, 431, 432, 7, 5, 0, 0, 432, 433, 7, 1, 0, 0, 433, 434, 7, 8, 0, 0, 434, 435, 7, 5, 0, 0, 435, 92, 1, 0, 0, 0, 436, 437, 7, 6, 0, 0, 437, 438, 7, 5, 0, 0, 438, 439, 7, 2, 0, 0, 439, 440, 7, 5, 0, 0, 440, 441, 7, 8, 0, 0, 441, 442, 7, 5, 0, 0, 442, 94, 1, 0, 0, 0, 443, 444, 7, 6, 0, 0, 444, 445, 7, 5, 0, 0, 445, 446, 7, 14, 0, 0, 446, 447, 7, 0, 0, 0, 447, 96, 1, 0, 0, 0, 448, 449, 7, 6, 0, 0, 449, 450, 7, 5, 0, 0, 450, 451, 7, 14, 0, 0, 451, 452, 7, 0, 0, 0, 452, 453, 7, 5, 0, 0, 453, 454, 7, 13, 0, 0, 454, 455, 7, 6, 0, 0, 455, 456, 7, 4, 0, 0, 456, 457, 7, 13, 0, 0, 457, 458, 7, 17, 0, 0, 458, 98, 1, 0, 0, 0, 459, 460, 7, 6, 0, 0, 460, 461, 7, 5, 0, 0, 461, 462, 7, 8, 0, 0, 462, 463, 7, 1, 0, 0, 463, 464, 7, 0, 0, 0, 464, 465, 7, 19, 0, 0, 465, 100, 1, 0, 0, 0, 466, 467, 7, 5, 0, 0, 467, 468, 7, 10, 0, 0, 468, 469, 7, 4, 0, 0, 469, 470, 7, 14, 0, 0, 470, 471, 7, 8, 0, 0, 471, 472, 7, 14, 0, 0, 472, 102, 1, 0, 0, 0, 473, 474, 7, 2, 0, 0, 474, 475, 7, 4, 0, 0, 475, 476, 7, 15, 0, 0, 476, 477, 7, 4, 0, 0, 477, 478, 7, 8, 0, 0, 478, 104, 1, 0, 0, 0, 479, 480, 7, 15, 0, 0, 480, 481, 7, 1, 0, 0, 481, 482, 7, 8, 0, 0, 482, 483, 7, 0, 0, 0, 483, 484, 7, 19, 0, 0, 484, 106, 1, 0, 0, 0, 485, 486, 7, 15, 0, 0, 486, 487, 7, 5, 0, 0, 487, 488, 7, 9, 0, 0, 488, 489, 7, 17, 0, 0, 489, 490, 7, 5, 0, 0, 490, 108, 1, 0, 0, 0, 491, 492, 7, 11, 0, 0, 492, 493, 7, 13, 0, 0, 493, 110, 1, 0, 0, 0, 494, 495, 7, 11, 0, 0, 495, 496, 7, 20, 0, 0, 496, 497, 7, 8, 0, 0, 497, 498, 7, 4, 0, 0, 498, 499, 7, 11, 0, 0, 499, 500, 7, 13, 0, 0, 500, 501, 7, 1, 0, 0, 501, 502, 7, 2, 0, 0, 502, 112, 1, 0, 0, 0, 503, 504, 7, 11, 0, 0, 504, 505, 7, 9, 0, 0, 505, 506, 7, 6, 0, 0, 506, 507, 7, 5, 0, 0, 507, 508, 7, 9, 0, 0, 508, 114, 1, 0, 0, 0, 509, 510, 7, 9, 0, 0, 510, 511, 7, 5, 0, 0, 511, 512, 7, 15, 0, 0, 512, 513, 7, 11, 0, 0, 513, 514, 7, 16, 0, 0, 514, 515, 7, 5, 0, 0, 515, 116, 1, 0, 0, 0, 516, 517, 7, 9, 0, 0, 517, 518, 7, 5, 0, 0, 518, 519, 7, 8, 0, 0, 519, 520, 7, 12, 0, 0, 520, 521, 7, 9, 0, 0, 521, 522, 7, 13, 0, 0, 522, 118, 1, 0, 0, 0, 523, 524, 7, 14, 0, 0, 524, 525, 7, 5, 0, 0, 525, 526, 7, 8, 0, 0, 526, 120, 1, 0, 0, 0, 527, 528, 7, 14, 0, 0, 528, 529, 7, 21, 0, 0, 529, 530, 7, 4, 0, 0, 530, 531, 7, 20, 0, 0, 531, 122, 1, 0, 0, 0, 532, 533, 7, 22, 0, 0, 533, 534, 7, 19, 0, 0, 534, 535, 7, 5, 0, 0, 535, 536, 7, 9, 0, 0, 536, 537, 7, 5, 0, 0, 537, 124, 1, 0, 0, 0, 538, 539, 7, 22, 0, 0, 539, 540, 7, 4, 0, 0, 540, 541, 7, 8, 0, 0, 541, 542, 7, 19, 0, 0, 542, 126, 1, 0, 0, 0, 543, 544, 7, 12, 0, 0, 544, 545, 7, 13, 0, 0, 545, 546, 7, 4, 0, 0, 546, 547, 7, 11, 0, 0, 547, 548, 7, 13, 0, 0, 548, 128, 1, 0, 0, 0, 549, 550, 7, 12, 0, 0, 550, 551, 7, 13, 0, 0, 551, 552, 7, 22, 0, 0, 552, 553, 7, 4, 0, 0, 553, 554, 7, 13, 0, 0, 554, 555, 7, 6, 0, 0, 555, 130, 1, 0, 0, 0, 556, 557, 7, 1, 0, 0, 557, 558, 7, 13, 0, 0, 558, 559, 7, 6, 0, 0, 559, 132, 1, 0, 0, 0, 560, 561, 7, 1, 0, 0, 561, 562, 7, 14, 0, 0, 562, 134, 1, 0, 0, 0, 563, 564, 7, 0, 0, 0, 564, 565, 7, 11, 0, 0, 565, 566, 7, 13, 0, 0, 566, 567, 7, 8, 0, 0, 567, 568, 7, 1, 0, 0, 568, 569, 7, 4, 0, 0, 569, 570, 7, 13, 0, 0, 570, 571, 7, 14, 0, 0, 571, 136, 1, 0, 0, 0, 572, 573, 7, 6, 0, 0, 573, 574, 7, 4, 0, 0, 574, 575, 7, 14, 0, 0, 575, 576, 7, 8, 0, 0, 576, 577, 7, 4, 0, 0, 577, 578, 7, 13, 0, 0, 578, 579, 7, 0, 0, 0, 579, 580, 7, 8, 0, 0, 580, 138, 1, 0, 0, 0, 581, 582, 7, 5, 0, 0, 582, 583, 7, 13, 0, 0, 583, 584, 7, 6, 0, 0, 584, 585, 7, 14, 0, 0, 585, 140, 1, 0, 0, 0, 586, 587, 7, 4, 0, 0, 587, 588, 7, 13, 0, 0, 588, 142, 1, 0, 0, 0, 589, 590, 7, 4, 0, 0, 590, 591, 7, 14, 0, 0, 591, 144, 1, 0, 0, 0, 592, 593, 7, 13, 0, 0, 593, 594, 7, 11, 0, 0, 594, 595, 7, 8, 0, 0, 595, 146, 1, 0, 0, 0, 596, 597, 7, 11, 0, 0, 597, 598, 7, 9, 0, 0, 598, 148, 1, 0, 0, 0, 599, 600, 7, 14, 0, 0, 600, 601, 7, 8, 0, 0, 601, 602, 7, 1, 0, 0, 602, 603, 7, 9, 0, 0, 603, 604, 7, 8, 0, 0, 604, 605, 7, 14, 0, 0, 605, 150, 1, 0, 0, 0, 606, 607, 7, 10, 0, 0, 607, 608, 7, 11, 0, 0, 608, 609, 7, 9, 0, 0, 609, 152, 1, 0, 0, 0, 610, 611, 7, 7, 0, 0, 611, 612, 7, 1, 0, 0, 612, 613, 7, 2, 0, 0, 613, 614, 7, 14, 0, 0, 614, 615, 7, 5, 0, 0, 615, 154, 1, 0, 0, 0, 616, 617, 7, 8, 0, 0, 617, 618, 7, 9, 0, 0, 618, 619, 7, 12, 0, 0, 619, 620, 7, 5, 0, 0, 620, 156, 1, 0, 0, 0, 621, 622, 7, 13, 0, 0, 622, 623, 7, 12, 0, 0, 623, 624, 7, 2, 0, 0, 624, 625, 7, 2, 0, 0, 625, 158, 1, 0, 0, 0, 626, 627, 7, 0, 0, 0, 627, 628, 7, 11, 0, 0, 628, 629, 7, 13, 0, 0, 629, 630, 7, 14, 0, 0, 630, 631, 7, 8, 0, 0, 631, 632, 7, 9, 0, 0, 632, 633, 7, 1, 0, 0, 633, 634, 7, 4, 0, 0, 634, 635, 7, 13, 0, 0, 635, 636, 7, 8, 0, 0, 636, 160, 1, 0, 0, 0, 637, 638, 7, 6, 0, 0, 638, 639, 7, 11, 0, 0, 639, 162, 1, 0, 0, 0, 640, 641, 7, 7, 0, 0, 641, 642, 7, 11, 0, 0, 642, 643, 7, 9, 0, 0, 643, 164, 1, 0, 0, 0, 644, 645, 7, 9, 0, 0, 645, 646, 7, 5, 0, 0, 646, 647, 7, 23, 0, 0, 647, 648, 7, 12, 0, 0, 648, 649, 7, 4, 0, 0, 649, 650, 7, 9, 0, 0, 650, 651, 7, 5, 0, 0, 651, 166, 1, 0, 0, 0, 652, 653, 7, 12, 0, 0, 653, 654, 7, 13, 0, 0, 654, 655, 7, 4, 0, 0, 655, 656, 7, 23, 0, 0, 656, 657, 7, 12, 0, 0, 657, 658, 7, 5, 0, 0, 658, 168, 1, 0, 0, 0, 659, 660, 7, 0, 0, 0, 660, 661, 7, 1, 0, 0, 661, 662, 7, 14, 0, 0, 662, 663, 7, 5, 0, 0, 663, 170, 1, 0, 0, 0, 664, 665, 7, 22, 0, 0, 665, 666, 7, 19, 0, 0, 666, 667, 7, 5, 0, 0, 667, 668, 7, 13, 0, 0, 668, 172, 1, 0, 0, 0, 669, 670, 7, 8, 0, 0, 670, 671, 7, 19, 0, 0, 671, 672, 7, 5, 0, 0, 672, 673, 7, 13, 0, 0, 673, 174, 1, 0, 0, 0, 674, 675, 7, 5, 0, 0, 675, 676, 7, 2, 0, 0, 676, 677, 7, 14, 0, 0, 677, 678, 7, 5, 0, 0, 678, 176, 1, 0, 0, 0, 679, 680, 7, 5, 0, 0, 680, 681, 7, 13, 0, 0, 681, 682, 7, 6, 0, 0, 682, 178, 1, 0, 0, 0, 683, 684, 7, 15, 0, 0, 684, 685, 7, 1, 0, 0, 685, 686, 7, 13, 0, 0, 686, 687, 7, 6, 0, 0, 687, 688, 7, 1, 0, 0, 688, 689, 7, 8, 0, 0, 689, 690, 7, 11, 0, 0, 690, 691, 7, 9, 0, 0, 691, 692, 7, 3, 0, 0, 692, 180, 1, 0, 0, 0, 693, 694, 7, 14, 0, 0, 694, 695, 7, 0, 0, 0, 695, 696, 7, 1, 0, 0, 696, 697, 7, 2, 0, 0, 697, 698, 7, 1, 0, 0, 698, 699, 7, 9, 0, 0, 699, 182, 1, 0, 0, 0, 700, 701, 7, 11, 0, 0, 701, 702, 7, 7, 0, 0, 702, 184, 1, 0, 0, 0, 703, 704, 7, 1, 0, 0, 704, 705, 7, 6, 0, 0, 705, 706, 7, 6, 0, 0, 706, 186, 1, 0, 0, 0, 707, 708, 7, 6, 0, 0, 708, 709, 7, 9, 0, 0, 709, 710, 7, 11, 0, 0, 710, 711, 7, 20, 0, 0, 711, 188, 1, 0, 0, 0, 712, 713, 7, 4, 0, 0, 713, 714, 7, 13, 0, 0, 714, 715, 7, 6, 0, 0, 715, 716, 7, 5, 0, 0, 716, 717, 7, 10, 0, 0, 717, 190, 1, 0, 0, 0, 718, 719, 7, 4, 0, 0, 719, 720, 7, 13, 0, 0, 720, 721, 7, 6, 0, 0, 721, 722, 7, 5, 0, 0, 722, 723, 7, 10, 0, 0, 723, 724, 7, 5, 0, 0, 724, 725, 7, 14, 0, 0, 725, 192, 1, 0, 0, 0, 726, 727, 7, 16, 0, 0, 727, 728, 7, 5, 0, 0, 728, 729, 7, 0, 0, 0, 729, 730, 7, 8, 0, 0, 730, 731, 7, 11, 0, 0, 731, 732, 7, 9, 0, 0, 732, 194, 1, 0, 0, 0, 733, 734, 7, 5, 0, 0, 734, 735, 7, 10, 0, 0, 735, 736, 7, 20, 0, 0, 736, 737, 7, 2, 0, 0, 737, 738, 7, 1, 0, 0, 738, 739, 7, 4, 0, 0, 739, 740, 7, 13, 0, 0, 740, 196, 1, 0, 0, 0, 741, 742, 7, 20, 0, 0, 742, 743, 7, 9, 0, 0, 743, 744, 7, 11, 0, 0, 744, 745, 7, 7, 0, 0, 745, 746, 7, 4, 0, 0, 746, 747, 7, 2, 0, 0, 747, 748, 7, 5, 0, 0, 748, 198, 1, 0, 0, 0, 749, 750, 7, 14, 0, 0, 750, 751, 7, 19, 0, 0, 751, 752, 7, 11, 0, 0, 752, 753, 7, 22, 0, 0, 753, 200, 1, 0, 0, 0, 754, 755, 7, 0, 0, 0, 755, 756, 7, 11, 0, 0, 756, 757, 7, 13, 0, 0, 757, 758, 7, 14, 0, 0, 758, 759, 7, 8, 0, 0, 759, 760, 7, 9, 0, 0, 760, 761, 7, 1, 0, 0, 761, 762, 7, 4, 0, 0, 762, 763, 7, 13, 0, 0, 763, 764, 7, 8, 0, 0, 764, 765, 7, 14, 0, 0, 765, 202, 1, 0, 0, 0, 766, 767, 7, 20, 0, 0, 767, 768, 7, 9, 0, 0, 768, 769, 7, 11, 0, 0, 769, 770, 7, 0, 0, 0, 770, 771, 7, 5, 0, 0, 771, 772, 7, 6, 0, 0, 772, 773, 7, 12, 0, 0, 773, 774, 7, 9, 0, 0, 774, 775, 7, 5, 0, 0, 775, 776, 7, 14, 0, 0, 776, 204, 1, 0, 0, 0, 777, 778, 7, 7, 0, 0, 778, 779, 7, 12, 0, 0, 779, 780, 7, 13, 0, 0, 780, 781, 7, 0, 0, 0, 781, 782, 7, 8, 0, 0, 782, 783, 7, 4, 0, 0, 783, 784, 7, 11, 0, 0, 784, 785, 7, 13, 0, 0, 785, 786, 7, 14, 0, 0, 786, 206, 1, 0, 0, 0, 787, 788, 7, 6, 0, 0, 788, 789, 7, 1, 0, 0, 789, 790, 7, 8, 0, 0, 790, 791, 7, 1, 0, 0, 791, 792, 7, 18, 0, 0, 792, 793, 7, 1, 0, 0, 793, 794, 7, 14, 0, 0, 794, 795, 7, 5, 0, 0, 795, 208, 1, 0, 0, 0, 796, 797, 7, 6, 0, 0, 797, 798, 7, 1, 0, 0, 798, 799, 7, 8, 0, 0, 799, 800, 7, 1, 0, 0, 800, 801, 7, 18, 0, 0, 801, 802, 7, 1, 0, 0, 802, 803, 7, 14, 0, 0, 803, 804, 7, 5, 0, 0, 804, 805, 7, 14, 0, 0, 805, 210, 1, 0, 0, 0, 806, 807, 7, 7, 0, 0, 807, 808, 7, 12, 0, 0, 808, 809, 7, 2, 0, 0, 809, 810, 7, 2, 0, 0, 810, 811, 7, 8, 0, 0, 811, 812, 7, 5, 0, 0, 812, 813, 7, 10, 0, 0, 813, 814, 7, 8, 0, 0, 814, 212, 1, 0, 0, 0, 815, 816, 7, 11, 0, 0, 816, 817, 7, 20, 0, 0, 817, 818, 7, 8, 0, 0, 818, 819, 7, 4, 0, 0, 819, 820, 7, 11, 0, 0, 820, 821, 7, 13, 0, 0, 821, 822, 7, 14, 0, 0, 822, 214, 1, 0, 0, 0, 823, 824, 7, 5, 0, 0, 824, 825, 7, 1, 0, 0, 825, 826, 7, 0, 0, 0, 826, 827, 7, 19, 0, 0, 827, 216, 1, 0, 0, 0, 828, 829, 7, 4, 0, 0, 829, 830, 7, 7, 0, 0, 830, 218, 1, 0, 0, 0, 831, 832, 7, 8, 0, 0, 832, 833, 7, 9, 0, 0, 833, 834, 7, 1, 0, 0, 834, 835, 7, 13, 0, 0, 835, 836, 7, 14, 0, 0, 836, 837, 7, 1, 0, 0, 837, 838, 7, 0, 0, 0, 838, 839, 7, 8, 0, 0, 839, 840, 7, 4, 0, 0, 840, 841, 7, 11, 0, 0, 841, 842, 7, 13, 0, 0, 842, 843, 7, 14, 0, 0, 843, 220, 1, 0, 0, 0, 844, 845, 7, 9, 0, 0, 845, 846, 7, 11, 0, 0, 846, 847, 7, 22, 0, 0, 847, 848, 7, 14, 0, 0, 848, 222, 1, 0, 0, 0, 849, 850, 7, 1, 0, 0, 850, 851, 7, 14, 0, 0, 851, 852, 7, 14, 0, 0, 852, 853, 7, 5, 0, 0, 853, 854, 7, 9, 0, 0, 854, 855, 7, 8, 0, 0, 855, 224, 1, 0, 0, 0, 856, 857, 7, 21, 0, 0, 857, 858, 7, 5, 0, 0, 858, 859, 7, 3, 0, 0, 859, 226, 1, 0, 0, 0, 860, 861, 7, 13, 0, 0, 861, 862, 7, 11, 0, 0, 862, 863, 7, 6, 0, 0, 863, 864, 7, 5, 0, 0, 864, 228, 1, 0, 0, 0, 865, 866, 7, 14, 0, 0, 866, 867, 7, 19, 0, 0, 867, 868, 7, 11, 0, 0, 868, 869, 7, 9, 0, 0, 869, 870, 7, 8, 0, 0, 870, 871, 7, 5, 0, 0, 871, 872, 7, 14, 0, 0, 872, 873, 7, 8, 0, 0, 873, 874, 7, 20, 0, 0, 874, 875, 7, 1, 0, 0, 875, 876, 7, 8, 0, 0, 876, 877, 7, 19, 0, 0, 877, 230, 1, 0, 0, 0, 878, 879, 7, 1, 0, 0, 879, 880, 7, 2, 0, 0, 880, 881, 7, 2, 0, 0, 881, 882, 7, 14, 0, 0, 882, 883, 7, 19, 0, 0, 883, 884, 7, 11, 0, 0, 884, 885, 7, 9, 0, 0, 885, 886, 7, 8, 0, 0, 886, 887, 7, 5, 0, 0, 887, 888, 7, 14, 0, 0, 888, 889, 7, 8, 0, 0, 889, 890, 7, 20, 0, 0, 890, 891, 7, 1, 0, 0, 891, 892, 7, 8, 0, 0, 892, 893, 7, 19, 0, 0, 893, 894, 7, 14, 0, 0, 894, 232, 1, 0, 0, 0, 895, 897, 3, 37, 18, 0, 896, 895, 1, 0, 0, 0, 896, 897, 1, 0, 0, 0, 897, 935, 1, 0, 0, 0, 898, 900, 7, 24, 0, 0, 899, 898, 1, 0, 0, 0, 900, 901, 1, 0, 0, 0, 901, 899, 1, 0, 0, 0, 901, 902, 1, 0, 0, 0, 902, 903, 1, 0, 0, 0, 903, 905, 5, 46, 0, 0, 904, 906, 7, 24, 0, 0, 905, 904, 1, 0, 0, 0, 906, 907, 1, 0, 0, 0, 907, 905, 1, 0, 0, 0, 907, 908, 1, 0, 0, 0, 908, 916, 1, 0, 0, 0, 909, 911, 5, 46, 0, 0, 910, 912, 7, 24, 0, 0, 911, 910, 1, 0, 0, 0, 912, 913, 1, 0, 0, 0, 913, 911, 1, 0, 0, 0, 913, 914, 1, 0, 0, 0, 914, 916, 1, 0, 0, 0, 915, 899, 1, 0, 0, 0, 915, 909, 1, 0, 0, 0, 916, 918, 1, 0, 0, 0, 917, 919, 3, 257, 128, 0, 918, 917, 1, 0, 0, 0, 918, 919, 1, 0, 0, 0, 919, 921, 1, 0, 0, 0, 920, 922, 7, 25, 0, 0, 921, 920, 1, 0, 0, 0, 921, 922, 1, 0, 0, 0, 922, 936, 1, 0, 0, 0, 923, 925, 7, 24, 0, 0, 924, 923, 1, 0, 0, 0, 925, 926, 1, 0, 0, 0, 926, 924, 1, 0, 0, 0, 926, 927, 1, 0, 0, 0, 927, 933, 1, 0, 0, 0, 928, 930, 3, 257, 128, 0, 929, 931, 7, 25, 0, 0, 930, 929, 1, 0, 0, 0, 930, 931, 1, 0, 0, 0, 931, 934, 1, 0, 0, 0, 932, 934, 7, 25, 0, 0, 933, 928, 1, 0, 0, 0, 933, 932, 1, 0, 0, 0, 934, 936, 1, 0, 0, 0, 935, 915, 1, 0, 0, 0, 935, 924, 1, 0, 0, 0, 936, 234, 1, 0, 0, 0, 937, 939, 3, 37, 18, 0, 938, 937, 1, 0, 0, 0, 938, 939, 1, 0, 0, 0, 939, 940, 1, 0, 0, 0, 940, 941, 3, 265, 132, 0, 941, 236, 1, 0, 0, 0, 942, 946, 3, 259, 129, 0, 943, 946, 3, 263, 131, 0, 944, 946, 7, 24, 0, 0, 945, 942, 1, 0, 0, 0, 945, 943, 1, 0, 0, 0, 945, 944, 1, 0, 0, 0, 946, 238, 1, 0, 0, 0, 947, 951, 3, 269, 134, 0, 948, 950, 3, 267, 133, 0, 949, 948, 1, 0, 0, 0, 950, 953, 1, 0, 0, 0, 951, 949, 1, 0, 0, 0, 951, 952, 1, 0, 0, 0, 952, 240, 1, 0, 0, 0, 953, 951, 1, 0, 0, 0, 954, 958, 5, 96, 0, 0, 955, 957, 9, 0, 0, 0, 956, 955, 1, 0, 0, 0, 957, 960, 1, 0, 0, 0, 958, 959, 1, 0, 0, 0, 958, 956, 1, 0, 0, 0, 959, 961, 1, 0, 0, 0, 960, 958, 1, 0, 0, 0, 961, 962, 5, 96, 0, 0, 962, 242, 1, 0, 0, 0, 963, 968, 5, 39, 0, 0, 964, 967, 8, 26, 0, 0, 965, 967, 3, 255, 127, 0, 966, 964, 1, 0, 0, 0, 966, 965, 1, 0, 0, 0, 967, 970, 1, 0, 0, 0, 968, 966, 1, 0, 0, 0, 968, 969, 1, 0, 0, 0, 969, 971, 1, 0, 0, 0, 970, 968, 1, 0, 0, 0, 971, 972, 5, 39, 0, 0, 972, 244, 1, 0, 0, 0, 973, 978, 5, 34, 0, 0, 974, 977, 8, 27, 0, 0, 975, 977, 3, 255, 127, 0, 976, 974, 1, 0, 0, 0, 976, 975, 1, 0, 0, 0, 977, 980, 1, 0, 0, 0, 978, 976, 1, 0, 0, 0, 978, 979, 1, 0, 0, 0, 979, 981, 1, 0, 0, 0, 980, 978, 1, 0, 0, 0, 981, 982, 5, 34, 0, 0, 982, 246, 1, 0, 0, 0, 983, 985, 7, 28, 0, 0, 984, 983, 1, 0, 0, 0, 985, 986, 1, 0, 0, 0, 986, 984, 1, 0, 0, 0, 986, 987, 1, 0, 0, 0, 987, 988, 1, 0, 0, 0, 988, 989, 6, 123, 0, 0, 989, 248, 1, 0, 0, 0, 990, 991, 5, 47, 0, 0, 991, 992, 5, 42, 0, 0, 992, 996, 1, 0, 0, 0, 993, 995, 9, 0, 0, 0, 994, 993, 1, 0, 0, 0, 995, 998, 1, 0, 0, 0, 996, 997, 1, 0, 0, 0, 996, 994, 1, 0, 0, 0, 997, 999, 1, 0, 0, 0, 998, 996, 1, 0, 0, 0, 999, 1000, 5, 42, 0, 0, 1000, 1001, 5, 47, 0, 0, 1001, 1002, 1, 0, 0, 0, 1002, 1003, 6, 124, 1, 0, 1003, 250, 1, 0, 0, 0, 1004, 1005, 5, 47, 0, 0, 1005, 1006, 5, 47, 0, 0, 1006, 1010, 1, 0, 0, 0, 1007, 1009, 8, 29, 0, 0, 1008, 1007, 1, 0, 0, 0, 1009, 1012, 1, 0, 0, 0, 1010, 1008, 1, 0, 0, 0, 1010, 1011, 1, 0, 0, 0, 1011, 1013, 1, 0, 0, 0, 1012, 1010, 1, 0, 0, 0, 1013, 1014, 6, 125, 1, 0, 1014, 252, 1, 0, 0, 0, 1015, 1016, 9, 0, 0, 0, 1016, 254, 1, 0, 0, 0, 1017, 1018, 5, 92, 0, 0, 1018, 1039, 7, 30, 0, 0, 1019, 1024, 5, 92, 0, 0, 1020, 1022, 7, 31, 0, 0, 1021, 1020, 1, 0, 0, 0, 1021, 1022, 1, 0, 0, 0, 1022, 1023, 1, 0, 0, 0, 1023, 1025, 7, 32, 0, 0, 1024, 1021, 1, 0, 0, 0, 1024, 1025, 1, 0, 0, 0, 1025, 1026, 1, 0, 0, 0, 1026, 1039, 7, 32, 0, 0, 1027, 1029, 5, 92, 0, 0, 1028, 1030, 7, 12, 0, 0, 1029, 1028, 1, 0, 0, 0, 1030, 1031, 1, 0, 0, 0, 1031, 1029, 1, 0, 0, 0, 1031, 1032, 1, 0, 0, 0, 1032, 1033, 1, 0, 0, 0, 1033, 1034, 3, 261, 130, 0, 1034, 1035, 3, 261, 130, 0, 1035, 1036, 3, 261, 130, 0, 1036, 1037, 3, 261, 130, 0, 1037, 1039, 1, 0, 0, 0, 1038, 1017, 1, 0, 0, 0, 1038, 1019, 1, 0, 0, 0, 1038, 1027, 1, 0, 0, 0, 1039, 256, 1, 0, 0, 0, 1040, 1042, 7, 5, 0, 0, 1041, 1043, 7, 33, 0, 0, 1042, 1041, 1, 0, 0, 0, 1042, 1043, 1, 0, 0, 0, 1043, 1044, 1, 0, 0, 0, 1044, 1045, 3, 265, 132, 0, 1045, 258, 1, 0, 0, 0, 1046, 1047, 5, 48, 0, 0, 1047, 1049, 7, 10, 0, 0, 1048, 1050, 3, 261, 130, 0, 1049, 1048, 1, 0, 0, 0, 1050, 1051, 1, 0, 0, 0, 1051, 1049, 1, 0, 0, 0, 1051, 1052, 1, 0, 0, 0, 1052, 260, 1, 0, 0, 0, 1053, 1054, 7, 34, 0, 0, 1054, 262, 1, 0, 0, 0, 1055, 1057, 5, 48, 0, 0, 1056, 1058, 7, 11, 0, 0, 1057, 1056, 1, 0, 0, 0, 1057, 1058, 1, 0, 0, 0, 1058, 1060, 1, 0, 0, 0, 1059, 1061, 7, 32, 0, 0, 1060, 1059, 1, 0, 0, 0, 1061, 1062, 1, 0, 0, 0, 1062, 1060, 1, 0, 0, 0, 1062, 1063, 1, 0, 0, 0, 1063, 264, 1, 0, 0, 0, 1064, 1073, 5, 48, 0, 0, 1065, 1069, 7, 35, 0, 0, 1066, 1068, 7, 24, 0, 0, 1067, 1066, 1, 0, 0, 0, 1068, 1071, 1, 0, 0, 0, 1069, 1067, 1, 0, 0, 0, 1069, 1070, 1, 0, 0, 0, 1070, 1073, 1, 0, 0, 0, 1071, 1069, 1, 0, 0, 0, 1072, 1064, 1, 0, 0, 0, 1072, 1065, 1, 0, 0, 0, 1073, 266, 1, 0, 0, 0, 1074, 1077, 3, 269, 134, 0, 1075, 1077, 7, 24, 0, 0, 1076, 1074, 1, 0, 0, 0, 1076, 1075, 1, 0, 0, 0, 1077, 268, 1, 0, 0, 0, 1078, 1083, 7, 36, 0, 0, 1079, 1083, 8, 37, 0, 0, 1080, 1081, 7, 38, 0, 0, 1081, 1083, 7, 39, 0, 0, 1082, 1078, 1, 0, 0, 0, 1082, 1079, 1, 0, 0, 0, 1082, 1080, 1, 0, 0, 0, 1083, 270, 1, 0, 0, 0, 36, 0, 290, 896, 901, 907, 913, 915, 918, 921, 926, 930, 933, 935, 938, 945, 951, 958, 966, 968, 976, 978, 986, 996, 1010, 1021, 1024, 1031, 1038, 1042, 1051, 1057, 1062, 1069, 1072, 1076, 1082, 2, 0, 1, 0, 0, 2, 0]
\ No newline at end of file
diff --git a/nornicdb/pkg/cypher/antlr/CypherLexer.tokens b/nornicdb/pkg/cypher/antlr/CypherLexer.tokens
new file mode 100644
index 0000000..663ccb8
--- /dev/null
+++ b/nornicdb/pkg/cypher/antlr/CypherLexer.tokens
@@ -0,0 +1,243 @@
+ASSIGN=1
+ADD_ASSIGN=2
+LE=3
+GE=4
+GT=5
+LT=6
+NOT_EQUAL=7
+REGEX_MATCH=8
+RANGE=9
+SEMI=10
+DOT=11
+COMMA=12
+LPAREN=13
+RPAREN=14
+LBRACE=15
+RBRACE=16
+LBRACK=17
+RBRACK=18
+SUB=19
+PLUS=20
+DIV=21
+MOD=22
+CARET=23
+MULT=24
+ESC=25
+COLON=26
+STICK=27
+DOLLAR=28
+CALL=29
+YIELD=30
+FILTER=31
+EXTRACT=32
+COUNT=33
+SUM=34
+AVG=35
+MIN=36
+MAX=37
+COLLECT=38
+ANY=39
+NONE=40
+SINGLE=41
+ALL=42
+ASC=43
+ASCENDING=44
+BY=45
+CREATE=46
+DELETE=47
+DESC=48
+DESCENDING=49
+DETACH=50
+EXISTS=51
+LIMIT=52
+MATCH=53
+MERGE=54
+ON=55
+OPTIONAL=56
+ORDER=57
+REMOVE=58
+RETURN=59
+SET=60
+SKIP_W=61
+WHERE=62
+WITH=63
+UNION=64
+UNWIND=65
+AND=66
+AS=67
+CONTAINS=68
+DISTINCT=69
+ENDS=70
+IN=71
+IS=72
+NOT=73
+OR=74
+STARTS=75
+XOR=76
+FALSE=77
+TRUE=78
+NULL_W=79
+CONSTRAINT=80
+DO=81
+FOR=82
+REQUIRE=83
+UNIQUE=84
+CASE=85
+WHEN=86
+THEN=87
+ELSE=88
+END=89
+MANDATORY=90
+SCALAR=91
+OF=92
+ADD=93
+DROP=94
+INDEX=95
+INDEXES=96
+VECTOR=97
+EXPLAIN=98
+PROFILE=99
+SHOW=100
+CONSTRAINTS=101
+PROCEDURES=102
+FUNCTIONS=103
+DATABASE=104
+DATABASES=105
+FULLTEXT=106
+OPTIONS=107
+EACH=108
+IF=109
+TRANSACTIONS=110
+ROWS=111
+ASSERT=112
+KEY=113
+NODE=114
+SHORTESTPATH=115
+ALLSHORTESTPATHS=116
+FLOAT=117
+INTEGER=118
+DIGIT=119
+ID=120
+ESC_LITERAL=121
+CHAR_LITERAL=122
+STRING_LITERAL=123
+WS=124
+COMMENT=125
+LINE_COMMENT=126
+ERRCHAR=127
+Letter=128
+'='=1
+'+='=2
+'<='=3
+'>='=4
+'>'=5
+'<'=6
+'=~'=8
+'..'=9
+';'=10
+'.'=11
+','=12
+'('=13
+')'=14
+'{'=15
+'}'=16
+'['=17
+']'=18
+'-'=19
+'+'=20
+'/'=21
+'%'=22
+'^'=23
+'*'=24
+'`'=25
+':'=26
+'|'=27
+'$'=28
+'CALL'=29
+'YIELD'=30
+'FILTER'=31
+'EXTRACT'=32
+'COUNT'=33
+'SUM'=34
+'AVG'=35
+'MIN'=36
+'MAX'=37
+'COLLECT'=38
+'ANY'=39
+'NONE'=40
+'SINGLE'=41
+'ALL'=42
+'ASC'=43
+'ASCENDING'=44
+'BY'=45
+'CREATE'=46
+'DELETE'=47
+'DESC'=48
+'DESCENDING'=49
+'DETACH'=50
+'EXISTS'=51
+'LIMIT'=52
+'MATCH'=53
+'MERGE'=54
+'ON'=55
+'OPTIONAL'=56
+'ORDER'=57
+'REMOVE'=58
+'RETURN'=59
+'SET'=60
+'SKIP'=61
+'WHERE'=62
+'WITH'=63
+'UNION'=64
+'UNWIND'=65
+'AND'=66
+'AS'=67
+'CONTAINS'=68
+'DISTINCT'=69
+'ENDS'=70
+'IN'=71
+'IS'=72
+'NOT'=73
+'OR'=74
+'STARTS'=75
+'XOR'=76
+'FALSE'=77
+'TRUE'=78
+'NULL'=79
+'CONSTRAINT'=80
+'DO'=81
+'FOR'=82
+'REQUIRE'=83
+'UNIQUE'=84
+'CASE'=85
+'WHEN'=86
+'THEN'=87
+'ELSE'=88
+'END'=89
+'MANDATORY'=90
+'SCALAR'=91
+'OF'=92
+'ADD'=93
+'DROP'=94
+'INDEX'=95
+'INDEXES'=96
+'VECTOR'=97
+'EXPLAIN'=98
+'PROFILE'=99
+'SHOW'=100
+'CONSTRAINTS'=101
+'PROCEDURES'=102
+'FUNCTIONS'=103
+'DATABASE'=104
+'DATABASES'=105
+'FULLTEXT'=106
+'OPTIONS'=107
+'EACH'=108
+'IF'=109
+'TRANSACTIONS'=110
+'ROWS'=111
+'ASSERT'=112
+'KEY'=113
+'NODE'=114
+'shortestPath'=115
+'allShortestPaths'=116
diff --git a/nornicdb/pkg/cypher/antlr/CypherParser.g4 b/nornicdb/pkg/cypher/antlr/CypherParser.g4
new file mode 100644
index 0000000..9404ce1
--- /dev/null
+++ b/nornicdb/pkg/cypher/antlr/CypherParser.g4
@@ -0,0 +1,595 @@
+/*
+ [The "BSD licence"]
+ Copyright (c) 2022 Boris Zhguchev
+ All rights reserved.
+
+ Redistribution and use in source and binary forms with or without
+ modification are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT INDIRECT
+ INCIDENTAL SPECIAL EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING BUT
+ NOT LIMITED TO PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE
+ DATA OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY WHETHER IN CONTRACT STRICT LIABILITY OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// $antlr-format alignTrailingComments true, columnLimit 150, minEmptyLines 1, maxEmptyLinesToKeep 1, reflowComments false, useTab false
+// $antlr-format allowShortRulesOnASingleLine false, allowShortBlocksOnASingleLine true, alignSemicolons hanging, alignColons hanging
+
+parser grammar CypherParser;
+
+options {
+ tokenVocab = CypherLexer;
+}
+
+script
+ : query (SEMI query)* SEMI? EOF
+ ;
+
+// statements
+query
+ : queryPrefix? (regularQuery | standaloneCall | schemaCommand | showCommand)
+ ;
+
+// EXPLAIN/PROFILE prefix
+queryPrefix
+ : EXPLAIN
+ | PROFILE
+ ;
+
+// SHOW commands
+showCommand
+ : SHOW (INDEXES | INDEX | CONSTRAINTS | CONSTRAINT | PROCEDURES | FUNCTIONS | DATABASE | DATABASES | ALL?)
+ ;
+
+// Schema commands (DROP INDEX, CREATE INDEX, etc.)
+schemaCommand
+ : DROP INDEX name? (IF EXISTS)?
+ | CREATE INDEX name? (IF NOT EXISTS)? (FOR nodePattern)? ON? parenExpressionChain?
+ | CREATE FULLTEXT INDEX name? (IF NOT EXISTS)? (FOR nodePattern)? ON? EACH? LBRACK expressionChain RBRACK
+ | CREATE VECTOR INDEX name? (IF NOT EXISTS)? (FOR nodePattern)? ON? parenExpressionChain? (OPTIONS mapLit)?
+ | DROP CONSTRAINT name? (IF EXISTS)?
+ | CREATE CONSTRAINT name? (IF NOT EXISTS)? (FOR nodePattern)? REQUIRE expression (IS UNIQUE | IS NOT NULL_W)
+ | CREATE CONSTRAINT name? (IF NOT EXISTS)? ON? nodePattern? ASSERT (expression | parenExpressionChain) IS (UNIQUE | NOT NULL_W | NODE KEY)
+ ;
+
+regularQuery
+ : singleQuery unionSt*
+ ;
+
+singleQuery
+ : singlePartQ
+ | multiPartQ
+ ;
+
+standaloneCall
+ : CALL invocationName parenExpressionChain? (YIELD (MULT | yieldItems))?
+ ;
+
+// Subqueries
+existsSubquery
+ : EXISTS LBRACE matchSt RBRACE
+ ;
+
+countSubquery
+ : COUNT LBRACE matchSt RBRACE
+ ;
+
+callSubquery
+ : CALL LBRACE subqueryBody RBRACE (IN TRANSACTIONS (OF numLit ROWS)?)?
+ ;
+
+// Subquery body can start with WITH (to import variables) or have statements
+subqueryBody
+ : withSt? (readingStatement | updatingStatement)* returnSt?
+ ;
+
+returnSt
+ : RETURN projectionBody
+ ;
+
+withSt
+ : WITH projectionBody where?
+ ;
+
+skipSt
+ : SKIP_W expression
+ ;
+
+limitSt
+ : LIMIT expression
+ ;
+
+projectionBody
+ : DISTINCT? projectionItems orderSt? skipSt? limitSt?
+ ;
+
+projectionItems
+ : (MULT | projectionItem) (COMMA projectionItem)*
+ ;
+
+projectionItem
+ : expression (AS symbol)?
+ ;
+
+orderItem
+ : expression (ASCENDING | ASC | DESCENDING | DESC)?
+ ;
+
+orderSt
+ : ORDER BY orderItem (COMMA orderItem)*
+ ;
+
+singlePartQ
+ : readingStatement* (returnSt | updatingStatement+ returnSt?)?
+ | callSubquery orderSt?
+ ;
+
+multiPartQ
+ : ((readingStatement | updatingStatement)* withSt)+ singlePartQ
+ ;
+
+matchSt
+ : OPTIONAL? MATCH patternWhere
+ ;
+
+unwindSt
+ : UNWIND expression AS symbol where?
+ ;
+
+readingStatement
+ : matchSt
+ | unwindSt
+ | queryCallSt
+ | callSubquery
+ ;
+
+updatingStatement
+ : createSt
+ | mergeSt
+ | deleteSt
+ | setSt
+ | removeSt
+ ;
+
+deleteSt
+ : DETACH? DELETE expressionChain
+ ;
+
+removeSt
+ : REMOVE removeItem (COMMA removeItem)*
+ ;
+
+removeItem
+ : symbol nodeLabels
+ | propertyExpression
+ ;
+
+queryCallSt
+ : CALL invocationName parenExpressionChain (YIELD yieldItems)?
+ ;
+
+parenExpressionChain
+ : LPAREN expressionChain? RPAREN
+ ;
+
+yieldItems
+ : yieldItem (COMMA yieldItem)* where?
+ ;
+
+yieldItem
+ : (symbol AS)? symbol
+ ;
+
+mergeSt
+ : MERGE patternPart mergeAction*
+ ;
+
+mergeAction
+ : ON (MATCH | CREATE) setSt
+ ;
+
+setSt
+ : SET setItem (COMMA setItem)*
+ ;
+
+setItem
+ : propertyExpression ASSIGN expression
+ | symbol (ASSIGN | ADD_ASSIGN) expression
+ | symbol nodeLabels
+ ;
+
+nodeLabels
+ : (COLON name)+
+ ;
+
+createSt
+ : CREATE pattern
+ ;
+
+patternWhere
+ : pattern where?
+ ;
+
+where
+ : WHERE expression
+ ;
+
+pattern
+ : patternPart (COMMA patternPart)*
+ ;
+
+expression
+ : xorExpression (OR xorExpression)*
+ ;
+
+xorExpression
+ : andExpression (XOR andExpression)*
+ ;
+
+andExpression
+ : notExpression (AND notExpression)*
+ ;
+
+notExpression
+ : NOT? comparisonExpression
+ | NOT? existsSubquery
+ | countSubquery comparisonSigns expression
+ ;
+
+comparisonExpression
+ : addSubExpression (comparisonSigns addSubExpression)*
+ ;
+
+comparisonSigns
+ : ASSIGN
+ | LE
+ | GE
+ | GT
+ | LT
+ | NOT_EQUAL
+ | REGEX_MATCH
+ ;
+
+addSubExpression
+ : multDivExpression ((PLUS | SUB) multDivExpression)*
+ ;
+
+multDivExpression
+ : powerExpression ((MULT | DIV | MOD) powerExpression)*
+ ;
+
+powerExpression
+ : unaryAddSubExpression (CARET unaryAddSubExpression)*
+ ;
+
+unaryAddSubExpression
+ : (PLUS | SUB)? atomicExpression
+ ;
+
+atomicExpression
+ : propertyOrLabelExpression (stringExpression | listExpression | nullExpression)*
+ ;
+
+listExpression
+ : IN propertyOrLabelExpression
+ | LBRACK (expression? RANGE expression? | expression) RBRACK
+ ;
+
+stringExpression
+ : stringExpPrefix propertyOrLabelExpression
+ ;
+
+stringExpPrefix
+ : STARTS WITH
+ | ENDS WITH
+ | CONTAINS
+ ;
+
+nullExpression
+ : IS NOT? NULL_W
+ ;
+
+propertyOrLabelExpression
+ : propertyExpression nodeLabels?
+ ;
+
+propertyExpression
+ : atom (DOT name)*
+ ;
+
+patternPart
+ : (symbol ASSIGN)? patternElem
+ | (symbol ASSIGN)? pathFunction
+ ;
+
+pathFunction
+ : (SHORTESTPATH | ALLSHORTESTPATHS) LPAREN patternElem RPAREN
+ ;
+
+patternElem
+ : nodePattern patternElemChain*
+ | LPAREN patternElem RPAREN
+ ;
+
+patternElemChain
+ : relationshipPattern nodePattern
+ ;
+
+properties
+ : mapLit
+ | parameter
+ ;
+
+nodePattern
+ : LPAREN symbol? nodeLabels? properties? RPAREN
+ ;
+
+atom
+ : literal
+ | parameter
+ | caseExpression
+ | countAll
+ | listComprehension
+ | patternComprehension
+ | filterWith
+ | relationshipsChainPattern
+ | parenthesizedExpression
+ | functionInvocation
+ | symbol
+ | subqueryExist
+ ;
+
+lhs
+ : symbol ASSIGN
+ ;
+
+relationshipPattern
+ : LT SUB relationDetail? SUB GT?
+ | SUB relationDetail? SUB GT?
+ ;
+
+relationDetail
+ : LBRACK symbol? relationshipTypes? rangeLit? properties? RBRACK
+ ;
+
+relationshipTypes
+ : COLON name (STICK COLON? name)*
+ ;
+
+unionSt
+ : UNION ALL? singleQuery
+ ;
+
+subqueryExist
+ : EXISTS LBRACE (regularQuery | patternWhere) RBRACE
+ ;
+
+invocationName
+ : symbol (DOT symbol)*
+ ;
+
+functionInvocation
+ : invocationName LPAREN DISTINCT? expressionChain? RPAREN
+ ;
+
+parenthesizedExpression
+ : LPAREN expression RPAREN
+ ;
+
+filterWith
+ : (ALL | ANY | NONE | SINGLE) LPAREN filterExpression RPAREN
+ ;
+
+patternComprehension
+ : LBRACK lhs? relationshipsChainPattern where? STICK expression RBRACK
+ ;
+
+relationshipsChainPattern
+ : nodePattern patternElemChain+
+ ;
+
+listComprehension
+ : LBRACK filterExpression (STICK expression)? RBRACK
+ ;
+
+filterExpression
+ : symbol IN expression where?
+ ;
+
+countAll
+ : COUNT LPAREN MULT RPAREN
+ ;
+
+expressionChain
+ : expression (COMMA expression)*
+ ;
+
+caseExpression
+ : CASE expression? (WHEN expression THEN expression)+ (ELSE expression)? END
+ ;
+
+parameter
+ : DOLLAR (symbol | numLit)
+ ;
+
+// literals
+literal
+ : boolLit
+ | numLit
+ | NULL_W
+ | stringLit
+ | charLit
+ | listLit
+ | mapLit
+ ;
+
+rangeLit
+ : MULT integerLit? (RANGE integerLit?)?
+ ;
+
+boolLit
+ : TRUE
+ | FALSE
+ ;
+
+integerLit
+ : INTEGER
+ | DIGIT
+ ;
+
+numLit
+ : FLOAT
+ | integerLit
+ ;
+
+stringLit
+ : STRING_LITERAL
+ ;
+
+charLit
+ : CHAR_LITERAL
+ ;
+
+listLit
+ : LBRACK expressionChain? RBRACK
+ ;
+
+mapLit
+ : LBRACE (mapPair (COMMA mapPair)*)? RBRACE
+ ;
+
+mapPair
+ : name COLON expression
+ ;
+
+// primitive ids
+name
+ : symbol
+ | reservedWord
+ ;
+
+symbol
+ : ESC_LITERAL
+ | ID
+ | COUNT
+ | SUM
+ | AVG
+ | MIN
+ | MAX
+ | COLLECT
+ | FILTER
+ | EXTRACT
+ | ANY
+ | NONE
+ | SINGLE
+ | INDEX
+ | INDEXES
+ | CONSTRAINT
+ | CONSTRAINTS
+ | DROP
+ | CREATE
+ | VECTOR
+ | DELETE
+ | ADD
+ | REMOVE
+ | SET
+ | MATCH
+ | MERGE
+ | FULLTEXT
+ | PROCEDURES
+ | FUNCTIONS
+ | DATABASE
+ | EXISTS
+ | SHOW
+ | OPTIONS
+ | NODE
+ | KEY
+ | ASSERT
+ | ROWS
+ | TRANSACTIONS
+ | END
+ | CASE
+ | WHEN
+ | THEN
+ | ELSE
+ | TRUE
+ | FALSE
+ | NULL_W
+ | UNIQUE
+ | REQUIRE
+ | IF
+ | EACH
+ | ALL
+ | SHORTESTPATH
+ | ALLSHORTESTPATHS
+ ;
+
+reservedWord
+ : ALL
+ | ASC
+ | ASCENDING
+ | BY
+ | CREATE
+ | DELETE
+ | DESC
+ | DESCENDING
+ | DETACH
+ | EXISTS
+ | LIMIT
+ | MATCH
+ | MERGE
+ | ON
+ | OPTIONAL
+ | ORDER
+ | REMOVE
+ | RETURN
+ | SET
+ | SKIP_W
+ | WHERE
+ | WITH
+ | UNION
+ | UNWIND
+ | AND
+ | AS
+ | CONTAINS
+ | DISTINCT
+ | ENDS
+ | IN
+ | IS
+ | NOT
+ | OR
+ | STARTS
+ | XOR
+ | FALSE
+ | TRUE
+ | NULL_W
+ | CONSTRAINT
+ | DO
+ | FOR
+ | REQUIRE
+ | UNIQUE
+ | CASE
+ | WHEN
+ | THEN
+ | ELSE
+ | END
+ | MANDATORY
+ | SCALAR
+ | OF
+ | ADD
+ | DROP
+ ;
\ No newline at end of file
diff --git a/nornicdb/pkg/cypher/antlr/CypherParser.interp b/nornicdb/pkg/cypher/antlr/CypherParser.interp
new file mode 100644
index 0000000..f600329
--- /dev/null
+++ b/nornicdb/pkg/cypher/antlr/CypherParser.interp
@@ -0,0 +1,365 @@
+token literal names:
+null
+'='
+'+='
+'<='
+'>='
+'>'
+'<'
+null
+'=~'
+'..'
+';'
+'.'
+','
+'('
+')'
+'{'
+'}'
+'['
+']'
+'-'
+'+'
+'/'
+'%'
+'^'
+'*'
+'`'
+':'
+'|'
+'$'
+'CALL'
+'YIELD'
+'FILTER'
+'EXTRACT'
+'COUNT'
+'SUM'
+'AVG'
+'MIN'
+'MAX'
+'COLLECT'
+'ANY'
+'NONE'
+'SINGLE'
+'ALL'
+'ASC'
+'ASCENDING'
+'BY'
+'CREATE'
+'DELETE'
+'DESC'
+'DESCENDING'
+'DETACH'
+'EXISTS'
+'LIMIT'
+'MATCH'
+'MERGE'
+'ON'
+'OPTIONAL'
+'ORDER'
+'REMOVE'
+'RETURN'
+'SET'
+'SKIP'
+'WHERE'
+'WITH'
+'UNION'
+'UNWIND'
+'AND'
+'AS'
+'CONTAINS'
+'DISTINCT'
+'ENDS'
+'IN'
+'IS'
+'NOT'
+'OR'
+'STARTS'
+'XOR'
+'FALSE'
+'TRUE'
+'NULL'
+'CONSTRAINT'
+'DO'
+'FOR'
+'REQUIRE'
+'UNIQUE'
+'CASE'
+'WHEN'
+'THEN'
+'ELSE'
+'END'
+'MANDATORY'
+'SCALAR'
+'OF'
+'ADD'
+'DROP'
+'INDEX'
+'INDEXES'
+'VECTOR'
+'EXPLAIN'
+'PROFILE'
+'SHOW'
+'CONSTRAINTS'
+'PROCEDURES'
+'FUNCTIONS'
+'DATABASE'
+'DATABASES'
+'FULLTEXT'
+'OPTIONS'
+'EACH'
+'IF'
+'TRANSACTIONS'
+'ROWS'
+'ASSERT'
+'KEY'
+'NODE'
+'shortestPath'
+'allShortestPaths'
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+
+token symbolic names:
+null
+ASSIGN
+ADD_ASSIGN
+LE
+GE
+GT
+LT
+NOT_EQUAL
+REGEX_MATCH
+RANGE
+SEMI
+DOT
+COMMA
+LPAREN
+RPAREN
+LBRACE
+RBRACE
+LBRACK
+RBRACK
+SUB
+PLUS
+DIV
+MOD
+CARET
+MULT
+ESC
+COLON
+STICK
+DOLLAR
+CALL
+YIELD
+FILTER
+EXTRACT
+COUNT
+SUM
+AVG
+MIN
+MAX
+COLLECT
+ANY
+NONE
+SINGLE
+ALL
+ASC
+ASCENDING
+BY
+CREATE
+DELETE
+DESC
+DESCENDING
+DETACH
+EXISTS
+LIMIT
+MATCH
+MERGE
+ON
+OPTIONAL
+ORDER
+REMOVE
+RETURN
+SET
+SKIP_W
+WHERE
+WITH
+UNION
+UNWIND
+AND
+AS
+CONTAINS
+DISTINCT
+ENDS
+IN
+IS
+NOT
+OR
+STARTS
+XOR
+FALSE
+TRUE
+NULL_W
+CONSTRAINT
+DO
+FOR
+REQUIRE
+UNIQUE
+CASE
+WHEN
+THEN
+ELSE
+END
+MANDATORY
+SCALAR
+OF
+ADD
+DROP
+INDEX
+INDEXES
+VECTOR
+EXPLAIN
+PROFILE
+SHOW
+CONSTRAINTS
+PROCEDURES
+FUNCTIONS
+DATABASE
+DATABASES
+FULLTEXT
+OPTIONS
+EACH
+IF
+TRANSACTIONS
+ROWS
+ASSERT
+KEY
+NODE
+SHORTESTPATH
+ALLSHORTESTPATHS
+FLOAT
+INTEGER
+DIGIT
+ID
+ESC_LITERAL
+CHAR_LITERAL
+STRING_LITERAL
+WS
+COMMENT
+LINE_COMMENT
+ERRCHAR
+Letter
+
+rule names:
+script
+query
+queryPrefix
+showCommand
+schemaCommand
+regularQuery
+singleQuery
+standaloneCall
+existsSubquery
+countSubquery
+callSubquery
+subqueryBody
+returnSt
+withSt
+skipSt
+limitSt
+projectionBody
+projectionItems
+projectionItem
+orderItem
+orderSt
+singlePartQ
+multiPartQ
+matchSt
+unwindSt
+readingStatement
+updatingStatement
+deleteSt
+removeSt
+removeItem
+queryCallSt
+parenExpressionChain
+yieldItems
+yieldItem
+mergeSt
+mergeAction
+setSt
+setItem
+nodeLabels
+createSt
+patternWhere
+where
+pattern
+expression
+xorExpression
+andExpression
+notExpression
+comparisonExpression
+comparisonSigns
+addSubExpression
+multDivExpression
+powerExpression
+unaryAddSubExpression
+atomicExpression
+listExpression
+stringExpression
+stringExpPrefix
+nullExpression
+propertyOrLabelExpression
+propertyExpression
+patternPart
+pathFunction
+patternElem
+patternElemChain
+properties
+nodePattern
+atom
+lhs
+relationshipPattern
+relationDetail
+relationshipTypes
+unionSt
+subqueryExist
+invocationName
+functionInvocation
+parenthesizedExpression
+filterWith
+patternComprehension
+relationshipsChainPattern
+listComprehension
+filterExpression
+countAll
+expressionChain
+caseExpression
+parameter
+literal
+rangeLit
+boolLit
+integerLit
+numLit
+stringLit
+charLit
+listLit
+mapLit
+mapPair
+name
+symbol
+reservedWord
+
+
+atn:
+[4, 1, 128, 1084, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7, 57, 2, 58, 7, 58, 2, 59, 7, 59, 2, 60, 7, 60, 2, 61, 7, 61, 2, 62, 7, 62, 2, 63, 7, 63, 2, 64, 7, 64, 2, 65, 7, 65, 2, 66, 7, 66, 2, 67, 7, 67, 2, 68, 7, 68, 2, 69, 7, 69, 2, 70, 7, 70, 2, 71, 7, 71, 2, 72, 7, 72, 2, 73, 7, 73, 2, 74, 7, 74, 2, 75, 7, 75, 2, 76, 7, 76, 2, 77, 7, 77, 2, 78, 7, 78, 2, 79, 7, 79, 2, 80, 7, 80, 2, 81, 7, 81, 2, 82, 7, 82, 2, 83, 7, 83, 2, 84, 7, 84, 2, 85, 7, 85, 2, 86, 7, 86, 2, 87, 7, 87, 2, 88, 7, 88, 2, 89, 7, 89, 2, 90, 7, 90, 2, 91, 7, 91, 2, 92, 7, 92, 2, 93, 7, 93, 2, 94, 7, 94, 2, 95, 7, 95, 2, 96, 7, 96, 2, 97, 7, 97, 1, 0, 1, 0, 1, 0, 5, 0, 200, 8, 0, 10, 0, 12, 0, 203, 9, 0, 1, 0, 3, 0, 206, 8, 0, 1, 0, 1, 0, 1, 1, 3, 1, 211, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 217, 8, 1, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 3, 3, 231, 8, 3, 3, 3, 233, 8, 3, 1, 4, 1, 4, 1, 4, 3, 4, 238, 8, 4, 1, 4, 1, 4, 3, 4, 242, 8, 4, 1, 4, 1, 4, 1, 4, 3, 4, 247, 8, 4, 1, 4, 1, 4, 1, 4, 3, 4, 252, 8, 4, 1, 4, 1, 4, 3, 4, 256, 8, 4, 1, 4, 3, 4, 259, 8, 4, 1, 4, 3, 4, 262, 8, 4, 1, 4, 1, 4, 1, 4, 1, 4, 3, 4, 268, 8, 4, 1, 4, 1, 4, 1, 4, 3, 4, 273, 8, 4, 1, 4, 1, 4, 3, 4, 277, 8, 4, 1, 4, 3, 4, 280, 8, 4, 1, 4, 3, 4, 283, 8, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 3, 4, 293, 8, 4, 1, 4, 1, 4, 1, 4, 3, 4, 298, 8, 4, 1, 4, 1, 4, 3, 4, 302, 8, 4, 1, 4, 3, 4, 305, 8, 4, 1, 4, 3, 4, 308, 8, 4, 1, 4, 1, 4, 3, 4, 312, 8, 4, 1, 4, 1, 4, 1, 4, 3, 4, 317, 8, 4, 1, 4, 1, 4, 3, 4, 321, 8, 4, 1, 4, 1, 4, 1, 4, 3, 4, 326, 8, 4, 1, 4, 1, 4, 1, 4, 3, 4, 331, 8, 4, 1, 4, 1, 4, 3, 4, 335, 8, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 3, 4, 344, 8, 4, 1, 4, 1, 4, 1, 4, 3, 4, 349, 8, 4, 1, 4, 1, 4, 1, 4, 3, 4, 354, 8, 4, 1, 4, 3, 4, 357, 8, 4, 1, 4, 3, 4, 360, 8, 4, 1, 4, 1, 4, 1, 4, 3, 4, 365, 8, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 3, 4, 373, 8, 4, 3, 4, 375, 8, 4, 1, 5, 1, 5, 5, 5, 379, 8, 5, 10, 5, 12, 5, 382, 9, 5, 1, 6, 1, 6, 3, 6, 386, 8, 6, 1, 7, 1, 7, 1, 7, 3, 7, 391, 8, 7, 1, 7, 1, 7, 1, 7, 3, 7, 396, 8, 7, 3, 7, 398, 8, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 3, 10, 420, 8, 10, 3, 10, 422, 8, 10, 1, 11, 3, 11, 425, 8, 11, 1, 11, 1, 11, 5, 11, 429, 8, 11, 10, 11, 12, 11, 432, 9, 11, 1, 11, 3, 11, 435, 8, 11, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 3, 13, 443, 8, 13, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 16, 3, 16, 452, 8, 16, 1, 16, 1, 16, 3, 16, 456, 8, 16, 1, 16, 3, 16, 459, 8, 16, 1, 16, 3, 16, 462, 8, 16, 1, 17, 1, 17, 3, 17, 466, 8, 17, 1, 17, 1, 17, 5, 17, 470, 8, 17, 10, 17, 12, 17, 473, 9, 17, 1, 18, 1, 18, 1, 18, 3, 18, 478, 8, 18, 1, 19, 1, 19, 3, 19, 482, 8, 19, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 5, 20, 489, 8, 20, 10, 20, 12, 20, 492, 9, 20, 1, 21, 5, 21, 495, 8, 21, 10, 21, 12, 21, 498, 9, 21, 1, 21, 1, 21, 4, 21, 502, 8, 21, 11, 21, 12, 21, 503, 1, 21, 3, 21, 507, 8, 21, 3, 21, 509, 8, 21, 1, 21, 1, 21, 3, 21, 513, 8, 21, 3, 21, 515, 8, 21, 1, 22, 1, 22, 5, 22, 519, 8, 22, 10, 22, 12, 22, 522, 9, 22, 1, 22, 4, 22, 525, 8, 22, 11, 22, 12, 22, 526, 1, 22, 1, 22, 1, 23, 3, 23, 532, 8, 23, 1, 23, 1, 23, 1, 23, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 3, 24, 542, 8, 24, 1, 25, 1, 25, 1, 25, 1, 25, 3, 25, 548, 8, 25, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 3, 26, 555, 8, 26, 1, 27, 3, 27, 558, 8, 27, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 28, 5, 28, 567, 8, 28, 10, 28, 12, 28, 570, 9, 28, 1, 29, 1, 29, 1, 29, 1, 29, 3, 29, 576, 8, 29, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 3, 30, 583, 8, 30, 1, 31, 1, 31, 3, 31, 587, 8, 31, 1, 31, 1, 31, 1, 32, 1, 32, 1, 32, 5, 32, 594, 8, 32, 10, 32, 12, 32, 597, 9, 32, 1, 32, 3, 32, 600, 8, 32, 1, 33, 1, 33, 1, 33, 3, 33, 605, 8, 33, 1, 33, 1, 33, 1, 34, 1, 34, 1, 34, 5, 34, 612, 8, 34, 10, 34, 12, 34, 615, 9, 34, 1, 35, 1, 35, 1, 35, 1, 35, 1, 36, 1, 36, 1, 36, 1, 36, 5, 36, 625, 8, 36, 10, 36, 12, 36, 628, 9, 36, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 3, 37, 641, 8, 37, 1, 38, 1, 38, 4, 38, 645, 8, 38, 11, 38, 12, 38, 646, 1, 39, 1, 39, 1, 39, 1, 40, 1, 40, 3, 40, 654, 8, 40, 1, 41, 1, 41, 1, 41, 1, 42, 1, 42, 1, 42, 5, 42, 662, 8, 42, 10, 42, 12, 42, 665, 9, 42, 1, 43, 1, 43, 1, 43, 5, 43, 670, 8, 43, 10, 43, 12, 43, 673, 9, 43, 1, 44, 1, 44, 1, 44, 5, 44, 678, 8, 44, 10, 44, 12, 44, 681, 9, 44, 1, 45, 1, 45, 1, 45, 5, 45, 686, 8, 45, 10, 45, 12, 45, 689, 9, 45, 1, 46, 3, 46, 692, 8, 46, 1, 46, 1, 46, 3, 46, 696, 8, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 3, 46, 703, 8, 46, 1, 47, 1, 47, 1, 47, 1, 47, 5, 47, 709, 8, 47, 10, 47, 12, 47, 712, 9, 47, 1, 48, 1, 48, 1, 49, 1, 49, 1, 49, 5, 49, 719, 8, 49, 10, 49, 12, 49, 722, 9, 49, 1, 50, 1, 50, 1, 50, 5, 50, 727, 8, 50, 10, 50, 12, 50, 730, 9, 50, 1, 51, 1, 51, 1, 51, 5, 51, 735, 8, 51, 10, 51, 12, 51, 738, 9, 51, 1, 52, 3, 52, 741, 8, 52, 1, 52, 1, 52, 1, 53, 1, 53, 1, 53, 1, 53, 5, 53, 749, 8, 53, 10, 53, 12, 53, 752, 9, 53, 1, 54, 1, 54, 1, 54, 1, 54, 3, 54, 758, 8, 54, 1, 54, 1, 54, 3, 54, 762, 8, 54, 1, 54, 3, 54, 765, 8, 54, 1, 54, 3, 54, 768, 8, 54, 1, 55, 1, 55, 1, 55, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 3, 56, 778, 8, 56, 1, 57, 1, 57, 3, 57, 782, 8, 57, 1, 57, 1, 57, 1, 58, 1, 58, 3, 58, 788, 8, 58, 1, 59, 1, 59, 1, 59, 5, 59, 793, 8, 59, 10, 59, 12, 59, 796, 9, 59, 1, 60, 1, 60, 1, 60, 3, 60, 801, 8, 60, 1, 60, 1, 60, 1, 60, 1, 60, 3, 60, 807, 8, 60, 1, 60, 3, 60, 810, 8, 60, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 62, 1, 62, 5, 62, 819, 8, 62, 10, 62, 12, 62, 822, 9, 62, 1, 62, 1, 62, 1, 62, 1, 62, 3, 62, 828, 8, 62, 1, 63, 1, 63, 1, 63, 1, 64, 1, 64, 3, 64, 835, 8, 64, 1, 65, 1, 65, 3, 65, 839, 8, 65, 1, 65, 3, 65, 842, 8, 65, 1, 65, 3, 65, 845, 8, 65, 1, 65, 1, 65, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 3, 66, 861, 8, 66, 1, 67, 1, 67, 1, 67, 1, 68, 1, 68, 1, 68, 3, 68, 869, 8, 68, 1, 68, 1, 68, 3, 68, 873, 8, 68, 1, 68, 1, 68, 3, 68, 877, 8, 68, 1, 68, 1, 68, 3, 68, 881, 8, 68, 3, 68, 883, 8, 68, 1, 69, 1, 69, 3, 69, 887, 8, 69, 1, 69, 3, 69, 890, 8, 69, 1, 69, 3, 69, 893, 8, 69, 1, 69, 3, 69, 896, 8, 69, 1, 69, 1, 69, 1, 70, 1, 70, 1, 70, 1, 70, 3, 70, 904, 8, 70, 1, 70, 5, 70, 907, 8, 70, 10, 70, 12, 70, 910, 9, 70, 1, 71, 1, 71, 3, 71, 914, 8, 71, 1, 71, 1, 71, 1, 72, 1, 72, 1, 72, 1, 72, 3, 72, 922, 8, 72, 1, 72, 1, 72, 1, 73, 1, 73, 1, 73, 5, 73, 929, 8, 73, 10, 73, 12, 73, 932, 9, 73, 1, 74, 1, 74, 1, 74, 3, 74, 937, 8, 74, 1, 74, 3, 74, 940, 8, 74, 1, 74, 1, 74, 1, 75, 1, 75, 1, 75, 1, 75, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 77, 1, 77, 3, 77, 955, 8, 77, 1, 77, 1, 77, 3, 77, 959, 8, 77, 1, 77, 1, 77, 1, 77, 1, 77, 1, 78, 1, 78, 4, 78, 967, 8, 78, 11, 78, 12, 78, 968, 1, 79, 1, 79, 1, 79, 1, 79, 3, 79, 975, 8, 79, 1, 79, 1, 79, 1, 80, 1, 80, 1, 80, 1, 80, 3, 80, 983, 8, 80, 1, 81, 1, 81, 1, 81, 1, 81, 1, 81, 1, 82, 1, 82, 1, 82, 5, 82, 993, 8, 82, 10, 82, 12, 82, 996, 9, 82, 1, 83, 1, 83, 3, 83, 1000, 8, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 4, 83, 1007, 8, 83, 11, 83, 12, 83, 1008, 1, 83, 1, 83, 3, 83, 1013, 8, 83, 1, 83, 1, 83, 1, 84, 1, 84, 1, 84, 3, 84, 1020, 8, 84, 1, 85, 1, 85, 1, 85, 1, 85, 1, 85, 1, 85, 1, 85, 3, 85, 1029, 8, 85, 1, 86, 1, 86, 3, 86, 1033, 8, 86, 1, 86, 1, 86, 3, 86, 1037, 8, 86, 3, 86, 1039, 8, 86, 1, 87, 1, 87, 1, 88, 1, 88, 1, 89, 1, 89, 3, 89, 1047, 8, 89, 1, 90, 1, 90, 1, 91, 1, 91, 1, 92, 1, 92, 3, 92, 1055, 8, 92, 1, 92, 1, 92, 1, 93, 1, 93, 1, 93, 1, 93, 5, 93, 1063, 8, 93, 10, 93, 12, 93, 1066, 9, 93, 3, 93, 1068, 8, 93, 1, 93, 1, 93, 1, 94, 1, 94, 1, 94, 1, 94, 1, 95, 1, 95, 3, 95, 1078, 8, 95, 1, 96, 1, 96, 1, 97, 1, 97, 1, 97, 0, 0, 98, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 0, 13, 1, 0, 98, 99, 2, 0, 43, 44, 48, 49, 2, 0, 46, 46, 53, 53, 1, 0, 1, 2, 2, 0, 1, 1, 3, 8, 1, 0, 19, 20, 2, 0, 21, 22, 24, 24, 1, 0, 115, 116, 1, 0, 39, 42, 1, 0, 77, 78, 1, 0, 118, 119, 12, 0, 31, 42, 46, 47, 51, 51, 53, 54, 58, 58, 60, 60, 77, 80, 83, 89, 93, 97, 100, 104, 106, 116, 120, 121, 1, 0, 42, 94, 1176, 0, 196, 1, 0, 0, 0, 2, 210, 1, 0, 0, 0, 4, 218, 1, 0, 0, 0, 6, 220, 1, 0, 0, 0, 8, 374, 1, 0, 0, 0, 10, 376, 1, 0, 0, 0, 12, 385, 1, 0, 0, 0, 14, 387, 1, 0, 0, 0, 16, 399, 1, 0, 0, 0, 18, 404, 1, 0, 0, 0, 20, 409, 1, 0, 0, 0, 22, 424, 1, 0, 0, 0, 24, 436, 1, 0, 0, 0, 26, 439, 1, 0, 0, 0, 28, 444, 1, 0, 0, 0, 30, 447, 1, 0, 0, 0, 32, 451, 1, 0, 0, 0, 34, 465, 1, 0, 0, 0, 36, 474, 1, 0, 0, 0, 38, 479, 1, 0, 0, 0, 40, 483, 1, 0, 0, 0, 42, 514, 1, 0, 0, 0, 44, 524, 1, 0, 0, 0, 46, 531, 1, 0, 0, 0, 48, 536, 1, 0, 0, 0, 50, 547, 1, 0, 0, 0, 52, 554, 1, 0, 0, 0, 54, 557, 1, 0, 0, 0, 56, 562, 1, 0, 0, 0, 58, 575, 1, 0, 0, 0, 60, 577, 1, 0, 0, 0, 62, 584, 1, 0, 0, 0, 64, 590, 1, 0, 0, 0, 66, 604, 1, 0, 0, 0, 68, 608, 1, 0, 0, 0, 70, 616, 1, 0, 0, 0, 72, 620, 1, 0, 0, 0, 74, 640, 1, 0, 0, 0, 76, 644, 1, 0, 0, 0, 78, 648, 1, 0, 0, 0, 80, 651, 1, 0, 0, 0, 82, 655, 1, 0, 0, 0, 84, 658, 1, 0, 0, 0, 86, 666, 1, 0, 0, 0, 88, 674, 1, 0, 0, 0, 90, 682, 1, 0, 0, 0, 92, 702, 1, 0, 0, 0, 94, 704, 1, 0, 0, 0, 96, 713, 1, 0, 0, 0, 98, 715, 1, 0, 0, 0, 100, 723, 1, 0, 0, 0, 102, 731, 1, 0, 0, 0, 104, 740, 1, 0, 0, 0, 106, 744, 1, 0, 0, 0, 108, 767, 1, 0, 0, 0, 110, 769, 1, 0, 0, 0, 112, 777, 1, 0, 0, 0, 114, 779, 1, 0, 0, 0, 116, 785, 1, 0, 0, 0, 118, 789, 1, 0, 0, 0, 120, 809, 1, 0, 0, 0, 122, 811, 1, 0, 0, 0, 124, 827, 1, 0, 0, 0, 126, 829, 1, 0, 0, 0, 128, 834, 1, 0, 0, 0, 130, 836, 1, 0, 0, 0, 132, 860, 1, 0, 0, 0, 134, 862, 1, 0, 0, 0, 136, 882, 1, 0, 0, 0, 138, 884, 1, 0, 0, 0, 140, 899, 1, 0, 0, 0, 142, 911, 1, 0, 0, 0, 144, 917, 1, 0, 0, 0, 146, 925, 1, 0, 0, 0, 148, 933, 1, 0, 0, 0, 150, 943, 1, 0, 0, 0, 152, 947, 1, 0, 0, 0, 154, 952, 1, 0, 0, 0, 156, 964, 1, 0, 0, 0, 158, 970, 1, 0, 0, 0, 160, 978, 1, 0, 0, 0, 162, 984, 1, 0, 0, 0, 164, 989, 1, 0, 0, 0, 166, 997, 1, 0, 0, 0, 168, 1016, 1, 0, 0, 0, 170, 1028, 1, 0, 0, 0, 172, 1030, 1, 0, 0, 0, 174, 1040, 1, 0, 0, 0, 176, 1042, 1, 0, 0, 0, 178, 1046, 1, 0, 0, 0, 180, 1048, 1, 0, 0, 0, 182, 1050, 1, 0, 0, 0, 184, 1052, 1, 0, 0, 0, 186, 1058, 1, 0, 0, 0, 188, 1071, 1, 0, 0, 0, 190, 1077, 1, 0, 0, 0, 192, 1079, 1, 0, 0, 0, 194, 1081, 1, 0, 0, 0, 196, 201, 3, 2, 1, 0, 197, 198, 5, 10, 0, 0, 198, 200, 3, 2, 1, 0, 199, 197, 1, 0, 0, 0, 200, 203, 1, 0, 0, 0, 201, 199, 1, 0, 0, 0, 201, 202, 1, 0, 0, 0, 202, 205, 1, 0, 0, 0, 203, 201, 1, 0, 0, 0, 204, 206, 5, 10, 0, 0, 205, 204, 1, 0, 0, 0, 205, 206, 1, 0, 0, 0, 206, 207, 1, 0, 0, 0, 207, 208, 5, 0, 0, 1, 208, 1, 1, 0, 0, 0, 209, 211, 3, 4, 2, 0, 210, 209, 1, 0, 0, 0, 210, 211, 1, 0, 0, 0, 211, 216, 1, 0, 0, 0, 212, 217, 3, 10, 5, 0, 213, 217, 3, 14, 7, 0, 214, 217, 3, 8, 4, 0, 215, 217, 3, 6, 3, 0, 216, 212, 1, 0, 0, 0, 216, 213, 1, 0, 0, 0, 216, 214, 1, 0, 0, 0, 216, 215, 1, 0, 0, 0, 217, 3, 1, 0, 0, 0, 218, 219, 7, 0, 0, 0, 219, 5, 1, 0, 0, 0, 220, 232, 5, 100, 0, 0, 221, 233, 5, 96, 0, 0, 222, 233, 5, 95, 0, 0, 223, 233, 5, 101, 0, 0, 224, 233, 5, 80, 0, 0, 225, 233, 5, 102, 0, 0, 226, 233, 5, 103, 0, 0, 227, 233, 5, 104, 0, 0, 228, 233, 5, 105, 0, 0, 229, 231, 5, 42, 0, 0, 230, 229, 1, 0, 0, 0, 230, 231, 1, 0, 0, 0, 231, 233, 1, 0, 0, 0, 232, 221, 1, 0, 0, 0, 232, 222, 1, 0, 0, 0, 232, 223, 1, 0, 0, 0, 232, 224, 1, 0, 0, 0, 232, 225, 1, 0, 0, 0, 232, 226, 1, 0, 0, 0, 232, 227, 1, 0, 0, 0, 232, 228, 1, 0, 0, 0, 232, 230, 1, 0, 0, 0, 233, 7, 1, 0, 0, 0, 234, 235, 5, 94, 0, 0, 235, 237, 5, 95, 0, 0, 236, 238, 3, 190, 95, 0, 237, 236, 1, 0, 0, 0, 237, 238, 1, 0, 0, 0, 238, 241, 1, 0, 0, 0, 239, 240, 5, 109, 0, 0, 240, 242, 5, 51, 0, 0, 241, 239, 1, 0, 0, 0, 241, 242, 1, 0, 0, 0, 242, 375, 1, 0, 0, 0, 243, 244, 5, 46, 0, 0, 244, 246, 5, 95, 0, 0, 245, 247, 3, 190, 95, 0, 246, 245, 1, 0, 0, 0, 246, 247, 1, 0, 0, 0, 247, 251, 1, 0, 0, 0, 248, 249, 5, 109, 0, 0, 249, 250, 5, 73, 0, 0, 250, 252, 5, 51, 0, 0, 251, 248, 1, 0, 0, 0, 251, 252, 1, 0, 0, 0, 252, 255, 1, 0, 0, 0, 253, 254, 5, 82, 0, 0, 254, 256, 3, 130, 65, 0, 255, 253, 1, 0, 0, 0, 255, 256, 1, 0, 0, 0, 256, 258, 1, 0, 0, 0, 257, 259, 5, 55, 0, 0, 258, 257, 1, 0, 0, 0, 258, 259, 1, 0, 0, 0, 259, 261, 1, 0, 0, 0, 260, 262, 3, 62, 31, 0, 261, 260, 1, 0, 0, 0, 261, 262, 1, 0, 0, 0, 262, 375, 1, 0, 0, 0, 263, 264, 5, 46, 0, 0, 264, 265, 5, 106, 0, 0, 265, 267, 5, 95, 0, 0, 266, 268, 3, 190, 95, 0, 267, 266, 1, 0, 0, 0, 267, 268, 1, 0, 0, 0, 268, 272, 1, 0, 0, 0, 269, 270, 5, 109, 0, 0, 270, 271, 5, 73, 0, 0, 271, 273, 5, 51, 0, 0, 272, 269, 1, 0, 0, 0, 272, 273, 1, 0, 0, 0, 273, 276, 1, 0, 0, 0, 274, 275, 5, 82, 0, 0, 275, 277, 3, 130, 65, 0, 276, 274, 1, 0, 0, 0, 276, 277, 1, 0, 0, 0, 277, 279, 1, 0, 0, 0, 278, 280, 5, 55, 0, 0, 279, 278, 1, 0, 0, 0, 279, 280, 1, 0, 0, 0, 280, 282, 1, 0, 0, 0, 281, 283, 5, 108, 0, 0, 282, 281, 1, 0, 0, 0, 282, 283, 1, 0, 0, 0, 283, 284, 1, 0, 0, 0, 284, 285, 5, 17, 0, 0, 285, 286, 3, 164, 82, 0, 286, 287, 5, 18, 0, 0, 287, 375, 1, 0, 0, 0, 288, 289, 5, 46, 0, 0, 289, 290, 5, 97, 0, 0, 290, 292, 5, 95, 0, 0, 291, 293, 3, 190, 95, 0, 292, 291, 1, 0, 0, 0, 292, 293, 1, 0, 0, 0, 293, 297, 1, 0, 0, 0, 294, 295, 5, 109, 0, 0, 295, 296, 5, 73, 0, 0, 296, 298, 5, 51, 0, 0, 297, 294, 1, 0, 0, 0, 297, 298, 1, 0, 0, 0, 298, 301, 1, 0, 0, 0, 299, 300, 5, 82, 0, 0, 300, 302, 3, 130, 65, 0, 301, 299, 1, 0, 0, 0, 301, 302, 1, 0, 0, 0, 302, 304, 1, 0, 0, 0, 303, 305, 5, 55, 0, 0, 304, 303, 1, 0, 0, 0, 304, 305, 1, 0, 0, 0, 305, 307, 1, 0, 0, 0, 306, 308, 3, 62, 31, 0, 307, 306, 1, 0, 0, 0, 307, 308, 1, 0, 0, 0, 308, 311, 1, 0, 0, 0, 309, 310, 5, 107, 0, 0, 310, 312, 3, 186, 93, 0, 311, 309, 1, 0, 0, 0, 311, 312, 1, 0, 0, 0, 312, 375, 1, 0, 0, 0, 313, 314, 5, 94, 0, 0, 314, 316, 5, 80, 0, 0, 315, 317, 3, 190, 95, 0, 316, 315, 1, 0, 0, 0, 316, 317, 1, 0, 0, 0, 317, 320, 1, 0, 0, 0, 318, 319, 5, 109, 0, 0, 319, 321, 5, 51, 0, 0, 320, 318, 1, 0, 0, 0, 320, 321, 1, 0, 0, 0, 321, 375, 1, 0, 0, 0, 322, 323, 5, 46, 0, 0, 323, 325, 5, 80, 0, 0, 324, 326, 3, 190, 95, 0, 325, 324, 1, 0, 0, 0, 325, 326, 1, 0, 0, 0, 326, 330, 1, 0, 0, 0, 327, 328, 5, 109, 0, 0, 328, 329, 5, 73, 0, 0, 329, 331, 5, 51, 0, 0, 330, 327, 1, 0, 0, 0, 330, 331, 1, 0, 0, 0, 331, 334, 1, 0, 0, 0, 332, 333, 5, 82, 0, 0, 333, 335, 3, 130, 65, 0, 334, 332, 1, 0, 0, 0, 334, 335, 1, 0, 0, 0, 335, 336, 1, 0, 0, 0, 336, 337, 5, 83, 0, 0, 337, 343, 3, 86, 43, 0, 338, 339, 5, 72, 0, 0, 339, 344, 5, 84, 0, 0, 340, 341, 5, 72, 0, 0, 341, 342, 5, 73, 0, 0, 342, 344, 5, 79, 0, 0, 343, 338, 1, 0, 0, 0, 343, 340, 1, 0, 0, 0, 344, 375, 1, 0, 0, 0, 345, 346, 5, 46, 0, 0, 346, 348, 5, 80, 0, 0, 347, 349, 3, 190, 95, 0, 348, 347, 1, 0, 0, 0, 348, 349, 1, 0, 0, 0, 349, 353, 1, 0, 0, 0, 350, 351, 5, 109, 0, 0, 351, 352, 5, 73, 0, 0, 352, 354, 5, 51, 0, 0, 353, 350, 1, 0, 0, 0, 353, 354, 1, 0, 0, 0, 354, 356, 1, 0, 0, 0, 355, 357, 5, 55, 0, 0, 356, 355, 1, 0, 0, 0, 356, 357, 1, 0, 0, 0, 357, 359, 1, 0, 0, 0, 358, 360, 3, 130, 65, 0, 359, 358, 1, 0, 0, 0, 359, 360, 1, 0, 0, 0, 360, 361, 1, 0, 0, 0, 361, 364, 5, 112, 0, 0, 362, 365, 3, 86, 43, 0, 363, 365, 3, 62, 31, 0, 364, 362, 1, 0, 0, 0, 364, 363, 1, 0, 0, 0, 365, 366, 1, 0, 0, 0, 366, 372, 5, 72, 0, 0, 367, 373, 5, 84, 0, 0, 368, 369, 5, 73, 0, 0, 369, 373, 5, 79, 0, 0, 370, 371, 5, 114, 0, 0, 371, 373, 5, 113, 0, 0, 372, 367, 1, 0, 0, 0, 372, 368, 1, 0, 0, 0, 372, 370, 1, 0, 0, 0, 373, 375, 1, 0, 0, 0, 374, 234, 1, 0, 0, 0, 374, 243, 1, 0, 0, 0, 374, 263, 1, 0, 0, 0, 374, 288, 1, 0, 0, 0, 374, 313, 1, 0, 0, 0, 374, 322, 1, 0, 0, 0, 374, 345, 1, 0, 0, 0, 375, 9, 1, 0, 0, 0, 376, 380, 3, 12, 6, 0, 377, 379, 3, 142, 71, 0, 378, 377, 1, 0, 0, 0, 379, 382, 1, 0, 0, 0, 380, 378, 1, 0, 0, 0, 380, 381, 1, 0, 0, 0, 381, 11, 1, 0, 0, 0, 382, 380, 1, 0, 0, 0, 383, 386, 3, 42, 21, 0, 384, 386, 3, 44, 22, 0, 385, 383, 1, 0, 0, 0, 385, 384, 1, 0, 0, 0, 386, 13, 1, 0, 0, 0, 387, 388, 5, 29, 0, 0, 388, 390, 3, 146, 73, 0, 389, 391, 3, 62, 31, 0, 390, 389, 1, 0, 0, 0, 390, 391, 1, 0, 0, 0, 391, 397, 1, 0, 0, 0, 392, 395, 5, 30, 0, 0, 393, 396, 5, 24, 0, 0, 394, 396, 3, 64, 32, 0, 395, 393, 1, 0, 0, 0, 395, 394, 1, 0, 0, 0, 396, 398, 1, 0, 0, 0, 397, 392, 1, 0, 0, 0, 397, 398, 1, 0, 0, 0, 398, 15, 1, 0, 0, 0, 399, 400, 5, 51, 0, 0, 400, 401, 5, 15, 0, 0, 401, 402, 3, 46, 23, 0, 402, 403, 5, 16, 0, 0, 403, 17, 1, 0, 0, 0, 404, 405, 5, 33, 0, 0, 405, 406, 5, 15, 0, 0, 406, 407, 3, 46, 23, 0, 407, 408, 5, 16, 0, 0, 408, 19, 1, 0, 0, 0, 409, 410, 5, 29, 0, 0, 410, 411, 5, 15, 0, 0, 411, 412, 3, 22, 11, 0, 412, 421, 5, 16, 0, 0, 413, 414, 5, 71, 0, 0, 414, 419, 5, 110, 0, 0, 415, 416, 5, 92, 0, 0, 416, 417, 3, 178, 89, 0, 417, 418, 5, 111, 0, 0, 418, 420, 1, 0, 0, 0, 419, 415, 1, 0, 0, 0, 419, 420, 1, 0, 0, 0, 420, 422, 1, 0, 0, 0, 421, 413, 1, 0, 0, 0, 421, 422, 1, 0, 0, 0, 422, 21, 1, 0, 0, 0, 423, 425, 3, 26, 13, 0, 424, 423, 1, 0, 0, 0, 424, 425, 1, 0, 0, 0, 425, 430, 1, 0, 0, 0, 426, 429, 3, 50, 25, 0, 427, 429, 3, 52, 26, 0, 428, 426, 1, 0, 0, 0, 428, 427, 1, 0, 0, 0, 429, 432, 1, 0, 0, 0, 430, 428, 1, 0, 0, 0, 430, 431, 1, 0, 0, 0, 431, 434, 1, 0, 0, 0, 432, 430, 1, 0, 0, 0, 433, 435, 3, 24, 12, 0, 434, 433, 1, 0, 0, 0, 434, 435, 1, 0, 0, 0, 435, 23, 1, 0, 0, 0, 436, 437, 5, 59, 0, 0, 437, 438, 3, 32, 16, 0, 438, 25, 1, 0, 0, 0, 439, 440, 5, 63, 0, 0, 440, 442, 3, 32, 16, 0, 441, 443, 3, 82, 41, 0, 442, 441, 1, 0, 0, 0, 442, 443, 1, 0, 0, 0, 443, 27, 1, 0, 0, 0, 444, 445, 5, 61, 0, 0, 445, 446, 3, 86, 43, 0, 446, 29, 1, 0, 0, 0, 447, 448, 5, 52, 0, 0, 448, 449, 3, 86, 43, 0, 449, 31, 1, 0, 0, 0, 450, 452, 5, 69, 0, 0, 451, 450, 1, 0, 0, 0, 451, 452, 1, 0, 0, 0, 452, 453, 1, 0, 0, 0, 453, 455, 3, 34, 17, 0, 454, 456, 3, 40, 20, 0, 455, 454, 1, 0, 0, 0, 455, 456, 1, 0, 0, 0, 456, 458, 1, 0, 0, 0, 457, 459, 3, 28, 14, 0, 458, 457, 1, 0, 0, 0, 458, 459, 1, 0, 0, 0, 459, 461, 1, 0, 0, 0, 460, 462, 3, 30, 15, 0, 461, 460, 1, 0, 0, 0, 461, 462, 1, 0, 0, 0, 462, 33, 1, 0, 0, 0, 463, 466, 5, 24, 0, 0, 464, 466, 3, 36, 18, 0, 465, 463, 1, 0, 0, 0, 465, 464, 1, 0, 0, 0, 466, 471, 1, 0, 0, 0, 467, 468, 5, 12, 0, 0, 468, 470, 3, 36, 18, 0, 469, 467, 1, 0, 0, 0, 470, 473, 1, 0, 0, 0, 471, 469, 1, 0, 0, 0, 471, 472, 1, 0, 0, 0, 472, 35, 1, 0, 0, 0, 473, 471, 1, 0, 0, 0, 474, 477, 3, 86, 43, 0, 475, 476, 5, 67, 0, 0, 476, 478, 3, 192, 96, 0, 477, 475, 1, 0, 0, 0, 477, 478, 1, 0, 0, 0, 478, 37, 1, 0, 0, 0, 479, 481, 3, 86, 43, 0, 480, 482, 7, 1, 0, 0, 481, 480, 1, 0, 0, 0, 481, 482, 1, 0, 0, 0, 482, 39, 1, 0, 0, 0, 483, 484, 5, 57, 0, 0, 484, 485, 5, 45, 0, 0, 485, 490, 3, 38, 19, 0, 486, 487, 5, 12, 0, 0, 487, 489, 3, 38, 19, 0, 488, 486, 1, 0, 0, 0, 489, 492, 1, 0, 0, 0, 490, 488, 1, 0, 0, 0, 490, 491, 1, 0, 0, 0, 491, 41, 1, 0, 0, 0, 492, 490, 1, 0, 0, 0, 493, 495, 3, 50, 25, 0, 494, 493, 1, 0, 0, 0, 495, 498, 1, 0, 0, 0, 496, 494, 1, 0, 0, 0, 496, 497, 1, 0, 0, 0, 497, 508, 1, 0, 0, 0, 498, 496, 1, 0, 0, 0, 499, 509, 3, 24, 12, 0, 500, 502, 3, 52, 26, 0, 501, 500, 1, 0, 0, 0, 502, 503, 1, 0, 0, 0, 503, 501, 1, 0, 0, 0, 503, 504, 1, 0, 0, 0, 504, 506, 1, 0, 0, 0, 505, 507, 3, 24, 12, 0, 506, 505, 1, 0, 0, 0, 506, 507, 1, 0, 0, 0, 507, 509, 1, 0, 0, 0, 508, 499, 1, 0, 0, 0, 508, 501, 1, 0, 0, 0, 508, 509, 1, 0, 0, 0, 509, 515, 1, 0, 0, 0, 510, 512, 3, 20, 10, 0, 511, 513, 3, 40, 20, 0, 512, 511, 1, 0, 0, 0, 512, 513, 1, 0, 0, 0, 513, 515, 1, 0, 0, 0, 514, 496, 1, 0, 0, 0, 514, 510, 1, 0, 0, 0, 515, 43, 1, 0, 0, 0, 516, 519, 3, 50, 25, 0, 517, 519, 3, 52, 26, 0, 518, 516, 1, 0, 0, 0, 518, 517, 1, 0, 0, 0, 519, 522, 1, 0, 0, 0, 520, 518, 1, 0, 0, 0, 520, 521, 1, 0, 0, 0, 521, 523, 1, 0, 0, 0, 522, 520, 1, 0, 0, 0, 523, 525, 3, 26, 13, 0, 524, 520, 1, 0, 0, 0, 525, 526, 1, 0, 0, 0, 526, 524, 1, 0, 0, 0, 526, 527, 1, 0, 0, 0, 527, 528, 1, 0, 0, 0, 528, 529, 3, 42, 21, 0, 529, 45, 1, 0, 0, 0, 530, 532, 5, 56, 0, 0, 531, 530, 1, 0, 0, 0, 531, 532, 1, 0, 0, 0, 532, 533, 1, 0, 0, 0, 533, 534, 5, 53, 0, 0, 534, 535, 3, 80, 40, 0, 535, 47, 1, 0, 0, 0, 536, 537, 5, 65, 0, 0, 537, 538, 3, 86, 43, 0, 538, 539, 5, 67, 0, 0, 539, 541, 3, 192, 96, 0, 540, 542, 3, 82, 41, 0, 541, 540, 1, 0, 0, 0, 541, 542, 1, 0, 0, 0, 542, 49, 1, 0, 0, 0, 543, 548, 3, 46, 23, 0, 544, 548, 3, 48, 24, 0, 545, 548, 3, 60, 30, 0, 546, 548, 3, 20, 10, 0, 547, 543, 1, 0, 0, 0, 547, 544, 1, 0, 0, 0, 547, 545, 1, 0, 0, 0, 547, 546, 1, 0, 0, 0, 548, 51, 1, 0, 0, 0, 549, 555, 3, 78, 39, 0, 550, 555, 3, 68, 34, 0, 551, 555, 3, 54, 27, 0, 552, 555, 3, 72, 36, 0, 553, 555, 3, 56, 28, 0, 554, 549, 1, 0, 0, 0, 554, 550, 1, 0, 0, 0, 554, 551, 1, 0, 0, 0, 554, 552, 1, 0, 0, 0, 554, 553, 1, 0, 0, 0, 555, 53, 1, 0, 0, 0, 556, 558, 5, 50, 0, 0, 557, 556, 1, 0, 0, 0, 557, 558, 1, 0, 0, 0, 558, 559, 1, 0, 0, 0, 559, 560, 5, 47, 0, 0, 560, 561, 3, 164, 82, 0, 561, 55, 1, 0, 0, 0, 562, 563, 5, 58, 0, 0, 563, 568, 3, 58, 29, 0, 564, 565, 5, 12, 0, 0, 565, 567, 3, 58, 29, 0, 566, 564, 1, 0, 0, 0, 567, 570, 1, 0, 0, 0, 568, 566, 1, 0, 0, 0, 568, 569, 1, 0, 0, 0, 569, 57, 1, 0, 0, 0, 570, 568, 1, 0, 0, 0, 571, 572, 3, 192, 96, 0, 572, 573, 3, 76, 38, 0, 573, 576, 1, 0, 0, 0, 574, 576, 3, 118, 59, 0, 575, 571, 1, 0, 0, 0, 575, 574, 1, 0, 0, 0, 576, 59, 1, 0, 0, 0, 577, 578, 5, 29, 0, 0, 578, 579, 3, 146, 73, 0, 579, 582, 3, 62, 31, 0, 580, 581, 5, 30, 0, 0, 581, 583, 3, 64, 32, 0, 582, 580, 1, 0, 0, 0, 582, 583, 1, 0, 0, 0, 583, 61, 1, 0, 0, 0, 584, 586, 5, 13, 0, 0, 585, 587, 3, 164, 82, 0, 586, 585, 1, 0, 0, 0, 586, 587, 1, 0, 0, 0, 587, 588, 1, 0, 0, 0, 588, 589, 5, 14, 0, 0, 589, 63, 1, 0, 0, 0, 590, 595, 3, 66, 33, 0, 591, 592, 5, 12, 0, 0, 592, 594, 3, 66, 33, 0, 593, 591, 1, 0, 0, 0, 594, 597, 1, 0, 0, 0, 595, 593, 1, 0, 0, 0, 595, 596, 1, 0, 0, 0, 596, 599, 1, 0, 0, 0, 597, 595, 1, 0, 0, 0, 598, 600, 3, 82, 41, 0, 599, 598, 1, 0, 0, 0, 599, 600, 1, 0, 0, 0, 600, 65, 1, 0, 0, 0, 601, 602, 3, 192, 96, 0, 602, 603, 5, 67, 0, 0, 603, 605, 1, 0, 0, 0, 604, 601, 1, 0, 0, 0, 604, 605, 1, 0, 0, 0, 605, 606, 1, 0, 0, 0, 606, 607, 3, 192, 96, 0, 607, 67, 1, 0, 0, 0, 608, 609, 5, 54, 0, 0, 609, 613, 3, 120, 60, 0, 610, 612, 3, 70, 35, 0, 611, 610, 1, 0, 0, 0, 612, 615, 1, 0, 0, 0, 613, 611, 1, 0, 0, 0, 613, 614, 1, 0, 0, 0, 614, 69, 1, 0, 0, 0, 615, 613, 1, 0, 0, 0, 616, 617, 5, 55, 0, 0, 617, 618, 7, 2, 0, 0, 618, 619, 3, 72, 36, 0, 619, 71, 1, 0, 0, 0, 620, 621, 5, 60, 0, 0, 621, 626, 3, 74, 37, 0, 622, 623, 5, 12, 0, 0, 623, 625, 3, 74, 37, 0, 624, 622, 1, 0, 0, 0, 625, 628, 1, 0, 0, 0, 626, 624, 1, 0, 0, 0, 626, 627, 1, 0, 0, 0, 627, 73, 1, 0, 0, 0, 628, 626, 1, 0, 0, 0, 629, 630, 3, 118, 59, 0, 630, 631, 5, 1, 0, 0, 631, 632, 3, 86, 43, 0, 632, 641, 1, 0, 0, 0, 633, 634, 3, 192, 96, 0, 634, 635, 7, 3, 0, 0, 635, 636, 3, 86, 43, 0, 636, 641, 1, 0, 0, 0, 637, 638, 3, 192, 96, 0, 638, 639, 3, 76, 38, 0, 639, 641, 1, 0, 0, 0, 640, 629, 1, 0, 0, 0, 640, 633, 1, 0, 0, 0, 640, 637, 1, 0, 0, 0, 641, 75, 1, 0, 0, 0, 642, 643, 5, 26, 0, 0, 643, 645, 3, 190, 95, 0, 644, 642, 1, 0, 0, 0, 645, 646, 1, 0, 0, 0, 646, 644, 1, 0, 0, 0, 646, 647, 1, 0, 0, 0, 647, 77, 1, 0, 0, 0, 648, 649, 5, 46, 0, 0, 649, 650, 3, 84, 42, 0, 650, 79, 1, 0, 0, 0, 651, 653, 3, 84, 42, 0, 652, 654, 3, 82, 41, 0, 653, 652, 1, 0, 0, 0, 653, 654, 1, 0, 0, 0, 654, 81, 1, 0, 0, 0, 655, 656, 5, 62, 0, 0, 656, 657, 3, 86, 43, 0, 657, 83, 1, 0, 0, 0, 658, 663, 3, 120, 60, 0, 659, 660, 5, 12, 0, 0, 660, 662, 3, 120, 60, 0, 661, 659, 1, 0, 0, 0, 662, 665, 1, 0, 0, 0, 663, 661, 1, 0, 0, 0, 663, 664, 1, 0, 0, 0, 664, 85, 1, 0, 0, 0, 665, 663, 1, 0, 0, 0, 666, 671, 3, 88, 44, 0, 667, 668, 5, 74, 0, 0, 668, 670, 3, 88, 44, 0, 669, 667, 1, 0, 0, 0, 670, 673, 1, 0, 0, 0, 671, 669, 1, 0, 0, 0, 671, 672, 1, 0, 0, 0, 672, 87, 1, 0, 0, 0, 673, 671, 1, 0, 0, 0, 674, 679, 3, 90, 45, 0, 675, 676, 5, 76, 0, 0, 676, 678, 3, 90, 45, 0, 677, 675, 1, 0, 0, 0, 678, 681, 1, 0, 0, 0, 679, 677, 1, 0, 0, 0, 679, 680, 1, 0, 0, 0, 680, 89, 1, 0, 0, 0, 681, 679, 1, 0, 0, 0, 682, 687, 3, 92, 46, 0, 683, 684, 5, 66, 0, 0, 684, 686, 3, 92, 46, 0, 685, 683, 1, 0, 0, 0, 686, 689, 1, 0, 0, 0, 687, 685, 1, 0, 0, 0, 687, 688, 1, 0, 0, 0, 688, 91, 1, 0, 0, 0, 689, 687, 1, 0, 0, 0, 690, 692, 5, 73, 0, 0, 691, 690, 1, 0, 0, 0, 691, 692, 1, 0, 0, 0, 692, 693, 1, 0, 0, 0, 693, 703, 3, 94, 47, 0, 694, 696, 5, 73, 0, 0, 695, 694, 1, 0, 0, 0, 695, 696, 1, 0, 0, 0, 696, 697, 1, 0, 0, 0, 697, 703, 3, 16, 8, 0, 698, 699, 3, 18, 9, 0, 699, 700, 3, 96, 48, 0, 700, 701, 3, 86, 43, 0, 701, 703, 1, 0, 0, 0, 702, 691, 1, 0, 0, 0, 702, 695, 1, 0, 0, 0, 702, 698, 1, 0, 0, 0, 703, 93, 1, 0, 0, 0, 704, 710, 3, 98, 49, 0, 705, 706, 3, 96, 48, 0, 706, 707, 3, 98, 49, 0, 707, 709, 1, 0, 0, 0, 708, 705, 1, 0, 0, 0, 709, 712, 1, 0, 0, 0, 710, 708, 1, 0, 0, 0, 710, 711, 1, 0, 0, 0, 711, 95, 1, 0, 0, 0, 712, 710, 1, 0, 0, 0, 713, 714, 7, 4, 0, 0, 714, 97, 1, 0, 0, 0, 715, 720, 3, 100, 50, 0, 716, 717, 7, 5, 0, 0, 717, 719, 3, 100, 50, 0, 718, 716, 1, 0, 0, 0, 719, 722, 1, 0, 0, 0, 720, 718, 1, 0, 0, 0, 720, 721, 1, 0, 0, 0, 721, 99, 1, 0, 0, 0, 722, 720, 1, 0, 0, 0, 723, 728, 3, 102, 51, 0, 724, 725, 7, 6, 0, 0, 725, 727, 3, 102, 51, 0, 726, 724, 1, 0, 0, 0, 727, 730, 1, 0, 0, 0, 728, 726, 1, 0, 0, 0, 728, 729, 1, 0, 0, 0, 729, 101, 1, 0, 0, 0, 730, 728, 1, 0, 0, 0, 731, 736, 3, 104, 52, 0, 732, 733, 5, 23, 0, 0, 733, 735, 3, 104, 52, 0, 734, 732, 1, 0, 0, 0, 735, 738, 1, 0, 0, 0, 736, 734, 1, 0, 0, 0, 736, 737, 1, 0, 0, 0, 737, 103, 1, 0, 0, 0, 738, 736, 1, 0, 0, 0, 739, 741, 7, 5, 0, 0, 740, 739, 1, 0, 0, 0, 740, 741, 1, 0, 0, 0, 741, 742, 1, 0, 0, 0, 742, 743, 3, 106, 53, 0, 743, 105, 1, 0, 0, 0, 744, 750, 3, 116, 58, 0, 745, 749, 3, 110, 55, 0, 746, 749, 3, 108, 54, 0, 747, 749, 3, 114, 57, 0, 748, 745, 1, 0, 0, 0, 748, 746, 1, 0, 0, 0, 748, 747, 1, 0, 0, 0, 749, 752, 1, 0, 0, 0, 750, 748, 1, 0, 0, 0, 750, 751, 1, 0, 0, 0, 751, 107, 1, 0, 0, 0, 752, 750, 1, 0, 0, 0, 753, 754, 5, 71, 0, 0, 754, 768, 3, 116, 58, 0, 755, 764, 5, 17, 0, 0, 756, 758, 3, 86, 43, 0, 757, 756, 1, 0, 0, 0, 757, 758, 1, 0, 0, 0, 758, 759, 1, 0, 0, 0, 759, 761, 5, 9, 0, 0, 760, 762, 3, 86, 43, 0, 761, 760, 1, 0, 0, 0, 761, 762, 1, 0, 0, 0, 762, 765, 1, 0, 0, 0, 763, 765, 3, 86, 43, 0, 764, 757, 1, 0, 0, 0, 764, 763, 1, 0, 0, 0, 765, 766, 1, 0, 0, 0, 766, 768, 5, 18, 0, 0, 767, 753, 1, 0, 0, 0, 767, 755, 1, 0, 0, 0, 768, 109, 1, 0, 0, 0, 769, 770, 3, 112, 56, 0, 770, 771, 3, 116, 58, 0, 771, 111, 1, 0, 0, 0, 772, 773, 5, 75, 0, 0, 773, 778, 5, 63, 0, 0, 774, 775, 5, 70, 0, 0, 775, 778, 5, 63, 0, 0, 776, 778, 5, 68, 0, 0, 777, 772, 1, 0, 0, 0, 777, 774, 1, 0, 0, 0, 777, 776, 1, 0, 0, 0, 778, 113, 1, 0, 0, 0, 779, 781, 5, 72, 0, 0, 780, 782, 5, 73, 0, 0, 781, 780, 1, 0, 0, 0, 781, 782, 1, 0, 0, 0, 782, 783, 1, 0, 0, 0, 783, 784, 5, 79, 0, 0, 784, 115, 1, 0, 0, 0, 785, 787, 3, 118, 59, 0, 786, 788, 3, 76, 38, 0, 787, 786, 1, 0, 0, 0, 787, 788, 1, 0, 0, 0, 788, 117, 1, 0, 0, 0, 789, 794, 3, 132, 66, 0, 790, 791, 5, 11, 0, 0, 791, 793, 3, 190, 95, 0, 792, 790, 1, 0, 0, 0, 793, 796, 1, 0, 0, 0, 794, 792, 1, 0, 0, 0, 794, 795, 1, 0, 0, 0, 795, 119, 1, 0, 0, 0, 796, 794, 1, 0, 0, 0, 797, 798, 3, 192, 96, 0, 798, 799, 5, 1, 0, 0, 799, 801, 1, 0, 0, 0, 800, 797, 1, 0, 0, 0, 800, 801, 1, 0, 0, 0, 801, 802, 1, 0, 0, 0, 802, 810, 3, 124, 62, 0, 803, 804, 3, 192, 96, 0, 804, 805, 5, 1, 0, 0, 805, 807, 1, 0, 0, 0, 806, 803, 1, 0, 0, 0, 806, 807, 1, 0, 0, 0, 807, 808, 1, 0, 0, 0, 808, 810, 3, 122, 61, 0, 809, 800, 1, 0, 0, 0, 809, 806, 1, 0, 0, 0, 810, 121, 1, 0, 0, 0, 811, 812, 7, 7, 0, 0, 812, 813, 5, 13, 0, 0, 813, 814, 3, 124, 62, 0, 814, 815, 5, 14, 0, 0, 815, 123, 1, 0, 0, 0, 816, 820, 3, 130, 65, 0, 817, 819, 3, 126, 63, 0, 818, 817, 1, 0, 0, 0, 819, 822, 1, 0, 0, 0, 820, 818, 1, 0, 0, 0, 820, 821, 1, 0, 0, 0, 821, 828, 1, 0, 0, 0, 822, 820, 1, 0, 0, 0, 823, 824, 5, 13, 0, 0, 824, 825, 3, 124, 62, 0, 825, 826, 5, 14, 0, 0, 826, 828, 1, 0, 0, 0, 827, 816, 1, 0, 0, 0, 827, 823, 1, 0, 0, 0, 828, 125, 1, 0, 0, 0, 829, 830, 3, 136, 68, 0, 830, 831, 3, 130, 65, 0, 831, 127, 1, 0, 0, 0, 832, 835, 3, 186, 93, 0, 833, 835, 3, 168, 84, 0, 834, 832, 1, 0, 0, 0, 834, 833, 1, 0, 0, 0, 835, 129, 1, 0, 0, 0, 836, 838, 5, 13, 0, 0, 837, 839, 3, 192, 96, 0, 838, 837, 1, 0, 0, 0, 838, 839, 1, 0, 0, 0, 839, 841, 1, 0, 0, 0, 840, 842, 3, 76, 38, 0, 841, 840, 1, 0, 0, 0, 841, 842, 1, 0, 0, 0, 842, 844, 1, 0, 0, 0, 843, 845, 3, 128, 64, 0, 844, 843, 1, 0, 0, 0, 844, 845, 1, 0, 0, 0, 845, 846, 1, 0, 0, 0, 846, 847, 5, 14, 0, 0, 847, 131, 1, 0, 0, 0, 848, 861, 3, 170, 85, 0, 849, 861, 3, 168, 84, 0, 850, 861, 3, 166, 83, 0, 851, 861, 3, 162, 81, 0, 852, 861, 3, 158, 79, 0, 853, 861, 3, 154, 77, 0, 854, 861, 3, 152, 76, 0, 855, 861, 3, 156, 78, 0, 856, 861, 3, 150, 75, 0, 857, 861, 3, 148, 74, 0, 858, 861, 3, 192, 96, 0, 859, 861, 3, 144, 72, 0, 860, 848, 1, 0, 0, 0, 860, 849, 1, 0, 0, 0, 860, 850, 1, 0, 0, 0, 860, 851, 1, 0, 0, 0, 860, 852, 1, 0, 0, 0, 860, 853, 1, 0, 0, 0, 860, 854, 1, 0, 0, 0, 860, 855, 1, 0, 0, 0, 860, 856, 1, 0, 0, 0, 860, 857, 1, 0, 0, 0, 860, 858, 1, 0, 0, 0, 860, 859, 1, 0, 0, 0, 861, 133, 1, 0, 0, 0, 862, 863, 3, 192, 96, 0, 863, 864, 5, 1, 0, 0, 864, 135, 1, 0, 0, 0, 865, 866, 5, 6, 0, 0, 866, 868, 5, 19, 0, 0, 867, 869, 3, 138, 69, 0, 868, 867, 1, 0, 0, 0, 868, 869, 1, 0, 0, 0, 869, 870, 1, 0, 0, 0, 870, 872, 5, 19, 0, 0, 871, 873, 5, 5, 0, 0, 872, 871, 1, 0, 0, 0, 872, 873, 1, 0, 0, 0, 873, 883, 1, 0, 0, 0, 874, 876, 5, 19, 0, 0, 875, 877, 3, 138, 69, 0, 876, 875, 1, 0, 0, 0, 876, 877, 1, 0, 0, 0, 877, 878, 1, 0, 0, 0, 878, 880, 5, 19, 0, 0, 879, 881, 5, 5, 0, 0, 880, 879, 1, 0, 0, 0, 880, 881, 1, 0, 0, 0, 881, 883, 1, 0, 0, 0, 882, 865, 1, 0, 0, 0, 882, 874, 1, 0, 0, 0, 883, 137, 1, 0, 0, 0, 884, 886, 5, 17, 0, 0, 885, 887, 3, 192, 96, 0, 886, 885, 1, 0, 0, 0, 886, 887, 1, 0, 0, 0, 887, 889, 1, 0, 0, 0, 888, 890, 3, 140, 70, 0, 889, 888, 1, 0, 0, 0, 889, 890, 1, 0, 0, 0, 890, 892, 1, 0, 0, 0, 891, 893, 3, 172, 86, 0, 892, 891, 1, 0, 0, 0, 892, 893, 1, 0, 0, 0, 893, 895, 1, 0, 0, 0, 894, 896, 3, 128, 64, 0, 895, 894, 1, 0, 0, 0, 895, 896, 1, 0, 0, 0, 896, 897, 1, 0, 0, 0, 897, 898, 5, 18, 0, 0, 898, 139, 1, 0, 0, 0, 899, 900, 5, 26, 0, 0, 900, 908, 3, 190, 95, 0, 901, 903, 5, 27, 0, 0, 902, 904, 5, 26, 0, 0, 903, 902, 1, 0, 0, 0, 903, 904, 1, 0, 0, 0, 904, 905, 1, 0, 0, 0, 905, 907, 3, 190, 95, 0, 906, 901, 1, 0, 0, 0, 907, 910, 1, 0, 0, 0, 908, 906, 1, 0, 0, 0, 908, 909, 1, 0, 0, 0, 909, 141, 1, 0, 0, 0, 910, 908, 1, 0, 0, 0, 911, 913, 5, 64, 0, 0, 912, 914, 5, 42, 0, 0, 913, 912, 1, 0, 0, 0, 913, 914, 1, 0, 0, 0, 914, 915, 1, 0, 0, 0, 915, 916, 3, 12, 6, 0, 916, 143, 1, 0, 0, 0, 917, 918, 5, 51, 0, 0, 918, 921, 5, 15, 0, 0, 919, 922, 3, 10, 5, 0, 920, 922, 3, 80, 40, 0, 921, 919, 1, 0, 0, 0, 921, 920, 1, 0, 0, 0, 922, 923, 1, 0, 0, 0, 923, 924, 5, 16, 0, 0, 924, 145, 1, 0, 0, 0, 925, 930, 3, 192, 96, 0, 926, 927, 5, 11, 0, 0, 927, 929, 3, 192, 96, 0, 928, 926, 1, 0, 0, 0, 929, 932, 1, 0, 0, 0, 930, 928, 1, 0, 0, 0, 930, 931, 1, 0, 0, 0, 931, 147, 1, 0, 0, 0, 932, 930, 1, 0, 0, 0, 933, 934, 3, 146, 73, 0, 934, 936, 5, 13, 0, 0, 935, 937, 5, 69, 0, 0, 936, 935, 1, 0, 0, 0, 936, 937, 1, 0, 0, 0, 937, 939, 1, 0, 0, 0, 938, 940, 3, 164, 82, 0, 939, 938, 1, 0, 0, 0, 939, 940, 1, 0, 0, 0, 940, 941, 1, 0, 0, 0, 941, 942, 5, 14, 0, 0, 942, 149, 1, 0, 0, 0, 943, 944, 5, 13, 0, 0, 944, 945, 3, 86, 43, 0, 945, 946, 5, 14, 0, 0, 946, 151, 1, 0, 0, 0, 947, 948, 7, 8, 0, 0, 948, 949, 5, 13, 0, 0, 949, 950, 3, 160, 80, 0, 950, 951, 5, 14, 0, 0, 951, 153, 1, 0, 0, 0, 952, 954, 5, 17, 0, 0, 953, 955, 3, 134, 67, 0, 954, 953, 1, 0, 0, 0, 954, 955, 1, 0, 0, 0, 955, 956, 1, 0, 0, 0, 956, 958, 3, 156, 78, 0, 957, 959, 3, 82, 41, 0, 958, 957, 1, 0, 0, 0, 958, 959, 1, 0, 0, 0, 959, 960, 1, 0, 0, 0, 960, 961, 5, 27, 0, 0, 961, 962, 3, 86, 43, 0, 962, 963, 5, 18, 0, 0, 963, 155, 1, 0, 0, 0, 964, 966, 3, 130, 65, 0, 965, 967, 3, 126, 63, 0, 966, 965, 1, 0, 0, 0, 967, 968, 1, 0, 0, 0, 968, 966, 1, 0, 0, 0, 968, 969, 1, 0, 0, 0, 969, 157, 1, 0, 0, 0, 970, 971, 5, 17, 0, 0, 971, 974, 3, 160, 80, 0, 972, 973, 5, 27, 0, 0, 973, 975, 3, 86, 43, 0, 974, 972, 1, 0, 0, 0, 974, 975, 1, 0, 0, 0, 975, 976, 1, 0, 0, 0, 976, 977, 5, 18, 0, 0, 977, 159, 1, 0, 0, 0, 978, 979, 3, 192, 96, 0, 979, 980, 5, 71, 0, 0, 980, 982, 3, 86, 43, 0, 981, 983, 3, 82, 41, 0, 982, 981, 1, 0, 0, 0, 982, 983, 1, 0, 0, 0, 983, 161, 1, 0, 0, 0, 984, 985, 5, 33, 0, 0, 985, 986, 5, 13, 0, 0, 986, 987, 5, 24, 0, 0, 987, 988, 5, 14, 0, 0, 988, 163, 1, 0, 0, 0, 989, 994, 3, 86, 43, 0, 990, 991, 5, 12, 0, 0, 991, 993, 3, 86, 43, 0, 992, 990, 1, 0, 0, 0, 993, 996, 1, 0, 0, 0, 994, 992, 1, 0, 0, 0, 994, 995, 1, 0, 0, 0, 995, 165, 1, 0, 0, 0, 996, 994, 1, 0, 0, 0, 997, 999, 5, 85, 0, 0, 998, 1000, 3, 86, 43, 0, 999, 998, 1, 0, 0, 0, 999, 1000, 1, 0, 0, 0, 1000, 1006, 1, 0, 0, 0, 1001, 1002, 5, 86, 0, 0, 1002, 1003, 3, 86, 43, 0, 1003, 1004, 5, 87, 0, 0, 1004, 1005, 3, 86, 43, 0, 1005, 1007, 1, 0, 0, 0, 1006, 1001, 1, 0, 0, 0, 1007, 1008, 1, 0, 0, 0, 1008, 1006, 1, 0, 0, 0, 1008, 1009, 1, 0, 0, 0, 1009, 1012, 1, 0, 0, 0, 1010, 1011, 5, 88, 0, 0, 1011, 1013, 3, 86, 43, 0, 1012, 1010, 1, 0, 0, 0, 1012, 1013, 1, 0, 0, 0, 1013, 1014, 1, 0, 0, 0, 1014, 1015, 5, 89, 0, 0, 1015, 167, 1, 0, 0, 0, 1016, 1019, 5, 28, 0, 0, 1017, 1020, 3, 192, 96, 0, 1018, 1020, 3, 178, 89, 0, 1019, 1017, 1, 0, 0, 0, 1019, 1018, 1, 0, 0, 0, 1020, 169, 1, 0, 0, 0, 1021, 1029, 3, 174, 87, 0, 1022, 1029, 3, 178, 89, 0, 1023, 1029, 5, 79, 0, 0, 1024, 1029, 3, 180, 90, 0, 1025, 1029, 3, 182, 91, 0, 1026, 1029, 3, 184, 92, 0, 1027, 1029, 3, 186, 93, 0, 1028, 1021, 1, 0, 0, 0, 1028, 1022, 1, 0, 0, 0, 1028, 1023, 1, 0, 0, 0, 1028, 1024, 1, 0, 0, 0, 1028, 1025, 1, 0, 0, 0, 1028, 1026, 1, 0, 0, 0, 1028, 1027, 1, 0, 0, 0, 1029, 171, 1, 0, 0, 0, 1030, 1032, 5, 24, 0, 0, 1031, 1033, 3, 176, 88, 0, 1032, 1031, 1, 0, 0, 0, 1032, 1033, 1, 0, 0, 0, 1033, 1038, 1, 0, 0, 0, 1034, 1036, 5, 9, 0, 0, 1035, 1037, 3, 176, 88, 0, 1036, 1035, 1, 0, 0, 0, 1036, 1037, 1, 0, 0, 0, 1037, 1039, 1, 0, 0, 0, 1038, 1034, 1, 0, 0, 0, 1038, 1039, 1, 0, 0, 0, 1039, 173, 1, 0, 0, 0, 1040, 1041, 7, 9, 0, 0, 1041, 175, 1, 0, 0, 0, 1042, 1043, 7, 10, 0, 0, 1043, 177, 1, 0, 0, 0, 1044, 1047, 5, 117, 0, 0, 1045, 1047, 3, 176, 88, 0, 1046, 1044, 1, 0, 0, 0, 1046, 1045, 1, 0, 0, 0, 1047, 179, 1, 0, 0, 0, 1048, 1049, 5, 123, 0, 0, 1049, 181, 1, 0, 0, 0, 1050, 1051, 5, 122, 0, 0, 1051, 183, 1, 0, 0, 0, 1052, 1054, 5, 17, 0, 0, 1053, 1055, 3, 164, 82, 0, 1054, 1053, 1, 0, 0, 0, 1054, 1055, 1, 0, 0, 0, 1055, 1056, 1, 0, 0, 0, 1056, 1057, 5, 18, 0, 0, 1057, 185, 1, 0, 0, 0, 1058, 1067, 5, 15, 0, 0, 1059, 1064, 3, 188, 94, 0, 1060, 1061, 5, 12, 0, 0, 1061, 1063, 3, 188, 94, 0, 1062, 1060, 1, 0, 0, 0, 1063, 1066, 1, 0, 0, 0, 1064, 1062, 1, 0, 0, 0, 1064, 1065, 1, 0, 0, 0, 1065, 1068, 1, 0, 0, 0, 1066, 1064, 1, 0, 0, 0, 1067, 1059, 1, 0, 0, 0, 1067, 1068, 1, 0, 0, 0, 1068, 1069, 1, 0, 0, 0, 1069, 1070, 5, 16, 0, 0, 1070, 187, 1, 0, 0, 0, 1071, 1072, 3, 190, 95, 0, 1072, 1073, 5, 26, 0, 0, 1073, 1074, 3, 86, 43, 0, 1074, 189, 1, 0, 0, 0, 1075, 1078, 3, 192, 96, 0, 1076, 1078, 3, 194, 97, 0, 1077, 1075, 1, 0, 0, 0, 1077, 1076, 1, 0, 0, 0, 1078, 191, 1, 0, 0, 0, 1079, 1080, 7, 11, 0, 0, 1080, 193, 1, 0, 0, 0, 1081, 1082, 7, 12, 0, 0, 1082, 195, 1, 0, 0, 0, 151, 201, 205, 210, 216, 230, 232, 237, 241, 246, 251, 255, 258, 261, 267, 272, 276, 279, 282, 292, 297, 301, 304, 307, 311, 316, 320, 325, 330, 334, 343, 348, 353, 356, 359, 364, 372, 374, 380, 385, 390, 395, 397, 419, 421, 424, 428, 430, 434, 442, 451, 455, 458, 461, 465, 471, 477, 481, 490, 496, 503, 506, 508, 512, 514, 518, 520, 526, 531, 541, 547, 554, 557, 568, 575, 582, 586, 595, 599, 604, 613, 626, 640, 646, 653, 663, 671, 679, 687, 691, 695, 702, 710, 720, 728, 736, 740, 748, 750, 757, 761, 764, 767, 777, 781, 787, 794, 800, 806, 809, 820, 827, 834, 838, 841, 844, 860, 868, 872, 876, 880, 882, 886, 889, 892, 895, 903, 908, 913, 921, 930, 936, 939, 954, 958, 968, 974, 982, 994, 999, 1008, 1012, 1019, 1028, 1032, 1036, 1038, 1046, 1054, 1064, 1067, 1077]
\ No newline at end of file
diff --git a/nornicdb/pkg/cypher/antlr/CypherParser.tokens b/nornicdb/pkg/cypher/antlr/CypherParser.tokens
new file mode 100644
index 0000000..663ccb8
--- /dev/null
+++ b/nornicdb/pkg/cypher/antlr/CypherParser.tokens
@@ -0,0 +1,243 @@
+ASSIGN=1
+ADD_ASSIGN=2
+LE=3
+GE=4
+GT=5
+LT=6
+NOT_EQUAL=7
+REGEX_MATCH=8
+RANGE=9
+SEMI=10
+DOT=11
+COMMA=12
+LPAREN=13
+RPAREN=14
+LBRACE=15
+RBRACE=16
+LBRACK=17
+RBRACK=18
+SUB=19
+PLUS=20
+DIV=21
+MOD=22
+CARET=23
+MULT=24
+ESC=25
+COLON=26
+STICK=27
+DOLLAR=28
+CALL=29
+YIELD=30
+FILTER=31
+EXTRACT=32
+COUNT=33
+SUM=34
+AVG=35
+MIN=36
+MAX=37
+COLLECT=38
+ANY=39
+NONE=40
+SINGLE=41
+ALL=42
+ASC=43
+ASCENDING=44
+BY=45
+CREATE=46
+DELETE=47
+DESC=48
+DESCENDING=49
+DETACH=50
+EXISTS=51
+LIMIT=52
+MATCH=53
+MERGE=54
+ON=55
+OPTIONAL=56
+ORDER=57
+REMOVE=58
+RETURN=59
+SET=60
+SKIP_W=61
+WHERE=62
+WITH=63
+UNION=64
+UNWIND=65
+AND=66
+AS=67
+CONTAINS=68
+DISTINCT=69
+ENDS=70
+IN=71
+IS=72
+NOT=73
+OR=74
+STARTS=75
+XOR=76
+FALSE=77
+TRUE=78
+NULL_W=79
+CONSTRAINT=80
+DO=81
+FOR=82
+REQUIRE=83
+UNIQUE=84
+CASE=85
+WHEN=86
+THEN=87
+ELSE=88
+END=89
+MANDATORY=90
+SCALAR=91
+OF=92
+ADD=93
+DROP=94
+INDEX=95
+INDEXES=96
+VECTOR=97
+EXPLAIN=98
+PROFILE=99
+SHOW=100
+CONSTRAINTS=101
+PROCEDURES=102
+FUNCTIONS=103
+DATABASE=104
+DATABASES=105
+FULLTEXT=106
+OPTIONS=107
+EACH=108
+IF=109
+TRANSACTIONS=110
+ROWS=111
+ASSERT=112
+KEY=113
+NODE=114
+SHORTESTPATH=115
+ALLSHORTESTPATHS=116
+FLOAT=117
+INTEGER=118
+DIGIT=119
+ID=120
+ESC_LITERAL=121
+CHAR_LITERAL=122
+STRING_LITERAL=123
+WS=124
+COMMENT=125
+LINE_COMMENT=126
+ERRCHAR=127
+Letter=128
+'='=1
+'+='=2
+'<='=3
+'>='=4
+'>'=5
+'<'=6
+'=~'=8
+'..'=9
+';'=10
+'.'=11
+','=12
+'('=13
+')'=14
+'{'=15
+'}'=16
+'['=17
+']'=18
+'-'=19
+'+'=20
+'/'=21
+'%'=22
+'^'=23
+'*'=24
+'`'=25
+':'=26
+'|'=27
+'$'=28
+'CALL'=29
+'YIELD'=30
+'FILTER'=31
+'EXTRACT'=32
+'COUNT'=33
+'SUM'=34
+'AVG'=35
+'MIN'=36
+'MAX'=37
+'COLLECT'=38
+'ANY'=39
+'NONE'=40
+'SINGLE'=41
+'ALL'=42
+'ASC'=43
+'ASCENDING'=44
+'BY'=45
+'CREATE'=46
+'DELETE'=47
+'DESC'=48
+'DESCENDING'=49
+'DETACH'=50
+'EXISTS'=51
+'LIMIT'=52
+'MATCH'=53
+'MERGE'=54
+'ON'=55
+'OPTIONAL'=56
+'ORDER'=57
+'REMOVE'=58
+'RETURN'=59
+'SET'=60
+'SKIP'=61
+'WHERE'=62
+'WITH'=63
+'UNION'=64
+'UNWIND'=65
+'AND'=66
+'AS'=67
+'CONTAINS'=68
+'DISTINCT'=69
+'ENDS'=70
+'IN'=71
+'IS'=72
+'NOT'=73
+'OR'=74
+'STARTS'=75
+'XOR'=76
+'FALSE'=77
+'TRUE'=78
+'NULL'=79
+'CONSTRAINT'=80
+'DO'=81
+'FOR'=82
+'REQUIRE'=83
+'UNIQUE'=84
+'CASE'=85
+'WHEN'=86
+'THEN'=87
+'ELSE'=88
+'END'=89
+'MANDATORY'=90
+'SCALAR'=91
+'OF'=92
+'ADD'=93
+'DROP'=94
+'INDEX'=95
+'INDEXES'=96
+'VECTOR'=97
+'EXPLAIN'=98
+'PROFILE'=99
+'SHOW'=100
+'CONSTRAINTS'=101
+'PROCEDURES'=102
+'FUNCTIONS'=103
+'DATABASE'=104
+'DATABASES'=105
+'FULLTEXT'=106
+'OPTIONS'=107
+'EACH'=108
+'IF'=109
+'TRANSACTIONS'=110
+'ROWS'=111
+'ASSERT'=112
+'KEY'=113
+'NODE'=114
+'shortestPath'=115
+'allShortestPaths'=116
diff --git a/nornicdb/pkg/cypher/antlr/analyzer.go b/nornicdb/pkg/cypher/antlr/analyzer.go
new file mode 100644
index 0000000..3826278
--- /dev/null
+++ b/nornicdb/pkg/cypher/antlr/analyzer.go
@@ -0,0 +1,324 @@
+// Package antlr provides ANTLR-based Cypher parsing for NornicDB.
+package antlr
+
+import (
+ "sync"
+
+ "github.com/antlr4-go/antlr/v4"
+)
+
+// ClauseType represents the type of a Cypher clause
+type ClauseType int
+
+const (
+ ClauseUnknown ClauseType = iota
+ ClauseMatch
+ ClauseCreate
+ ClauseMerge
+ ClauseDelete
+ ClauseSet
+ ClauseRemove
+ ClauseReturn
+ ClauseWith
+ ClauseUnwind
+ ClauseCall
+ ClauseForeach
+ ClauseLoadCSV
+ ClauseShow
+ ClauseDrop
+ ClauseOptionalMatch
+)
+
+// QueryInfo contains analyzed information about a Cypher query extracted from AST
+type QueryInfo struct {
+ // Query type flags
+ HasMatch bool
+ HasOptionalMatch bool
+ HasCreate bool
+ HasMerge bool
+ HasDelete bool
+ HasDetachDelete bool
+ HasSet bool
+ HasRemove bool
+ HasReturn bool
+ HasWith bool
+ HasUnwind bool
+ HasCall bool
+ HasExplain bool
+ HasProfile bool
+ HasShow bool
+ HasSchema bool // DROP INDEX, CREATE CONSTRAINT, etc.
+ HasUnion bool
+ HasUnionAll bool
+ HasForeach bool
+ HasLoadCSV bool
+
+ // FirstClause is the type of the first main clause in the query
+ // Used for routing (e.g., "starts with MATCH" vs "starts with CREATE")
+ FirstClause ClauseType
+
+ // CallIsDbProcedure is true when the query calls a db.* procedure
+ // These are metadata queries (db.labels, db.schema, etc.) that are safe to cache
+ CallIsDbProcedure bool
+
+ // HasShortestPath is true if query uses shortestPath() or allShortestPaths()
+ HasShortestPath bool
+
+ // MergeCount is the number of MERGE clauses (for detecting multiple MERGEs)
+ MergeCount int
+
+ // ClauseCount tracks number of main clause types (MATCH, CREATE, MERGE, DELETE, SET)
+ // Incremented during AST walk - used for IsCompoundQuery derivation
+ ClauseCount int
+
+ // Derived properties
+ IsReadOnly bool
+ IsWriteQuery bool
+ IsSchemaQuery bool
+
+ // IsCompoundQuery is true if query has multiple clause types (e.g., MATCH...CREATE)
+ IsCompoundQuery bool
+
+ // Labels mentioned in the query (for cache invalidation)
+ Labels []string
+
+ // The inner query (without EXPLAIN/PROFILE prefix)
+ InnerQuery string
+}
+
+// QueryAnalyzer walks ANTLR parse trees to extract query metadata
+type QueryAnalyzer struct {
+ cache map[string]*QueryInfo
+ cacheMu sync.RWMutex
+}
+
+// NewQueryAnalyzer creates a new query analyzer
+func NewQueryAnalyzer() *QueryAnalyzer {
+ return &QueryAnalyzer{
+ cache: make(map[string]*QueryInfo),
+ }
+}
+
+// Analyze extracts query information from a parse result
+// Results are cached by query string for performance
+func (a *QueryAnalyzer) Analyze(query string, parseResult *ParseResult) *QueryInfo {
+ // Check cache first
+ a.cacheMu.RLock()
+ if info, ok := a.cache[query]; ok {
+ a.cacheMu.RUnlock()
+ return info
+ }
+ a.cacheMu.RUnlock()
+
+ // Walk the AST to extract info
+ info := &QueryInfo{
+ InnerQuery: query,
+ }
+
+ if parseResult != nil && parseResult.Tree != nil {
+ walker := &queryWalker{info: info, query: query}
+ antlr.ParseTreeWalkerDefault.Walk(walker, parseResult.Tree)
+ }
+
+ // Derive properties
+ info.IsWriteQuery = info.HasCreate || info.HasMerge || info.HasDelete || info.HasSet || info.HasRemove
+
+ // Determine if query is read-only (safe to cache)
+ // - Must not be a write query or schema change
+ // - CALL procedures are NOT read-only UNLESS they're db.* metadata queries
+ // - Pure read patterns (MATCH, RETURN without writes) are read-only
+ callIsReadOnly := info.HasCall && info.CallIsDbProcedure
+ hasReadPattern := info.HasMatch || info.HasReturn || info.HasWith || info.HasUnwind
+
+ info.IsReadOnly = !info.IsWriteQuery && !info.HasSchema &&
+ (callIsReadOnly || (!info.HasCall && hasReadPattern))
+
+ info.IsSchemaQuery = info.HasSchema || info.HasShow
+
+ // IsCompoundQuery derived from clause counts tracked during AST walk
+ info.IsCompoundQuery = info.ClauseCount > 1 || info.MergeCount > 1
+
+ // Cache the result
+ a.cacheMu.Lock()
+ a.cache[query] = info
+ a.cacheMu.Unlock()
+
+ return info
+}
+
+// ClearCache clears the analysis cache
+func (a *QueryAnalyzer) ClearCache() {
+ a.cacheMu.Lock()
+ a.cache = make(map[string]*QueryInfo)
+ a.cacheMu.Unlock()
+}
+
+// queryWalker implements antlr.ParseTreeListener to walk the AST
+type queryWalker struct {
+ *BaseCypherParserListener
+ info *QueryInfo
+ query string
+ firstClauseSet bool // Track if we've seen the first clause
+}
+
+// setFirstClause sets the first clause type if not already set
+func (w *queryWalker) setFirstClause(ct ClauseType) {
+ if !w.firstClauseSet {
+ w.info.FirstClause = ct
+ w.firstClauseSet = true
+ }
+}
+
+// EnterQueryPrefix detects EXPLAIN/PROFILE
+func (w *queryWalker) EnterQueryPrefix(ctx *QueryPrefixContext) {
+ text := ctx.GetText()
+ if text == "EXPLAIN" {
+ w.info.HasExplain = true
+ } else if text == "PROFILE" {
+ w.info.HasProfile = true
+ }
+}
+
+// EnterMatchSt detects MATCH clauses (including OPTIONAL MATCH)
+func (w *queryWalker) EnterMatchSt(ctx *MatchStContext) {
+ // Check if this is an OPTIONAL MATCH
+ if ctx.OPTIONAL() != nil {
+ w.info.HasOptionalMatch = true
+ w.setFirstClause(ClauseOptionalMatch)
+ return
+ }
+ if !w.info.HasMatch {
+ w.info.HasMatch = true
+ w.info.ClauseCount++
+ }
+ w.setFirstClause(ClauseMatch)
+}
+
+// EnterCreateSt detects CREATE clauses
+func (w *queryWalker) EnterCreateSt(ctx *CreateStContext) {
+ if !w.info.HasCreate {
+ w.info.HasCreate = true
+ w.info.ClauseCount++
+ }
+ w.setFirstClause(ClauseCreate)
+}
+
+// EnterMergeSt detects MERGE clauses
+func (w *queryWalker) EnterMergeSt(ctx *MergeStContext) {
+ if !w.info.HasMerge {
+ w.info.HasMerge = true
+ w.info.ClauseCount++
+ }
+ w.info.MergeCount++
+ w.setFirstClause(ClauseMerge)
+}
+
+// EnterDeleteSt detects DELETE clauses
+func (w *queryWalker) EnterDeleteSt(ctx *DeleteStContext) {
+ if !w.info.HasDelete {
+ w.info.HasDelete = true
+ w.info.ClauseCount++
+ }
+ if ctx.DETACH() != nil {
+ w.info.HasDetachDelete = true
+ }
+ w.setFirstClause(ClauseDelete)
+}
+
+// EnterSetSt detects SET clauses
+func (w *queryWalker) EnterSetSt(ctx *SetStContext) {
+ if !w.info.HasSet {
+ w.info.HasSet = true
+ w.info.ClauseCount++
+ }
+ w.setFirstClause(ClauseSet)
+}
+
+// EnterRemoveSt detects REMOVE clauses
+func (w *queryWalker) EnterRemoveSt(ctx *RemoveStContext) {
+ w.info.HasRemove = true
+ w.setFirstClause(ClauseRemove)
+}
+
+// EnterReturnSt detects RETURN clauses
+func (w *queryWalker) EnterReturnSt(ctx *ReturnStContext) {
+ w.info.HasReturn = true
+ w.setFirstClause(ClauseReturn)
+}
+
+// EnterWithSt detects WITH clauses
+func (w *queryWalker) EnterWithSt(ctx *WithStContext) {
+ w.info.HasWith = true
+ w.setFirstClause(ClauseWith)
+}
+
+// EnterUnwindSt detects UNWIND clauses
+func (w *queryWalker) EnterUnwindSt(ctx *UnwindStContext) {
+ w.info.HasUnwind = true
+ w.setFirstClause(ClauseUnwind)
+}
+
+// EnterStandaloneCall detects standalone CALL statements (top-level)
+func (w *queryWalker) EnterStandaloneCall(ctx *StandaloneCallContext) {
+ w.info.HasCall = true
+ w.setFirstClause(ClauseCall)
+}
+
+// EnterCallSubquery detects CALL {} subqueries
+func (w *queryWalker) EnterCallSubquery(ctx *CallSubqueryContext) {
+ w.info.HasCall = true
+ w.setFirstClause(ClauseCall)
+}
+
+// EnterQueryCallSt detects CALL inside a regular query (e.g., CALL db.index...)
+func (w *queryWalker) EnterQueryCallSt(ctx *QueryCallStContext) {
+ w.info.HasCall = true
+ w.setFirstClause(ClauseCall)
+ // Check if this is a db.* procedure (safe to cache)
+ if ctx.InvocationName() != nil {
+ name := ctx.InvocationName().GetText()
+ if len(name) >= 3 && (name[:3] == "db." || name[:3] == "DB.") {
+ w.info.CallIsDbProcedure = true
+ }
+ }
+}
+
+// EnterShowCommand detects SHOW commands
+func (w *queryWalker) EnterShowCommand(ctx *ShowCommandContext) {
+ w.info.HasShow = true
+ w.info.HasSchema = true
+ w.setFirstClause(ClauseShow)
+}
+
+// EnterSchemaCommand detects schema commands (CREATE INDEX, etc.)
+func (w *queryWalker) EnterSchemaCommand(ctx *SchemaCommandContext) {
+ w.info.HasSchema = true
+ // Check if it's a DROP or CREATE command
+ if ctx.DROP() != nil {
+ w.setFirstClause(ClauseDrop)
+ } else if ctx.CREATE() != nil {
+ // CREATE INDEX or CREATE CONSTRAINT - still routed via ClauseCreate
+ w.setFirstClause(ClauseCreate)
+ }
+}
+
+// EnterPathFunction detects shortestPath/allShortestPaths
+func (w *queryWalker) EnterPathFunction(ctx *PathFunctionContext) {
+ w.info.HasShortestPath = true
+}
+
+// EnterNodeLabels collects node labels for cache invalidation
+func (w *queryWalker) EnterNodeLabels(ctx *NodeLabelsContext) {
+ for _, name := range ctx.AllName() {
+ w.info.Labels = append(w.info.Labels, name.GetText())
+ }
+}
+
+// EnterRelationshipTypes collects relationship types for cache invalidation
+// This is critical - the old regex extracted both node labels AND relationship types
+// for proper cache invalidation (e.g., :KNOWS, :BENCH_REL)
+func (w *queryWalker) EnterRelationshipTypes(ctx *RelationshipTypesContext) {
+ for _, name := range ctx.AllName() {
+ w.info.Labels = append(w.info.Labels, name.GetText())
+ }
+}
diff --git a/nornicdb/pkg/cypher/antlr/clauses.go b/nornicdb/pkg/cypher/antlr/clauses.go
new file mode 100644
index 0000000..f3725cd
--- /dev/null
+++ b/nornicdb/pkg/cypher/antlr/clauses.go
@@ -0,0 +1,369 @@
+// Package antlr - Clause extraction from ANTLR AST.
+//
+// This file provides utilities to extract individual clause CONTENT directly
+// from the AST structure, eliminating ALL string-based keyword parsing.
+// The extracted content is ready to use - no HasPrefix stripping needed.
+package antlr
+
+import (
+ "strings"
+
+ "github.com/antlr4-go/antlr/v4"
+)
+
+// ClauseInfo contains extracted clause CONTENT from AST (without keywords)
+type ClauseInfo struct {
+ // Content of each clause type - just the body, NOT the keyword
+ // Example: for "RETURN x, y" -> ReturnContent = "x, y"
+ MatchPattern string // Pattern from MATCH (n:Label) - just "(n:Label)"
+ MatchFull string // Full MATCH clause including keyword (for executeMatch)
+ OptionalMatches []string // Full OPTIONAL MATCH clauses
+ WhereCondition string // Condition from WHERE - just the expression
+ CreatePattern string // Pattern from CREATE
+ CreateFull string // Full CREATE clause
+ MergePattern string // Pattern from MERGE
+ MergeFull string // Full MERGE clause
+ MergePatterns []string // Multiple MERGE patterns
+ DeleteTargets string // Variables from DELETE - just "n, r"
+ DetachDelete bool // Whether DETACH DELETE
+ SetAssignments string // Assignments from SET - just "n.prop = value"
+ RemoveItems string // Items from REMOVE - just "n.prop, n:Label"
+ ReturnItems string // Items from RETURN - just "x, y AS alias"
+ WithItems string // Items from WITH - just "x, y"
+ WithItemsList []string // Multiple WITH items
+ UnwindExpr string // Expression from UNWIND
+ UnwindAs string // Variable from UNWIND AS
+ OrderByItems string // Items from ORDER BY - just "n.name DESC"
+ LimitValue string // Value from LIMIT - just "10"
+ SkipValue string // Value from SKIP - just "5"
+ CallProcedure string // Procedure call - just "db.labels()"
+
+ // ON CREATE SET / ON MATCH SET content (assignments only)
+ OnCreateSet string
+ OnMatchSet string
+
+ // Pattern parts extracted from MATCH
+ Patterns []string
+
+ // Variables defined in the query
+ Variables []string
+}
+
+// ClauseExtractor extracts clause information from ANTLR parse trees
+type ClauseExtractor struct {
+ info *ClauseInfo
+}
+
+// NewClauseExtractor creates a new extractor
+func NewClauseExtractor() *ClauseExtractor {
+ return &ClauseExtractor{
+ info: &ClauseInfo{},
+ }
+}
+
+// Extract extracts clause information from a parse result
+func (e *ClauseExtractor) Extract(parseResult *ParseResult) *ClauseInfo {
+ if parseResult == nil || parseResult.Tree == nil {
+ return e.info
+ }
+
+ // Walk the tree
+ walker := &clauseWalker{info: e.info}
+ antlr.ParseTreeWalkerDefault.Walk(walker, parseResult.Tree)
+
+ return e.info
+}
+
+// ExtractClauses is a convenience function that parses and extracts in one call
+func ExtractClauses(query string, parseResult *ParseResult) *ClauseInfo {
+ extractor := NewClauseExtractor()
+ return extractor.Extract(parseResult)
+}
+
+// clauseWalker walks the AST and extracts clause content
+type clauseWalker struct {
+ *BaseCypherParserListener
+ info *ClauseInfo
+}
+
+// getChildText extracts text from a child context
+func getChildText(ctx antlr.ParserRuleContext) string {
+ if ctx == nil {
+ return ""
+ }
+ start := ctx.GetStart()
+ stop := ctx.GetStop()
+ if start == nil || stop == nil {
+ return strings.TrimSpace(ctx.GetText())
+ }
+ input := start.GetInputStream()
+ if input == nil {
+ return strings.TrimSpace(ctx.GetText())
+ }
+ return strings.TrimSpace(input.GetText(start.GetStart(), stop.GetStop()))
+}
+
+// getFullText extracts text including whitespace from token positions
+func getFullText(ctx antlr.ParserRuleContext) string {
+ if ctx == nil {
+ return ""
+ }
+ start := ctx.GetStart()
+ stop := ctx.GetStop()
+ if start == nil || stop == nil {
+ return strings.TrimSpace(ctx.GetText())
+ }
+ input := start.GetInputStream()
+ if input == nil {
+ return strings.TrimSpace(ctx.GetText())
+ }
+ return input.GetText(start.GetStart(), stop.GetStop())
+}
+
+// EnterMatchSt captures MATCH clause - extracts pattern directly from AST
+func (w *clauseWalker) EnterMatchSt(ctx *MatchStContext) {
+ fullText := getFullText(ctx)
+
+ if ctx.OPTIONAL() != nil {
+ w.info.OptionalMatches = append(w.info.OptionalMatches, fullText)
+ } else if w.info.MatchFull == "" {
+ w.info.MatchFull = fullText
+ }
+
+ // Extract pattern content from PatternWhere child
+ if pw := ctx.PatternWhere(); pw != nil {
+ if pattern := pw.Pattern(); pattern != nil {
+ patternText := getChildText(pattern)
+ w.info.Patterns = append(w.info.Patterns, patternText)
+ if w.info.MatchPattern == "" {
+ w.info.MatchPattern = patternText
+ }
+ }
+ if where := pw.Where(); where != nil {
+ // WHERE child contains "WHERE condition" - extract just condition
+ // The Where context has Expression() child
+ if whereCtx, ok := where.(*WhereContext); ok {
+ if expr := whereCtx.Expression(); expr != nil {
+ w.info.WhereCondition = getChildText(expr)
+ }
+ }
+ }
+ }
+}
+
+// EnterCreateSt captures CREATE clause - extracts pattern from AST
+func (w *clauseWalker) EnterCreateSt(ctx *CreateStContext) {
+ if w.info.CreateFull == "" {
+ w.info.CreateFull = getFullText(ctx)
+ // CreateSt has Pattern() child containing just the pattern
+ if pattern := ctx.Pattern(); pattern != nil {
+ w.info.CreatePattern = getChildText(pattern)
+ }
+ }
+}
+
+// EnterMergeSt captures MERGE clause - extracts pattern from AST
+func (w *clauseWalker) EnterMergeSt(ctx *MergeStContext) {
+ fullText := getFullText(ctx)
+ if w.info.MergeFull == "" {
+ w.info.MergeFull = fullText
+ }
+
+ // MergeSt has PatternPart() child containing just the pattern
+ if patternPart := ctx.PatternPart(); patternPart != nil {
+ patternText := getChildText(patternPart)
+ w.info.MergePatterns = append(w.info.MergePatterns, patternText)
+ if w.info.MergePattern == "" {
+ w.info.MergePattern = patternText
+ }
+ }
+
+ // Extract ON CREATE SET / ON MATCH SET content from MergeAction children
+ for _, action := range ctx.AllMergeAction() {
+ if actionCtx, ok := action.(*MergeActionContext); ok {
+ // MergeAction has SetSt() which contains SetItem children
+ if setSt := actionCtx.SetSt(); setSt != nil {
+ if setCtx, ok := setSt.(*SetStContext); ok {
+ // Extract assignments directly from SetItem children
+ var assignments []string
+ for _, item := range setCtx.AllSetItem() {
+ assignments = append(assignments, getChildText(item))
+ }
+ assignmentsText := strings.Join(assignments, ", ")
+
+ // Determine if ON CREATE or ON MATCH using AST tokens
+ if actionCtx.CREATE() != nil {
+ w.info.OnCreateSet = assignmentsText
+ } else if actionCtx.MATCH() != nil {
+ w.info.OnMatchSet = assignmentsText
+ }
+ }
+ }
+ }
+ }
+}
+
+// EnterDeleteSt captures DELETE clause - extracts targets from ExpressionChain
+func (w *clauseWalker) EnterDeleteSt(ctx *DeleteStContext) {
+ if ctx.DETACH() != nil {
+ w.info.DetachDelete = true
+ }
+
+ // DeleteSt has ExpressionChain() containing the delete targets
+ if exprChain := ctx.ExpressionChain(); exprChain != nil {
+ w.info.DeleteTargets = getChildText(exprChain)
+ }
+}
+
+// EnterSetSt captures SET clause - extracts assignments from SetItem children
+func (w *clauseWalker) EnterSetSt(ctx *SetStContext) {
+ if w.info.SetAssignments != "" {
+ return
+ }
+
+ // SetSt has AllSetItem() containing the individual assignments
+ var assignments []string
+ for _, item := range ctx.AllSetItem() {
+ assignments = append(assignments, getChildText(item))
+ }
+ w.info.SetAssignments = strings.Join(assignments, ", ")
+}
+
+// EnterRemoveSt captures REMOVE clause - extracts items from RemoveItem children
+func (w *clauseWalker) EnterRemoveSt(ctx *RemoveStContext) {
+ if w.info.RemoveItems != "" {
+ return
+ }
+
+ // RemoveSt has AllRemoveItem() containing the individual items
+ var items []string
+ for _, item := range ctx.AllRemoveItem() {
+ items = append(items, getChildText(item))
+ }
+ w.info.RemoveItems = strings.Join(items, ", ")
+}
+
+// EnterReturnSt captures RETURN clause - extracts items from ProjectionBody
+func (w *clauseWalker) EnterReturnSt(ctx *ReturnStContext) {
+ if w.info.ReturnItems != "" {
+ return
+ }
+
+ // ReturnSt has ProjectionBody() containing the return expressions
+ if projBody := ctx.ProjectionBody(); projBody != nil {
+ w.info.ReturnItems = getChildText(projBody)
+ }
+}
+
+// EnterWithSt captures WITH clause - extracts items from ProjectionBody
+func (w *clauseWalker) EnterWithSt(ctx *WithStContext) {
+ // WithSt has ProjectionBody() containing the with expressions
+ if projBody := ctx.ProjectionBody(); projBody != nil {
+ itemsText := getChildText(projBody)
+ w.info.WithItemsList = append(w.info.WithItemsList, itemsText)
+ if w.info.WithItems == "" {
+ w.info.WithItems = itemsText
+ }
+ }
+}
+
+// EnterUnwindSt captures UNWIND clause - extracts expression and variable
+func (w *clauseWalker) EnterUnwindSt(ctx *UnwindStContext) {
+ if w.info.UnwindExpr != "" {
+ return
+ }
+
+ // UnwindSt has Expression() and Symbol() children
+ if expr := ctx.Expression(); expr != nil {
+ w.info.UnwindExpr = getChildText(expr)
+ }
+ if symbol := ctx.Symbol(); symbol != nil {
+ w.info.UnwindAs = getChildText(symbol)
+ }
+}
+
+// EnterOrderSt captures ORDER BY clause - extracts items from OrderItem children
+func (w *clauseWalker) EnterOrderSt(ctx *OrderStContext) {
+ if w.info.OrderByItems != "" {
+ return
+ }
+
+ // OrderSt has AllOrderItem() containing the individual items
+ var items []string
+ for _, item := range ctx.AllOrderItem() {
+ items = append(items, getChildText(item))
+ }
+ w.info.OrderByItems = strings.Join(items, ", ")
+}
+
+// EnterLimitSt captures LIMIT clause - extracts value from Expression
+func (w *clauseWalker) EnterLimitSt(ctx *LimitStContext) {
+ if w.info.LimitValue != "" {
+ return
+ }
+
+ // LimitSt has Expression() containing the limit value
+ if expr := ctx.Expression(); expr != nil {
+ w.info.LimitValue = getChildText(expr)
+ }
+}
+
+// EnterSkipSt captures SKIP clause - extracts value from Expression
+func (w *clauseWalker) EnterSkipSt(ctx *SkipStContext) {
+ if w.info.SkipValue != "" {
+ return
+ }
+
+ // SkipSt has Expression() containing the skip value
+ if expr := ctx.Expression(); expr != nil {
+ w.info.SkipValue = getChildText(expr)
+ }
+}
+
+// EnterStandaloneCall captures CALL procedure - extracts procedure name and args from AST
+func (w *clauseWalker) EnterStandaloneCall(ctx *StandaloneCallContext) {
+ if w.info.CallProcedure != "" {
+ return
+ }
+
+ // Build procedure call from InvocationName and ParenExpressionChain AST nodes
+ var callText string
+ if invName := ctx.InvocationName(); invName != nil {
+ callText = getChildText(invName)
+ }
+ if parenExpr := ctx.ParenExpressionChain(); parenExpr != nil {
+ callText += getChildText(parenExpr)
+ }
+ w.info.CallProcedure = callText
+}
+
+// EnterQueryCallSt captures CALL in query context - extracts from AST
+func (w *clauseWalker) EnterQueryCallSt(ctx *QueryCallStContext) {
+ if w.info.CallProcedure != "" {
+ return
+ }
+
+ // Build procedure call from InvocationName and ParenExpressionChain AST nodes
+ var callText string
+ if invName := ctx.InvocationName(); invName != nil {
+ callText = getChildText(invName)
+ }
+ if parenExpr := ctx.ParenExpressionChain(); parenExpr != nil {
+ callText += getChildText(parenExpr)
+ }
+ w.info.CallProcedure = callText
+}
+
+// EnterSymbol captures variable names
+func (w *clauseWalker) EnterSymbol(ctx *SymbolContext) {
+ varName := strings.TrimSpace(ctx.GetText())
+ if varName != "" {
+ // Deduplicate
+ for _, v := range w.info.Variables {
+ if v == varName {
+ return
+ }
+ }
+ w.info.Variables = append(w.info.Variables, varName)
+ }
+}
diff --git a/nornicdb/pkg/cypher/antlr/cypher_lexer.go b/nornicdb/pkg/cypher/antlr/cypher_lexer.go
new file mode 100644
index 0000000..d038ebf
--- /dev/null
+++ b/nornicdb/pkg/cypher/antlr/cypher_lexer.go
@@ -0,0 +1,765 @@
+// Code generated from CypherLexer.g4 by ANTLR 4.13.2. DO NOT EDIT.
+
+package antlr
+
+import (
+ "fmt"
+ "github.com/antlr4-go/antlr/v4"
+ "sync"
+ "unicode"
+)
+
+// Suppress unused import error
+var _ = fmt.Printf
+var _ = sync.Once{}
+var _ = unicode.IsLetter
+
+type CypherLexer struct {
+ *antlr.BaseLexer
+ channelNames []string
+ modeNames []string
+ // TODO: EOF string
+}
+
+var CypherLexerLexerStaticData struct {
+ once sync.Once
+ serializedATN []int32
+ ChannelNames []string
+ ModeNames []string
+ LiteralNames []string
+ SymbolicNames []string
+ RuleNames []string
+ PredictionContextCache *antlr.PredictionContextCache
+ atn *antlr.ATN
+ decisionToDFA []*antlr.DFA
+}
+
+func cypherlexerLexerInit() {
+ staticData := &CypherLexerLexerStaticData
+ staticData.ChannelNames = []string{
+ "DEFAULT_TOKEN_CHANNEL", "HIDDEN", "COMMENTS",
+ }
+ staticData.ModeNames = []string{
+ "DEFAULT_MODE",
+ }
+ staticData.LiteralNames = []string{
+ "", "'='", "'+='", "'<='", "'>='", "'>'", "'<'", "", "'=~'", "'..'",
+ "';'", "'.'", "','", "'('", "')'", "'{'", "'}'", "'['", "']'", "'-'",
+ "'+'", "'/'", "'%'", "'^'", "'*'", "'`'", "':'", "'|'", "'$'", "'CALL'",
+ "'YIELD'", "'FILTER'", "'EXTRACT'", "'COUNT'", "'SUM'", "'AVG'", "'MIN'",
+ "'MAX'", "'COLLECT'", "'ANY'", "'NONE'", "'SINGLE'", "'ALL'", "'ASC'",
+ "'ASCENDING'", "'BY'", "'CREATE'", "'DELETE'", "'DESC'", "'DESCENDING'",
+ "'DETACH'", "'EXISTS'", "'LIMIT'", "'MATCH'", "'MERGE'", "'ON'", "'OPTIONAL'",
+ "'ORDER'", "'REMOVE'", "'RETURN'", "'SET'", "'SKIP'", "'WHERE'", "'WITH'",
+ "'UNION'", "'UNWIND'", "'AND'", "'AS'", "'CONTAINS'", "'DISTINCT'",
+ "'ENDS'", "'IN'", "'IS'", "'NOT'", "'OR'", "'STARTS'", "'XOR'", "'FALSE'",
+ "'TRUE'", "'NULL'", "'CONSTRAINT'", "'DO'", "'FOR'", "'REQUIRE'", "'UNIQUE'",
+ "'CASE'", "'WHEN'", "'THEN'", "'ELSE'", "'END'", "'MANDATORY'", "'SCALAR'",
+ "'OF'", "'ADD'", "'DROP'", "'INDEX'", "'INDEXES'", "'VECTOR'", "'EXPLAIN'",
+ "'PROFILE'", "'SHOW'", "'CONSTRAINTS'", "'PROCEDURES'", "'FUNCTIONS'",
+ "'DATABASE'", "'DATABASES'", "'FULLTEXT'", "'OPTIONS'", "'EACH'", "'IF'",
+ "'TRANSACTIONS'", "'ROWS'", "'ASSERT'", "'KEY'", "'NODE'", "'shortestPath'",
+ "'allShortestPaths'",
+ }
+ staticData.SymbolicNames = []string{
+ "", "ASSIGN", "ADD_ASSIGN", "LE", "GE", "GT", "LT", "NOT_EQUAL", "REGEX_MATCH",
+ "RANGE", "SEMI", "DOT", "COMMA", "LPAREN", "RPAREN", "LBRACE", "RBRACE",
+ "LBRACK", "RBRACK", "SUB", "PLUS", "DIV", "MOD", "CARET", "MULT", "ESC",
+ "COLON", "STICK", "DOLLAR", "CALL", "YIELD", "FILTER", "EXTRACT", "COUNT",
+ "SUM", "AVG", "MIN", "MAX", "COLLECT", "ANY", "NONE", "SINGLE", "ALL",
+ "ASC", "ASCENDING", "BY", "CREATE", "DELETE", "DESC", "DESCENDING",
+ "DETACH", "EXISTS", "LIMIT", "MATCH", "MERGE", "ON", "OPTIONAL", "ORDER",
+ "REMOVE", "RETURN", "SET", "SKIP_W", "WHERE", "WITH", "UNION", "UNWIND",
+ "AND", "AS", "CONTAINS", "DISTINCT", "ENDS", "IN", "IS", "NOT", "OR",
+ "STARTS", "XOR", "FALSE", "TRUE", "NULL_W", "CONSTRAINT", "DO", "FOR",
+ "REQUIRE", "UNIQUE", "CASE", "WHEN", "THEN", "ELSE", "END", "MANDATORY",
+ "SCALAR", "OF", "ADD", "DROP", "INDEX", "INDEXES", "VECTOR", "EXPLAIN",
+ "PROFILE", "SHOW", "CONSTRAINTS", "PROCEDURES", "FUNCTIONS", "DATABASE",
+ "DATABASES", "FULLTEXT", "OPTIONS", "EACH", "IF", "TRANSACTIONS", "ROWS",
+ "ASSERT", "KEY", "NODE", "SHORTESTPATH", "ALLSHORTESTPATHS", "FLOAT",
+ "INTEGER", "DIGIT", "ID", "ESC_LITERAL", "CHAR_LITERAL", "STRING_LITERAL",
+ "WS", "COMMENT", "LINE_COMMENT", "ERRCHAR", "Letter",
+ }
+ staticData.RuleNames = []string{
+ "ASSIGN", "ADD_ASSIGN", "LE", "GE", "GT", "LT", "NOT_EQUAL", "REGEX_MATCH",
+ "RANGE", "SEMI", "DOT", "COMMA", "LPAREN", "RPAREN", "LBRACE", "RBRACE",
+ "LBRACK", "RBRACK", "SUB", "PLUS", "DIV", "MOD", "CARET", "MULT", "ESC",
+ "COLON", "STICK", "DOLLAR", "CALL", "YIELD", "FILTER", "EXTRACT", "COUNT",
+ "SUM", "AVG", "MIN", "MAX", "COLLECT", "ANY", "NONE", "SINGLE", "ALL",
+ "ASC", "ASCENDING", "BY", "CREATE", "DELETE", "DESC", "DESCENDING",
+ "DETACH", "EXISTS", "LIMIT", "MATCH", "MERGE", "ON", "OPTIONAL", "ORDER",
+ "REMOVE", "RETURN", "SET", "SKIP_W", "WHERE", "WITH", "UNION", "UNWIND",
+ "AND", "AS", "CONTAINS", "DISTINCT", "ENDS", "IN", "IS", "NOT", "OR",
+ "STARTS", "XOR", "FALSE", "TRUE", "NULL_W", "CONSTRAINT", "DO", "FOR",
+ "REQUIRE", "UNIQUE", "CASE", "WHEN", "THEN", "ELSE", "END", "MANDATORY",
+ "SCALAR", "OF", "ADD", "DROP", "INDEX", "INDEXES", "VECTOR", "EXPLAIN",
+ "PROFILE", "SHOW", "CONSTRAINTS", "PROCEDURES", "FUNCTIONS", "DATABASE",
+ "DATABASES", "FULLTEXT", "OPTIONS", "EACH", "IF", "TRANSACTIONS", "ROWS",
+ "ASSERT", "KEY", "NODE", "SHORTESTPATH", "ALLSHORTESTPATHS", "FLOAT",
+ "INTEGER", "DIGIT", "ID", "ESC_LITERAL", "CHAR_LITERAL", "STRING_LITERAL",
+ "WS", "COMMENT", "LINE_COMMENT", "ERRCHAR", "EscapeSequence", "ExponentPart",
+ "HexInteger", "HexDigit", "OctalInteger", "DecimalInteger", "LetterOrDigit",
+ "Letter",
+ }
+ staticData.PredictionContextCache = antlr.NewPredictionContextCache()
+ staticData.serializedATN = []int32{
+ 4, 0, 128, 1084, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3,
+ 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9,
+ 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2,
+ 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20,
+ 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7,
+ 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30,
+ 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2,
+ 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41,
+ 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7,
+ 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51,
+ 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2,
+ 57, 7, 57, 2, 58, 7, 58, 2, 59, 7, 59, 2, 60, 7, 60, 2, 61, 7, 61, 2, 62,
+ 7, 62, 2, 63, 7, 63, 2, 64, 7, 64, 2, 65, 7, 65, 2, 66, 7, 66, 2, 67, 7,
+ 67, 2, 68, 7, 68, 2, 69, 7, 69, 2, 70, 7, 70, 2, 71, 7, 71, 2, 72, 7, 72,
+ 2, 73, 7, 73, 2, 74, 7, 74, 2, 75, 7, 75, 2, 76, 7, 76, 2, 77, 7, 77, 2,
+ 78, 7, 78, 2, 79, 7, 79, 2, 80, 7, 80, 2, 81, 7, 81, 2, 82, 7, 82, 2, 83,
+ 7, 83, 2, 84, 7, 84, 2, 85, 7, 85, 2, 86, 7, 86, 2, 87, 7, 87, 2, 88, 7,
+ 88, 2, 89, 7, 89, 2, 90, 7, 90, 2, 91, 7, 91, 2, 92, 7, 92, 2, 93, 7, 93,
+ 2, 94, 7, 94, 2, 95, 7, 95, 2, 96, 7, 96, 2, 97, 7, 97, 2, 98, 7, 98, 2,
+ 99, 7, 99, 2, 100, 7, 100, 2, 101, 7, 101, 2, 102, 7, 102, 2, 103, 7, 103,
+ 2, 104, 7, 104, 2, 105, 7, 105, 2, 106, 7, 106, 2, 107, 7, 107, 2, 108,
+ 7, 108, 2, 109, 7, 109, 2, 110, 7, 110, 2, 111, 7, 111, 2, 112, 7, 112,
+ 2, 113, 7, 113, 2, 114, 7, 114, 2, 115, 7, 115, 2, 116, 7, 116, 2, 117,
+ 7, 117, 2, 118, 7, 118, 2, 119, 7, 119, 2, 120, 7, 120, 2, 121, 7, 121,
+ 2, 122, 7, 122, 2, 123, 7, 123, 2, 124, 7, 124, 2, 125, 7, 125, 2, 126,
+ 7, 126, 2, 127, 7, 127, 2, 128, 7, 128, 2, 129, 7, 129, 2, 130, 7, 130,
+ 2, 131, 7, 131, 2, 132, 7, 132, 2, 133, 7, 133, 2, 134, 7, 134, 1, 0, 1,
+ 0, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 4, 1, 4, 1,
+ 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 6, 3, 6, 291, 8, 6, 1, 7, 1, 7, 1, 7, 1,
+ 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 10, 1, 10, 1, 11, 1, 11, 1, 12, 1, 12, 1,
+ 13, 1, 13, 1, 14, 1, 14, 1, 15, 1, 15, 1, 16, 1, 16, 1, 17, 1, 17, 1, 18,
+ 1, 18, 1, 19, 1, 19, 1, 20, 1, 20, 1, 21, 1, 21, 1, 22, 1, 22, 1, 23, 1,
+ 23, 1, 24, 1, 24, 1, 25, 1, 25, 1, 26, 1, 26, 1, 27, 1, 27, 1, 28, 1, 28,
+ 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 30, 1,
+ 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31,
+ 1, 31, 1, 31, 1, 31, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 33, 1,
+ 33, 1, 33, 1, 33, 1, 34, 1, 34, 1, 34, 1, 34, 1, 35, 1, 35, 1, 35, 1, 35,
+ 1, 36, 1, 36, 1, 36, 1, 36, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1,
+ 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 38, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39,
+ 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 41, 1, 41, 1, 41, 1,
+ 41, 1, 42, 1, 42, 1, 42, 1, 42, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43,
+ 1, 43, 1, 43, 1, 43, 1, 43, 1, 44, 1, 44, 1, 44, 1, 45, 1, 45, 1, 45, 1,
+ 45, 1, 45, 1, 45, 1, 45, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46,
+ 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1,
+ 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49,
+ 1, 49, 1, 49, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 51, 1,
+ 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52,
+ 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 54, 1, 54, 1, 54, 1, 55, 1,
+ 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 56, 1, 56, 1, 56,
+ 1, 56, 1, 56, 1, 56, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1,
+ 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 59, 1, 59, 1, 59, 1, 59,
+ 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1,
+ 61, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63,
+ 1, 63, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 65, 1, 65, 1,
+ 65, 1, 65, 1, 66, 1, 66, 1, 66, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67,
+ 1, 67, 1, 67, 1, 67, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1,
+ 68, 1, 68, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 70, 1, 70, 1, 70, 1, 71,
+ 1, 71, 1, 71, 1, 72, 1, 72, 1, 72, 1, 72, 1, 73, 1, 73, 1, 73, 1, 74, 1,
+ 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 75, 1, 75, 1, 75, 1, 75, 1, 76,
+ 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 77, 1, 77, 1, 77, 1, 77, 1, 77, 1,
+ 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79,
+ 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 80, 1, 80, 1, 80, 1, 81, 1, 81, 1,
+ 81, 1, 81, 1, 82, 1, 82, 1, 82, 1, 82, 1, 82, 1, 82, 1, 82, 1, 82, 1, 83,
+ 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 84, 1, 84, 1, 84, 1, 84, 1,
+ 84, 1, 85, 1, 85, 1, 85, 1, 85, 1, 85, 1, 86, 1, 86, 1, 86, 1, 86, 1, 86,
+ 1, 87, 1, 87, 1, 87, 1, 87, 1, 87, 1, 88, 1, 88, 1, 88, 1, 88, 1, 89, 1,
+ 89, 1, 89, 1, 89, 1, 89, 1, 89, 1, 89, 1, 89, 1, 89, 1, 89, 1, 90, 1, 90,
+ 1, 90, 1, 90, 1, 90, 1, 90, 1, 90, 1, 91, 1, 91, 1, 91, 1, 92, 1, 92, 1,
+ 92, 1, 92, 1, 93, 1, 93, 1, 93, 1, 93, 1, 93, 1, 94, 1, 94, 1, 94, 1, 94,
+ 1, 94, 1, 94, 1, 95, 1, 95, 1, 95, 1, 95, 1, 95, 1, 95, 1, 95, 1, 95, 1,
+ 96, 1, 96, 1, 96, 1, 96, 1, 96, 1, 96, 1, 96, 1, 97, 1, 97, 1, 97, 1, 97,
+ 1, 97, 1, 97, 1, 97, 1, 97, 1, 98, 1, 98, 1, 98, 1, 98, 1, 98, 1, 98, 1,
+ 98, 1, 98, 1, 99, 1, 99, 1, 99, 1, 99, 1, 99, 1, 100, 1, 100, 1, 100, 1,
+ 100, 1, 100, 1, 100, 1, 100, 1, 100, 1, 100, 1, 100, 1, 100, 1, 100, 1,
+ 101, 1, 101, 1, 101, 1, 101, 1, 101, 1, 101, 1, 101, 1, 101, 1, 101, 1,
+ 101, 1, 101, 1, 102, 1, 102, 1, 102, 1, 102, 1, 102, 1, 102, 1, 102, 1,
+ 102, 1, 102, 1, 102, 1, 103, 1, 103, 1, 103, 1, 103, 1, 103, 1, 103, 1,
+ 103, 1, 103, 1, 103, 1, 104, 1, 104, 1, 104, 1, 104, 1, 104, 1, 104, 1,
+ 104, 1, 104, 1, 104, 1, 104, 1, 105, 1, 105, 1, 105, 1, 105, 1, 105, 1,
+ 105, 1, 105, 1, 105, 1, 105, 1, 106, 1, 106, 1, 106, 1, 106, 1, 106, 1,
+ 106, 1, 106, 1, 106, 1, 107, 1, 107, 1, 107, 1, 107, 1, 107, 1, 108, 1,
+ 108, 1, 108, 1, 109, 1, 109, 1, 109, 1, 109, 1, 109, 1, 109, 1, 109, 1,
+ 109, 1, 109, 1, 109, 1, 109, 1, 109, 1, 109, 1, 110, 1, 110, 1, 110, 1,
+ 110, 1, 110, 1, 111, 1, 111, 1, 111, 1, 111, 1, 111, 1, 111, 1, 111, 1,
+ 112, 1, 112, 1, 112, 1, 112, 1, 113, 1, 113, 1, 113, 1, 113, 1, 113, 1,
+ 114, 1, 114, 1, 114, 1, 114, 1, 114, 1, 114, 1, 114, 1, 114, 1, 114, 1,
+ 114, 1, 114, 1, 114, 1, 114, 1, 115, 1, 115, 1, 115, 1, 115, 1, 115, 1,
+ 115, 1, 115, 1, 115, 1, 115, 1, 115, 1, 115, 1, 115, 1, 115, 1, 115, 1,
+ 115, 1, 115, 1, 115, 1, 116, 3, 116, 897, 8, 116, 1, 116, 4, 116, 900,
+ 8, 116, 11, 116, 12, 116, 901, 1, 116, 1, 116, 4, 116, 906, 8, 116, 11,
+ 116, 12, 116, 907, 1, 116, 1, 116, 4, 116, 912, 8, 116, 11, 116, 12, 116,
+ 913, 3, 116, 916, 8, 116, 1, 116, 3, 116, 919, 8, 116, 1, 116, 3, 116,
+ 922, 8, 116, 1, 116, 4, 116, 925, 8, 116, 11, 116, 12, 116, 926, 1, 116,
+ 1, 116, 3, 116, 931, 8, 116, 1, 116, 3, 116, 934, 8, 116, 3, 116, 936,
+ 8, 116, 1, 117, 3, 117, 939, 8, 117, 1, 117, 1, 117, 1, 118, 1, 118, 1,
+ 118, 3, 118, 946, 8, 118, 1, 119, 1, 119, 5, 119, 950, 8, 119, 10, 119,
+ 12, 119, 953, 9, 119, 1, 120, 1, 120, 5, 120, 957, 8, 120, 10, 120, 12,
+ 120, 960, 9, 120, 1, 120, 1, 120, 1, 121, 1, 121, 1, 121, 5, 121, 967,
+ 8, 121, 10, 121, 12, 121, 970, 9, 121, 1, 121, 1, 121, 1, 122, 1, 122,
+ 1, 122, 5, 122, 977, 8, 122, 10, 122, 12, 122, 980, 9, 122, 1, 122, 1,
+ 122, 1, 123, 4, 123, 985, 8, 123, 11, 123, 12, 123, 986, 1, 123, 1, 123,
+ 1, 124, 1, 124, 1, 124, 1, 124, 5, 124, 995, 8, 124, 10, 124, 12, 124,
+ 998, 9, 124, 1, 124, 1, 124, 1, 124, 1, 124, 1, 124, 1, 125, 1, 125, 1,
+ 125, 1, 125, 5, 125, 1009, 8, 125, 10, 125, 12, 125, 1012, 9, 125, 1, 125,
+ 1, 125, 1, 126, 1, 126, 1, 127, 1, 127, 1, 127, 1, 127, 3, 127, 1022, 8,
+ 127, 1, 127, 3, 127, 1025, 8, 127, 1, 127, 1, 127, 1, 127, 4, 127, 1030,
+ 8, 127, 11, 127, 12, 127, 1031, 1, 127, 1, 127, 1, 127, 1, 127, 1, 127,
+ 3, 127, 1039, 8, 127, 1, 128, 1, 128, 3, 128, 1043, 8, 128, 1, 128, 1,
+ 128, 1, 129, 1, 129, 1, 129, 4, 129, 1050, 8, 129, 11, 129, 12, 129, 1051,
+ 1, 130, 1, 130, 1, 131, 1, 131, 3, 131, 1058, 8, 131, 1, 131, 4, 131, 1061,
+ 8, 131, 11, 131, 12, 131, 1062, 1, 132, 1, 132, 1, 132, 5, 132, 1068, 8,
+ 132, 10, 132, 12, 132, 1071, 9, 132, 3, 132, 1073, 8, 132, 1, 133, 1, 133,
+ 3, 133, 1077, 8, 133, 1, 134, 1, 134, 1, 134, 1, 134, 3, 134, 1083, 8,
+ 134, 2, 958, 996, 0, 135, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15,
+ 8, 17, 9, 19, 10, 21, 11, 23, 12, 25, 13, 27, 14, 29, 15, 31, 16, 33, 17,
+ 35, 18, 37, 19, 39, 20, 41, 21, 43, 22, 45, 23, 47, 24, 49, 25, 51, 26,
+ 53, 27, 55, 28, 57, 29, 59, 30, 61, 31, 63, 32, 65, 33, 67, 34, 69, 35,
+ 71, 36, 73, 37, 75, 38, 77, 39, 79, 40, 81, 41, 83, 42, 85, 43, 87, 44,
+ 89, 45, 91, 46, 93, 47, 95, 48, 97, 49, 99, 50, 101, 51, 103, 52, 105,
+ 53, 107, 54, 109, 55, 111, 56, 113, 57, 115, 58, 117, 59, 119, 60, 121,
+ 61, 123, 62, 125, 63, 127, 64, 129, 65, 131, 66, 133, 67, 135, 68, 137,
+ 69, 139, 70, 141, 71, 143, 72, 145, 73, 147, 74, 149, 75, 151, 76, 153,
+ 77, 155, 78, 157, 79, 159, 80, 161, 81, 163, 82, 165, 83, 167, 84, 169,
+ 85, 171, 86, 173, 87, 175, 88, 177, 89, 179, 90, 181, 91, 183, 92, 185,
+ 93, 187, 94, 189, 95, 191, 96, 193, 97, 195, 98, 197, 99, 199, 100, 201,
+ 101, 203, 102, 205, 103, 207, 104, 209, 105, 211, 106, 213, 107, 215, 108,
+ 217, 109, 219, 110, 221, 111, 223, 112, 225, 113, 227, 114, 229, 115, 231,
+ 116, 233, 117, 235, 118, 237, 119, 239, 120, 241, 121, 243, 122, 245, 123,
+ 247, 124, 249, 125, 251, 126, 253, 127, 255, 0, 257, 0, 259, 0, 261, 0,
+ 263, 0, 265, 0, 267, 0, 269, 128, 1, 0, 40, 2, 0, 67, 67, 99, 99, 2, 0,
+ 65, 65, 97, 97, 2, 0, 76, 76, 108, 108, 2, 0, 89, 89, 121, 121, 2, 0, 73,
+ 73, 105, 105, 2, 0, 69, 69, 101, 101, 2, 0, 68, 68, 100, 100, 2, 0, 70,
+ 70, 102, 102, 2, 0, 84, 84, 116, 116, 2, 0, 82, 82, 114, 114, 2, 0, 88,
+ 88, 120, 120, 2, 0, 79, 79, 111, 111, 2, 0, 85, 85, 117, 117, 2, 0, 78,
+ 78, 110, 110, 2, 0, 83, 83, 115, 115, 2, 0, 77, 77, 109, 109, 2, 0, 86,
+ 86, 118, 118, 2, 0, 71, 71, 103, 103, 2, 0, 66, 66, 98, 98, 2, 0, 72, 72,
+ 104, 104, 2, 0, 80, 80, 112, 112, 2, 0, 75, 75, 107, 107, 2, 0, 87, 87,
+ 119, 119, 2, 0, 81, 81, 113, 113, 1, 0, 48, 57, 4, 0, 68, 68, 70, 70, 100,
+ 100, 102, 102, 4, 0, 10, 10, 13, 13, 39, 39, 92, 92, 4, 0, 10, 10, 13,
+ 13, 34, 34, 92, 92, 3, 0, 9, 10, 12, 13, 32, 32, 2, 0, 10, 10, 13, 13,
+ 14, 0, 34, 34, 39, 39, 46, 47, 66, 66, 70, 70, 78, 78, 82, 82, 84, 85,
+ 92, 92, 98, 98, 102, 102, 110, 110, 114, 114, 116, 117, 1, 0, 48, 51, 1,
+ 0, 48, 55, 2, 0, 43, 43, 45, 45, 3, 0, 48, 57, 65, 70, 97, 102, 1, 0, 49,
+ 57, 3, 0, 65, 90, 95, 95, 97, 122, 2, 0, 0, 127, 55296, 56319, 1, 0, 55296,
+ 56319, 1, 0, 56320, 57343, 1114, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0,
+ 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0,
+ 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0,
+ 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0,
+ 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0,
+ 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 43, 1,
+ 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 51,
+ 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0, 0, 57, 1, 0, 0, 0, 0,
+ 59, 1, 0, 0, 0, 0, 61, 1, 0, 0, 0, 0, 63, 1, 0, 0, 0, 0, 65, 1, 0, 0, 0,
+ 0, 67, 1, 0, 0, 0, 0, 69, 1, 0, 0, 0, 0, 71, 1, 0, 0, 0, 0, 73, 1, 0, 0,
+ 0, 0, 75, 1, 0, 0, 0, 0, 77, 1, 0, 0, 0, 0, 79, 1, 0, 0, 0, 0, 81, 1, 0,
+ 0, 0, 0, 83, 1, 0, 0, 0, 0, 85, 1, 0, 0, 0, 0, 87, 1, 0, 0, 0, 0, 89, 1,
+ 0, 0, 0, 0, 91, 1, 0, 0, 0, 0, 93, 1, 0, 0, 0, 0, 95, 1, 0, 0, 0, 0, 97,
+ 1, 0, 0, 0, 0, 99, 1, 0, 0, 0, 0, 101, 1, 0, 0, 0, 0, 103, 1, 0, 0, 0,
+ 0, 105, 1, 0, 0, 0, 0, 107, 1, 0, 0, 0, 0, 109, 1, 0, 0, 0, 0, 111, 1,
+ 0, 0, 0, 0, 113, 1, 0, 0, 0, 0, 115, 1, 0, 0, 0, 0, 117, 1, 0, 0, 0, 0,
+ 119, 1, 0, 0, 0, 0, 121, 1, 0, 0, 0, 0, 123, 1, 0, 0, 0, 0, 125, 1, 0,
+ 0, 0, 0, 127, 1, 0, 0, 0, 0, 129, 1, 0, 0, 0, 0, 131, 1, 0, 0, 0, 0, 133,
+ 1, 0, 0, 0, 0, 135, 1, 0, 0, 0, 0, 137, 1, 0, 0, 0, 0, 139, 1, 0, 0, 0,
+ 0, 141, 1, 0, 0, 0, 0, 143, 1, 0, 0, 0, 0, 145, 1, 0, 0, 0, 0, 147, 1,
+ 0, 0, 0, 0, 149, 1, 0, 0, 0, 0, 151, 1, 0, 0, 0, 0, 153, 1, 0, 0, 0, 0,
+ 155, 1, 0, 0, 0, 0, 157, 1, 0, 0, 0, 0, 159, 1, 0, 0, 0, 0, 161, 1, 0,
+ 0, 0, 0, 163, 1, 0, 0, 0, 0, 165, 1, 0, 0, 0, 0, 167, 1, 0, 0, 0, 0, 169,
+ 1, 0, 0, 0, 0, 171, 1, 0, 0, 0, 0, 173, 1, 0, 0, 0, 0, 175, 1, 0, 0, 0,
+ 0, 177, 1, 0, 0, 0, 0, 179, 1, 0, 0, 0, 0, 181, 1, 0, 0, 0, 0, 183, 1,
+ 0, 0, 0, 0, 185, 1, 0, 0, 0, 0, 187, 1, 0, 0, 0, 0, 189, 1, 0, 0, 0, 0,
+ 191, 1, 0, 0, 0, 0, 193, 1, 0, 0, 0, 0, 195, 1, 0, 0, 0, 0, 197, 1, 0,
+ 0, 0, 0, 199, 1, 0, 0, 0, 0, 201, 1, 0, 0, 0, 0, 203, 1, 0, 0, 0, 0, 205,
+ 1, 0, 0, 0, 0, 207, 1, 0, 0, 0, 0, 209, 1, 0, 0, 0, 0, 211, 1, 0, 0, 0,
+ 0, 213, 1, 0, 0, 0, 0, 215, 1, 0, 0, 0, 0, 217, 1, 0, 0, 0, 0, 219, 1,
+ 0, 0, 0, 0, 221, 1, 0, 0, 0, 0, 223, 1, 0, 0, 0, 0, 225, 1, 0, 0, 0, 0,
+ 227, 1, 0, 0, 0, 0, 229, 1, 0, 0, 0, 0, 231, 1, 0, 0, 0, 0, 233, 1, 0,
+ 0, 0, 0, 235, 1, 0, 0, 0, 0, 237, 1, 0, 0, 0, 0, 239, 1, 0, 0, 0, 0, 241,
+ 1, 0, 0, 0, 0, 243, 1, 0, 0, 0, 0, 245, 1, 0, 0, 0, 0, 247, 1, 0, 0, 0,
+ 0, 249, 1, 0, 0, 0, 0, 251, 1, 0, 0, 0, 0, 253, 1, 0, 0, 0, 0, 269, 1,
+ 0, 0, 0, 1, 271, 1, 0, 0, 0, 3, 273, 1, 0, 0, 0, 5, 276, 1, 0, 0, 0, 7,
+ 279, 1, 0, 0, 0, 9, 282, 1, 0, 0, 0, 11, 284, 1, 0, 0, 0, 13, 290, 1, 0,
+ 0, 0, 15, 292, 1, 0, 0, 0, 17, 295, 1, 0, 0, 0, 19, 298, 1, 0, 0, 0, 21,
+ 300, 1, 0, 0, 0, 23, 302, 1, 0, 0, 0, 25, 304, 1, 0, 0, 0, 27, 306, 1,
+ 0, 0, 0, 29, 308, 1, 0, 0, 0, 31, 310, 1, 0, 0, 0, 33, 312, 1, 0, 0, 0,
+ 35, 314, 1, 0, 0, 0, 37, 316, 1, 0, 0, 0, 39, 318, 1, 0, 0, 0, 41, 320,
+ 1, 0, 0, 0, 43, 322, 1, 0, 0, 0, 45, 324, 1, 0, 0, 0, 47, 326, 1, 0, 0,
+ 0, 49, 328, 1, 0, 0, 0, 51, 330, 1, 0, 0, 0, 53, 332, 1, 0, 0, 0, 55, 334,
+ 1, 0, 0, 0, 57, 336, 1, 0, 0, 0, 59, 341, 1, 0, 0, 0, 61, 347, 1, 0, 0,
+ 0, 63, 354, 1, 0, 0, 0, 65, 362, 1, 0, 0, 0, 67, 368, 1, 0, 0, 0, 69, 372,
+ 1, 0, 0, 0, 71, 376, 1, 0, 0, 0, 73, 380, 1, 0, 0, 0, 75, 384, 1, 0, 0,
+ 0, 77, 392, 1, 0, 0, 0, 79, 396, 1, 0, 0, 0, 81, 401, 1, 0, 0, 0, 83, 408,
+ 1, 0, 0, 0, 85, 412, 1, 0, 0, 0, 87, 416, 1, 0, 0, 0, 89, 426, 1, 0, 0,
+ 0, 91, 429, 1, 0, 0, 0, 93, 436, 1, 0, 0, 0, 95, 443, 1, 0, 0, 0, 97, 448,
+ 1, 0, 0, 0, 99, 459, 1, 0, 0, 0, 101, 466, 1, 0, 0, 0, 103, 473, 1, 0,
+ 0, 0, 105, 479, 1, 0, 0, 0, 107, 485, 1, 0, 0, 0, 109, 491, 1, 0, 0, 0,
+ 111, 494, 1, 0, 0, 0, 113, 503, 1, 0, 0, 0, 115, 509, 1, 0, 0, 0, 117,
+ 516, 1, 0, 0, 0, 119, 523, 1, 0, 0, 0, 121, 527, 1, 0, 0, 0, 123, 532,
+ 1, 0, 0, 0, 125, 538, 1, 0, 0, 0, 127, 543, 1, 0, 0, 0, 129, 549, 1, 0,
+ 0, 0, 131, 556, 1, 0, 0, 0, 133, 560, 1, 0, 0, 0, 135, 563, 1, 0, 0, 0,
+ 137, 572, 1, 0, 0, 0, 139, 581, 1, 0, 0, 0, 141, 586, 1, 0, 0, 0, 143,
+ 589, 1, 0, 0, 0, 145, 592, 1, 0, 0, 0, 147, 596, 1, 0, 0, 0, 149, 599,
+ 1, 0, 0, 0, 151, 606, 1, 0, 0, 0, 153, 610, 1, 0, 0, 0, 155, 616, 1, 0,
+ 0, 0, 157, 621, 1, 0, 0, 0, 159, 626, 1, 0, 0, 0, 161, 637, 1, 0, 0, 0,
+ 163, 640, 1, 0, 0, 0, 165, 644, 1, 0, 0, 0, 167, 652, 1, 0, 0, 0, 169,
+ 659, 1, 0, 0, 0, 171, 664, 1, 0, 0, 0, 173, 669, 1, 0, 0, 0, 175, 674,
+ 1, 0, 0, 0, 177, 679, 1, 0, 0, 0, 179, 683, 1, 0, 0, 0, 181, 693, 1, 0,
+ 0, 0, 183, 700, 1, 0, 0, 0, 185, 703, 1, 0, 0, 0, 187, 707, 1, 0, 0, 0,
+ 189, 712, 1, 0, 0, 0, 191, 718, 1, 0, 0, 0, 193, 726, 1, 0, 0, 0, 195,
+ 733, 1, 0, 0, 0, 197, 741, 1, 0, 0, 0, 199, 749, 1, 0, 0, 0, 201, 754,
+ 1, 0, 0, 0, 203, 766, 1, 0, 0, 0, 205, 777, 1, 0, 0, 0, 207, 787, 1, 0,
+ 0, 0, 209, 796, 1, 0, 0, 0, 211, 806, 1, 0, 0, 0, 213, 815, 1, 0, 0, 0,
+ 215, 823, 1, 0, 0, 0, 217, 828, 1, 0, 0, 0, 219, 831, 1, 0, 0, 0, 221,
+ 844, 1, 0, 0, 0, 223, 849, 1, 0, 0, 0, 225, 856, 1, 0, 0, 0, 227, 860,
+ 1, 0, 0, 0, 229, 865, 1, 0, 0, 0, 231, 878, 1, 0, 0, 0, 233, 896, 1, 0,
+ 0, 0, 235, 938, 1, 0, 0, 0, 237, 945, 1, 0, 0, 0, 239, 947, 1, 0, 0, 0,
+ 241, 954, 1, 0, 0, 0, 243, 963, 1, 0, 0, 0, 245, 973, 1, 0, 0, 0, 247,
+ 984, 1, 0, 0, 0, 249, 990, 1, 0, 0, 0, 251, 1004, 1, 0, 0, 0, 253, 1015,
+ 1, 0, 0, 0, 255, 1038, 1, 0, 0, 0, 257, 1040, 1, 0, 0, 0, 259, 1046, 1,
+ 0, 0, 0, 261, 1053, 1, 0, 0, 0, 263, 1055, 1, 0, 0, 0, 265, 1072, 1, 0,
+ 0, 0, 267, 1076, 1, 0, 0, 0, 269, 1082, 1, 0, 0, 0, 271, 272, 5, 61, 0,
+ 0, 272, 2, 1, 0, 0, 0, 273, 274, 5, 43, 0, 0, 274, 275, 5, 61, 0, 0, 275,
+ 4, 1, 0, 0, 0, 276, 277, 5, 60, 0, 0, 277, 278, 5, 61, 0, 0, 278, 6, 1,
+ 0, 0, 0, 279, 280, 5, 62, 0, 0, 280, 281, 5, 61, 0, 0, 281, 8, 1, 0, 0,
+ 0, 282, 283, 5, 62, 0, 0, 283, 10, 1, 0, 0, 0, 284, 285, 5, 60, 0, 0, 285,
+ 12, 1, 0, 0, 0, 286, 287, 5, 60, 0, 0, 287, 291, 5, 62, 0, 0, 288, 289,
+ 5, 33, 0, 0, 289, 291, 5, 61, 0, 0, 290, 286, 1, 0, 0, 0, 290, 288, 1,
+ 0, 0, 0, 291, 14, 1, 0, 0, 0, 292, 293, 5, 61, 0, 0, 293, 294, 5, 126,
+ 0, 0, 294, 16, 1, 0, 0, 0, 295, 296, 5, 46, 0, 0, 296, 297, 5, 46, 0, 0,
+ 297, 18, 1, 0, 0, 0, 298, 299, 5, 59, 0, 0, 299, 20, 1, 0, 0, 0, 300, 301,
+ 5, 46, 0, 0, 301, 22, 1, 0, 0, 0, 302, 303, 5, 44, 0, 0, 303, 24, 1, 0,
+ 0, 0, 304, 305, 5, 40, 0, 0, 305, 26, 1, 0, 0, 0, 306, 307, 5, 41, 0, 0,
+ 307, 28, 1, 0, 0, 0, 308, 309, 5, 123, 0, 0, 309, 30, 1, 0, 0, 0, 310,
+ 311, 5, 125, 0, 0, 311, 32, 1, 0, 0, 0, 312, 313, 5, 91, 0, 0, 313, 34,
+ 1, 0, 0, 0, 314, 315, 5, 93, 0, 0, 315, 36, 1, 0, 0, 0, 316, 317, 5, 45,
+ 0, 0, 317, 38, 1, 0, 0, 0, 318, 319, 5, 43, 0, 0, 319, 40, 1, 0, 0, 0,
+ 320, 321, 5, 47, 0, 0, 321, 42, 1, 0, 0, 0, 322, 323, 5, 37, 0, 0, 323,
+ 44, 1, 0, 0, 0, 324, 325, 5, 94, 0, 0, 325, 46, 1, 0, 0, 0, 326, 327, 5,
+ 42, 0, 0, 327, 48, 1, 0, 0, 0, 328, 329, 5, 96, 0, 0, 329, 50, 1, 0, 0,
+ 0, 330, 331, 5, 58, 0, 0, 331, 52, 1, 0, 0, 0, 332, 333, 5, 124, 0, 0,
+ 333, 54, 1, 0, 0, 0, 334, 335, 5, 36, 0, 0, 335, 56, 1, 0, 0, 0, 336, 337,
+ 7, 0, 0, 0, 337, 338, 7, 1, 0, 0, 338, 339, 7, 2, 0, 0, 339, 340, 7, 2,
+ 0, 0, 340, 58, 1, 0, 0, 0, 341, 342, 7, 3, 0, 0, 342, 343, 7, 4, 0, 0,
+ 343, 344, 7, 5, 0, 0, 344, 345, 7, 2, 0, 0, 345, 346, 7, 6, 0, 0, 346,
+ 60, 1, 0, 0, 0, 347, 348, 7, 7, 0, 0, 348, 349, 7, 4, 0, 0, 349, 350, 7,
+ 2, 0, 0, 350, 351, 7, 8, 0, 0, 351, 352, 7, 5, 0, 0, 352, 353, 7, 9, 0,
+ 0, 353, 62, 1, 0, 0, 0, 354, 355, 7, 5, 0, 0, 355, 356, 7, 10, 0, 0, 356,
+ 357, 7, 8, 0, 0, 357, 358, 7, 9, 0, 0, 358, 359, 7, 1, 0, 0, 359, 360,
+ 7, 0, 0, 0, 360, 361, 7, 8, 0, 0, 361, 64, 1, 0, 0, 0, 362, 363, 7, 0,
+ 0, 0, 363, 364, 7, 11, 0, 0, 364, 365, 7, 12, 0, 0, 365, 366, 7, 13, 0,
+ 0, 366, 367, 7, 8, 0, 0, 367, 66, 1, 0, 0, 0, 368, 369, 7, 14, 0, 0, 369,
+ 370, 7, 12, 0, 0, 370, 371, 7, 15, 0, 0, 371, 68, 1, 0, 0, 0, 372, 373,
+ 7, 1, 0, 0, 373, 374, 7, 16, 0, 0, 374, 375, 7, 17, 0, 0, 375, 70, 1, 0,
+ 0, 0, 376, 377, 7, 15, 0, 0, 377, 378, 7, 4, 0, 0, 378, 379, 7, 13, 0,
+ 0, 379, 72, 1, 0, 0, 0, 380, 381, 7, 15, 0, 0, 381, 382, 7, 1, 0, 0, 382,
+ 383, 7, 10, 0, 0, 383, 74, 1, 0, 0, 0, 384, 385, 7, 0, 0, 0, 385, 386,
+ 7, 11, 0, 0, 386, 387, 7, 2, 0, 0, 387, 388, 7, 2, 0, 0, 388, 389, 7, 5,
+ 0, 0, 389, 390, 7, 0, 0, 0, 390, 391, 7, 8, 0, 0, 391, 76, 1, 0, 0, 0,
+ 392, 393, 7, 1, 0, 0, 393, 394, 7, 13, 0, 0, 394, 395, 7, 3, 0, 0, 395,
+ 78, 1, 0, 0, 0, 396, 397, 7, 13, 0, 0, 397, 398, 7, 11, 0, 0, 398, 399,
+ 7, 13, 0, 0, 399, 400, 7, 5, 0, 0, 400, 80, 1, 0, 0, 0, 401, 402, 7, 14,
+ 0, 0, 402, 403, 7, 4, 0, 0, 403, 404, 7, 13, 0, 0, 404, 405, 7, 17, 0,
+ 0, 405, 406, 7, 2, 0, 0, 406, 407, 7, 5, 0, 0, 407, 82, 1, 0, 0, 0, 408,
+ 409, 7, 1, 0, 0, 409, 410, 7, 2, 0, 0, 410, 411, 7, 2, 0, 0, 411, 84, 1,
+ 0, 0, 0, 412, 413, 7, 1, 0, 0, 413, 414, 7, 14, 0, 0, 414, 415, 7, 0, 0,
+ 0, 415, 86, 1, 0, 0, 0, 416, 417, 7, 1, 0, 0, 417, 418, 7, 14, 0, 0, 418,
+ 419, 7, 0, 0, 0, 419, 420, 7, 5, 0, 0, 420, 421, 7, 13, 0, 0, 421, 422,
+ 7, 6, 0, 0, 422, 423, 7, 4, 0, 0, 423, 424, 7, 13, 0, 0, 424, 425, 7, 17,
+ 0, 0, 425, 88, 1, 0, 0, 0, 426, 427, 7, 18, 0, 0, 427, 428, 7, 3, 0, 0,
+ 428, 90, 1, 0, 0, 0, 429, 430, 7, 0, 0, 0, 430, 431, 7, 9, 0, 0, 431, 432,
+ 7, 5, 0, 0, 432, 433, 7, 1, 0, 0, 433, 434, 7, 8, 0, 0, 434, 435, 7, 5,
+ 0, 0, 435, 92, 1, 0, 0, 0, 436, 437, 7, 6, 0, 0, 437, 438, 7, 5, 0, 0,
+ 438, 439, 7, 2, 0, 0, 439, 440, 7, 5, 0, 0, 440, 441, 7, 8, 0, 0, 441,
+ 442, 7, 5, 0, 0, 442, 94, 1, 0, 0, 0, 443, 444, 7, 6, 0, 0, 444, 445, 7,
+ 5, 0, 0, 445, 446, 7, 14, 0, 0, 446, 447, 7, 0, 0, 0, 447, 96, 1, 0, 0,
+ 0, 448, 449, 7, 6, 0, 0, 449, 450, 7, 5, 0, 0, 450, 451, 7, 14, 0, 0, 451,
+ 452, 7, 0, 0, 0, 452, 453, 7, 5, 0, 0, 453, 454, 7, 13, 0, 0, 454, 455,
+ 7, 6, 0, 0, 455, 456, 7, 4, 0, 0, 456, 457, 7, 13, 0, 0, 457, 458, 7, 17,
+ 0, 0, 458, 98, 1, 0, 0, 0, 459, 460, 7, 6, 0, 0, 460, 461, 7, 5, 0, 0,
+ 461, 462, 7, 8, 0, 0, 462, 463, 7, 1, 0, 0, 463, 464, 7, 0, 0, 0, 464,
+ 465, 7, 19, 0, 0, 465, 100, 1, 0, 0, 0, 466, 467, 7, 5, 0, 0, 467, 468,
+ 7, 10, 0, 0, 468, 469, 7, 4, 0, 0, 469, 470, 7, 14, 0, 0, 470, 471, 7,
+ 8, 0, 0, 471, 472, 7, 14, 0, 0, 472, 102, 1, 0, 0, 0, 473, 474, 7, 2, 0,
+ 0, 474, 475, 7, 4, 0, 0, 475, 476, 7, 15, 0, 0, 476, 477, 7, 4, 0, 0, 477,
+ 478, 7, 8, 0, 0, 478, 104, 1, 0, 0, 0, 479, 480, 7, 15, 0, 0, 480, 481,
+ 7, 1, 0, 0, 481, 482, 7, 8, 0, 0, 482, 483, 7, 0, 0, 0, 483, 484, 7, 19,
+ 0, 0, 484, 106, 1, 0, 0, 0, 485, 486, 7, 15, 0, 0, 486, 487, 7, 5, 0, 0,
+ 487, 488, 7, 9, 0, 0, 488, 489, 7, 17, 0, 0, 489, 490, 7, 5, 0, 0, 490,
+ 108, 1, 0, 0, 0, 491, 492, 7, 11, 0, 0, 492, 493, 7, 13, 0, 0, 493, 110,
+ 1, 0, 0, 0, 494, 495, 7, 11, 0, 0, 495, 496, 7, 20, 0, 0, 496, 497, 7,
+ 8, 0, 0, 497, 498, 7, 4, 0, 0, 498, 499, 7, 11, 0, 0, 499, 500, 7, 13,
+ 0, 0, 500, 501, 7, 1, 0, 0, 501, 502, 7, 2, 0, 0, 502, 112, 1, 0, 0, 0,
+ 503, 504, 7, 11, 0, 0, 504, 505, 7, 9, 0, 0, 505, 506, 7, 6, 0, 0, 506,
+ 507, 7, 5, 0, 0, 507, 508, 7, 9, 0, 0, 508, 114, 1, 0, 0, 0, 509, 510,
+ 7, 9, 0, 0, 510, 511, 7, 5, 0, 0, 511, 512, 7, 15, 0, 0, 512, 513, 7, 11,
+ 0, 0, 513, 514, 7, 16, 0, 0, 514, 515, 7, 5, 0, 0, 515, 116, 1, 0, 0, 0,
+ 516, 517, 7, 9, 0, 0, 517, 518, 7, 5, 0, 0, 518, 519, 7, 8, 0, 0, 519,
+ 520, 7, 12, 0, 0, 520, 521, 7, 9, 0, 0, 521, 522, 7, 13, 0, 0, 522, 118,
+ 1, 0, 0, 0, 523, 524, 7, 14, 0, 0, 524, 525, 7, 5, 0, 0, 525, 526, 7, 8,
+ 0, 0, 526, 120, 1, 0, 0, 0, 527, 528, 7, 14, 0, 0, 528, 529, 7, 21, 0,
+ 0, 529, 530, 7, 4, 0, 0, 530, 531, 7, 20, 0, 0, 531, 122, 1, 0, 0, 0, 532,
+ 533, 7, 22, 0, 0, 533, 534, 7, 19, 0, 0, 534, 535, 7, 5, 0, 0, 535, 536,
+ 7, 9, 0, 0, 536, 537, 7, 5, 0, 0, 537, 124, 1, 0, 0, 0, 538, 539, 7, 22,
+ 0, 0, 539, 540, 7, 4, 0, 0, 540, 541, 7, 8, 0, 0, 541, 542, 7, 19, 0, 0,
+ 542, 126, 1, 0, 0, 0, 543, 544, 7, 12, 0, 0, 544, 545, 7, 13, 0, 0, 545,
+ 546, 7, 4, 0, 0, 546, 547, 7, 11, 0, 0, 547, 548, 7, 13, 0, 0, 548, 128,
+ 1, 0, 0, 0, 549, 550, 7, 12, 0, 0, 550, 551, 7, 13, 0, 0, 551, 552, 7,
+ 22, 0, 0, 552, 553, 7, 4, 0, 0, 553, 554, 7, 13, 0, 0, 554, 555, 7, 6,
+ 0, 0, 555, 130, 1, 0, 0, 0, 556, 557, 7, 1, 0, 0, 557, 558, 7, 13, 0, 0,
+ 558, 559, 7, 6, 0, 0, 559, 132, 1, 0, 0, 0, 560, 561, 7, 1, 0, 0, 561,
+ 562, 7, 14, 0, 0, 562, 134, 1, 0, 0, 0, 563, 564, 7, 0, 0, 0, 564, 565,
+ 7, 11, 0, 0, 565, 566, 7, 13, 0, 0, 566, 567, 7, 8, 0, 0, 567, 568, 7,
+ 1, 0, 0, 568, 569, 7, 4, 0, 0, 569, 570, 7, 13, 0, 0, 570, 571, 7, 14,
+ 0, 0, 571, 136, 1, 0, 0, 0, 572, 573, 7, 6, 0, 0, 573, 574, 7, 4, 0, 0,
+ 574, 575, 7, 14, 0, 0, 575, 576, 7, 8, 0, 0, 576, 577, 7, 4, 0, 0, 577,
+ 578, 7, 13, 0, 0, 578, 579, 7, 0, 0, 0, 579, 580, 7, 8, 0, 0, 580, 138,
+ 1, 0, 0, 0, 581, 582, 7, 5, 0, 0, 582, 583, 7, 13, 0, 0, 583, 584, 7, 6,
+ 0, 0, 584, 585, 7, 14, 0, 0, 585, 140, 1, 0, 0, 0, 586, 587, 7, 4, 0, 0,
+ 587, 588, 7, 13, 0, 0, 588, 142, 1, 0, 0, 0, 589, 590, 7, 4, 0, 0, 590,
+ 591, 7, 14, 0, 0, 591, 144, 1, 0, 0, 0, 592, 593, 7, 13, 0, 0, 593, 594,
+ 7, 11, 0, 0, 594, 595, 7, 8, 0, 0, 595, 146, 1, 0, 0, 0, 596, 597, 7, 11,
+ 0, 0, 597, 598, 7, 9, 0, 0, 598, 148, 1, 0, 0, 0, 599, 600, 7, 14, 0, 0,
+ 600, 601, 7, 8, 0, 0, 601, 602, 7, 1, 0, 0, 602, 603, 7, 9, 0, 0, 603,
+ 604, 7, 8, 0, 0, 604, 605, 7, 14, 0, 0, 605, 150, 1, 0, 0, 0, 606, 607,
+ 7, 10, 0, 0, 607, 608, 7, 11, 0, 0, 608, 609, 7, 9, 0, 0, 609, 152, 1,
+ 0, 0, 0, 610, 611, 7, 7, 0, 0, 611, 612, 7, 1, 0, 0, 612, 613, 7, 2, 0,
+ 0, 613, 614, 7, 14, 0, 0, 614, 615, 7, 5, 0, 0, 615, 154, 1, 0, 0, 0, 616,
+ 617, 7, 8, 0, 0, 617, 618, 7, 9, 0, 0, 618, 619, 7, 12, 0, 0, 619, 620,
+ 7, 5, 0, 0, 620, 156, 1, 0, 0, 0, 621, 622, 7, 13, 0, 0, 622, 623, 7, 12,
+ 0, 0, 623, 624, 7, 2, 0, 0, 624, 625, 7, 2, 0, 0, 625, 158, 1, 0, 0, 0,
+ 626, 627, 7, 0, 0, 0, 627, 628, 7, 11, 0, 0, 628, 629, 7, 13, 0, 0, 629,
+ 630, 7, 14, 0, 0, 630, 631, 7, 8, 0, 0, 631, 632, 7, 9, 0, 0, 632, 633,
+ 7, 1, 0, 0, 633, 634, 7, 4, 0, 0, 634, 635, 7, 13, 0, 0, 635, 636, 7, 8,
+ 0, 0, 636, 160, 1, 0, 0, 0, 637, 638, 7, 6, 0, 0, 638, 639, 7, 11, 0, 0,
+ 639, 162, 1, 0, 0, 0, 640, 641, 7, 7, 0, 0, 641, 642, 7, 11, 0, 0, 642,
+ 643, 7, 9, 0, 0, 643, 164, 1, 0, 0, 0, 644, 645, 7, 9, 0, 0, 645, 646,
+ 7, 5, 0, 0, 646, 647, 7, 23, 0, 0, 647, 648, 7, 12, 0, 0, 648, 649, 7,
+ 4, 0, 0, 649, 650, 7, 9, 0, 0, 650, 651, 7, 5, 0, 0, 651, 166, 1, 0, 0,
+ 0, 652, 653, 7, 12, 0, 0, 653, 654, 7, 13, 0, 0, 654, 655, 7, 4, 0, 0,
+ 655, 656, 7, 23, 0, 0, 656, 657, 7, 12, 0, 0, 657, 658, 7, 5, 0, 0, 658,
+ 168, 1, 0, 0, 0, 659, 660, 7, 0, 0, 0, 660, 661, 7, 1, 0, 0, 661, 662,
+ 7, 14, 0, 0, 662, 663, 7, 5, 0, 0, 663, 170, 1, 0, 0, 0, 664, 665, 7, 22,
+ 0, 0, 665, 666, 7, 19, 0, 0, 666, 667, 7, 5, 0, 0, 667, 668, 7, 13, 0,
+ 0, 668, 172, 1, 0, 0, 0, 669, 670, 7, 8, 0, 0, 670, 671, 7, 19, 0, 0, 671,
+ 672, 7, 5, 0, 0, 672, 673, 7, 13, 0, 0, 673, 174, 1, 0, 0, 0, 674, 675,
+ 7, 5, 0, 0, 675, 676, 7, 2, 0, 0, 676, 677, 7, 14, 0, 0, 677, 678, 7, 5,
+ 0, 0, 678, 176, 1, 0, 0, 0, 679, 680, 7, 5, 0, 0, 680, 681, 7, 13, 0, 0,
+ 681, 682, 7, 6, 0, 0, 682, 178, 1, 0, 0, 0, 683, 684, 7, 15, 0, 0, 684,
+ 685, 7, 1, 0, 0, 685, 686, 7, 13, 0, 0, 686, 687, 7, 6, 0, 0, 687, 688,
+ 7, 1, 0, 0, 688, 689, 7, 8, 0, 0, 689, 690, 7, 11, 0, 0, 690, 691, 7, 9,
+ 0, 0, 691, 692, 7, 3, 0, 0, 692, 180, 1, 0, 0, 0, 693, 694, 7, 14, 0, 0,
+ 694, 695, 7, 0, 0, 0, 695, 696, 7, 1, 0, 0, 696, 697, 7, 2, 0, 0, 697,
+ 698, 7, 1, 0, 0, 698, 699, 7, 9, 0, 0, 699, 182, 1, 0, 0, 0, 700, 701,
+ 7, 11, 0, 0, 701, 702, 7, 7, 0, 0, 702, 184, 1, 0, 0, 0, 703, 704, 7, 1,
+ 0, 0, 704, 705, 7, 6, 0, 0, 705, 706, 7, 6, 0, 0, 706, 186, 1, 0, 0, 0,
+ 707, 708, 7, 6, 0, 0, 708, 709, 7, 9, 0, 0, 709, 710, 7, 11, 0, 0, 710,
+ 711, 7, 20, 0, 0, 711, 188, 1, 0, 0, 0, 712, 713, 7, 4, 0, 0, 713, 714,
+ 7, 13, 0, 0, 714, 715, 7, 6, 0, 0, 715, 716, 7, 5, 0, 0, 716, 717, 7, 10,
+ 0, 0, 717, 190, 1, 0, 0, 0, 718, 719, 7, 4, 0, 0, 719, 720, 7, 13, 0, 0,
+ 720, 721, 7, 6, 0, 0, 721, 722, 7, 5, 0, 0, 722, 723, 7, 10, 0, 0, 723,
+ 724, 7, 5, 0, 0, 724, 725, 7, 14, 0, 0, 725, 192, 1, 0, 0, 0, 726, 727,
+ 7, 16, 0, 0, 727, 728, 7, 5, 0, 0, 728, 729, 7, 0, 0, 0, 729, 730, 7, 8,
+ 0, 0, 730, 731, 7, 11, 0, 0, 731, 732, 7, 9, 0, 0, 732, 194, 1, 0, 0, 0,
+ 733, 734, 7, 5, 0, 0, 734, 735, 7, 10, 0, 0, 735, 736, 7, 20, 0, 0, 736,
+ 737, 7, 2, 0, 0, 737, 738, 7, 1, 0, 0, 738, 739, 7, 4, 0, 0, 739, 740,
+ 7, 13, 0, 0, 740, 196, 1, 0, 0, 0, 741, 742, 7, 20, 0, 0, 742, 743, 7,
+ 9, 0, 0, 743, 744, 7, 11, 0, 0, 744, 745, 7, 7, 0, 0, 745, 746, 7, 4, 0,
+ 0, 746, 747, 7, 2, 0, 0, 747, 748, 7, 5, 0, 0, 748, 198, 1, 0, 0, 0, 749,
+ 750, 7, 14, 0, 0, 750, 751, 7, 19, 0, 0, 751, 752, 7, 11, 0, 0, 752, 753,
+ 7, 22, 0, 0, 753, 200, 1, 0, 0, 0, 754, 755, 7, 0, 0, 0, 755, 756, 7, 11,
+ 0, 0, 756, 757, 7, 13, 0, 0, 757, 758, 7, 14, 0, 0, 758, 759, 7, 8, 0,
+ 0, 759, 760, 7, 9, 0, 0, 760, 761, 7, 1, 0, 0, 761, 762, 7, 4, 0, 0, 762,
+ 763, 7, 13, 0, 0, 763, 764, 7, 8, 0, 0, 764, 765, 7, 14, 0, 0, 765, 202,
+ 1, 0, 0, 0, 766, 767, 7, 20, 0, 0, 767, 768, 7, 9, 0, 0, 768, 769, 7, 11,
+ 0, 0, 769, 770, 7, 0, 0, 0, 770, 771, 7, 5, 0, 0, 771, 772, 7, 6, 0, 0,
+ 772, 773, 7, 12, 0, 0, 773, 774, 7, 9, 0, 0, 774, 775, 7, 5, 0, 0, 775,
+ 776, 7, 14, 0, 0, 776, 204, 1, 0, 0, 0, 777, 778, 7, 7, 0, 0, 778, 779,
+ 7, 12, 0, 0, 779, 780, 7, 13, 0, 0, 780, 781, 7, 0, 0, 0, 781, 782, 7,
+ 8, 0, 0, 782, 783, 7, 4, 0, 0, 783, 784, 7, 11, 0, 0, 784, 785, 7, 13,
+ 0, 0, 785, 786, 7, 14, 0, 0, 786, 206, 1, 0, 0, 0, 787, 788, 7, 6, 0, 0,
+ 788, 789, 7, 1, 0, 0, 789, 790, 7, 8, 0, 0, 790, 791, 7, 1, 0, 0, 791,
+ 792, 7, 18, 0, 0, 792, 793, 7, 1, 0, 0, 793, 794, 7, 14, 0, 0, 794, 795,
+ 7, 5, 0, 0, 795, 208, 1, 0, 0, 0, 796, 797, 7, 6, 0, 0, 797, 798, 7, 1,
+ 0, 0, 798, 799, 7, 8, 0, 0, 799, 800, 7, 1, 0, 0, 800, 801, 7, 18, 0, 0,
+ 801, 802, 7, 1, 0, 0, 802, 803, 7, 14, 0, 0, 803, 804, 7, 5, 0, 0, 804,
+ 805, 7, 14, 0, 0, 805, 210, 1, 0, 0, 0, 806, 807, 7, 7, 0, 0, 807, 808,
+ 7, 12, 0, 0, 808, 809, 7, 2, 0, 0, 809, 810, 7, 2, 0, 0, 810, 811, 7, 8,
+ 0, 0, 811, 812, 7, 5, 0, 0, 812, 813, 7, 10, 0, 0, 813, 814, 7, 8, 0, 0,
+ 814, 212, 1, 0, 0, 0, 815, 816, 7, 11, 0, 0, 816, 817, 7, 20, 0, 0, 817,
+ 818, 7, 8, 0, 0, 818, 819, 7, 4, 0, 0, 819, 820, 7, 11, 0, 0, 820, 821,
+ 7, 13, 0, 0, 821, 822, 7, 14, 0, 0, 822, 214, 1, 0, 0, 0, 823, 824, 7,
+ 5, 0, 0, 824, 825, 7, 1, 0, 0, 825, 826, 7, 0, 0, 0, 826, 827, 7, 19, 0,
+ 0, 827, 216, 1, 0, 0, 0, 828, 829, 7, 4, 0, 0, 829, 830, 7, 7, 0, 0, 830,
+ 218, 1, 0, 0, 0, 831, 832, 7, 8, 0, 0, 832, 833, 7, 9, 0, 0, 833, 834,
+ 7, 1, 0, 0, 834, 835, 7, 13, 0, 0, 835, 836, 7, 14, 0, 0, 836, 837, 7,
+ 1, 0, 0, 837, 838, 7, 0, 0, 0, 838, 839, 7, 8, 0, 0, 839, 840, 7, 4, 0,
+ 0, 840, 841, 7, 11, 0, 0, 841, 842, 7, 13, 0, 0, 842, 843, 7, 14, 0, 0,
+ 843, 220, 1, 0, 0, 0, 844, 845, 7, 9, 0, 0, 845, 846, 7, 11, 0, 0, 846,
+ 847, 7, 22, 0, 0, 847, 848, 7, 14, 0, 0, 848, 222, 1, 0, 0, 0, 849, 850,
+ 7, 1, 0, 0, 850, 851, 7, 14, 0, 0, 851, 852, 7, 14, 0, 0, 852, 853, 7,
+ 5, 0, 0, 853, 854, 7, 9, 0, 0, 854, 855, 7, 8, 0, 0, 855, 224, 1, 0, 0,
+ 0, 856, 857, 7, 21, 0, 0, 857, 858, 7, 5, 0, 0, 858, 859, 7, 3, 0, 0, 859,
+ 226, 1, 0, 0, 0, 860, 861, 7, 13, 0, 0, 861, 862, 7, 11, 0, 0, 862, 863,
+ 7, 6, 0, 0, 863, 864, 7, 5, 0, 0, 864, 228, 1, 0, 0, 0, 865, 866, 7, 14,
+ 0, 0, 866, 867, 7, 19, 0, 0, 867, 868, 7, 11, 0, 0, 868, 869, 7, 9, 0,
+ 0, 869, 870, 7, 8, 0, 0, 870, 871, 7, 5, 0, 0, 871, 872, 7, 14, 0, 0, 872,
+ 873, 7, 8, 0, 0, 873, 874, 7, 20, 0, 0, 874, 875, 7, 1, 0, 0, 875, 876,
+ 7, 8, 0, 0, 876, 877, 7, 19, 0, 0, 877, 230, 1, 0, 0, 0, 878, 879, 7, 1,
+ 0, 0, 879, 880, 7, 2, 0, 0, 880, 881, 7, 2, 0, 0, 881, 882, 7, 14, 0, 0,
+ 882, 883, 7, 19, 0, 0, 883, 884, 7, 11, 0, 0, 884, 885, 7, 9, 0, 0, 885,
+ 886, 7, 8, 0, 0, 886, 887, 7, 5, 0, 0, 887, 888, 7, 14, 0, 0, 888, 889,
+ 7, 8, 0, 0, 889, 890, 7, 20, 0, 0, 890, 891, 7, 1, 0, 0, 891, 892, 7, 8,
+ 0, 0, 892, 893, 7, 19, 0, 0, 893, 894, 7, 14, 0, 0, 894, 232, 1, 0, 0,
+ 0, 895, 897, 3, 37, 18, 0, 896, 895, 1, 0, 0, 0, 896, 897, 1, 0, 0, 0,
+ 897, 935, 1, 0, 0, 0, 898, 900, 7, 24, 0, 0, 899, 898, 1, 0, 0, 0, 900,
+ 901, 1, 0, 0, 0, 901, 899, 1, 0, 0, 0, 901, 902, 1, 0, 0, 0, 902, 903,
+ 1, 0, 0, 0, 903, 905, 5, 46, 0, 0, 904, 906, 7, 24, 0, 0, 905, 904, 1,
+ 0, 0, 0, 906, 907, 1, 0, 0, 0, 907, 905, 1, 0, 0, 0, 907, 908, 1, 0, 0,
+ 0, 908, 916, 1, 0, 0, 0, 909, 911, 5, 46, 0, 0, 910, 912, 7, 24, 0, 0,
+ 911, 910, 1, 0, 0, 0, 912, 913, 1, 0, 0, 0, 913, 911, 1, 0, 0, 0, 913,
+ 914, 1, 0, 0, 0, 914, 916, 1, 0, 0, 0, 915, 899, 1, 0, 0, 0, 915, 909,
+ 1, 0, 0, 0, 916, 918, 1, 0, 0, 0, 917, 919, 3, 257, 128, 0, 918, 917, 1,
+ 0, 0, 0, 918, 919, 1, 0, 0, 0, 919, 921, 1, 0, 0, 0, 920, 922, 7, 25, 0,
+ 0, 921, 920, 1, 0, 0, 0, 921, 922, 1, 0, 0, 0, 922, 936, 1, 0, 0, 0, 923,
+ 925, 7, 24, 0, 0, 924, 923, 1, 0, 0, 0, 925, 926, 1, 0, 0, 0, 926, 924,
+ 1, 0, 0, 0, 926, 927, 1, 0, 0, 0, 927, 933, 1, 0, 0, 0, 928, 930, 3, 257,
+ 128, 0, 929, 931, 7, 25, 0, 0, 930, 929, 1, 0, 0, 0, 930, 931, 1, 0, 0,
+ 0, 931, 934, 1, 0, 0, 0, 932, 934, 7, 25, 0, 0, 933, 928, 1, 0, 0, 0, 933,
+ 932, 1, 0, 0, 0, 934, 936, 1, 0, 0, 0, 935, 915, 1, 0, 0, 0, 935, 924,
+ 1, 0, 0, 0, 936, 234, 1, 0, 0, 0, 937, 939, 3, 37, 18, 0, 938, 937, 1,
+ 0, 0, 0, 938, 939, 1, 0, 0, 0, 939, 940, 1, 0, 0, 0, 940, 941, 3, 265,
+ 132, 0, 941, 236, 1, 0, 0, 0, 942, 946, 3, 259, 129, 0, 943, 946, 3, 263,
+ 131, 0, 944, 946, 7, 24, 0, 0, 945, 942, 1, 0, 0, 0, 945, 943, 1, 0, 0,
+ 0, 945, 944, 1, 0, 0, 0, 946, 238, 1, 0, 0, 0, 947, 951, 3, 269, 134, 0,
+ 948, 950, 3, 267, 133, 0, 949, 948, 1, 0, 0, 0, 950, 953, 1, 0, 0, 0, 951,
+ 949, 1, 0, 0, 0, 951, 952, 1, 0, 0, 0, 952, 240, 1, 0, 0, 0, 953, 951,
+ 1, 0, 0, 0, 954, 958, 5, 96, 0, 0, 955, 957, 9, 0, 0, 0, 956, 955, 1, 0,
+ 0, 0, 957, 960, 1, 0, 0, 0, 958, 959, 1, 0, 0, 0, 958, 956, 1, 0, 0, 0,
+ 959, 961, 1, 0, 0, 0, 960, 958, 1, 0, 0, 0, 961, 962, 5, 96, 0, 0, 962,
+ 242, 1, 0, 0, 0, 963, 968, 5, 39, 0, 0, 964, 967, 8, 26, 0, 0, 965, 967,
+ 3, 255, 127, 0, 966, 964, 1, 0, 0, 0, 966, 965, 1, 0, 0, 0, 967, 970, 1,
+ 0, 0, 0, 968, 966, 1, 0, 0, 0, 968, 969, 1, 0, 0, 0, 969, 971, 1, 0, 0,
+ 0, 970, 968, 1, 0, 0, 0, 971, 972, 5, 39, 0, 0, 972, 244, 1, 0, 0, 0, 973,
+ 978, 5, 34, 0, 0, 974, 977, 8, 27, 0, 0, 975, 977, 3, 255, 127, 0, 976,
+ 974, 1, 0, 0, 0, 976, 975, 1, 0, 0, 0, 977, 980, 1, 0, 0, 0, 978, 976,
+ 1, 0, 0, 0, 978, 979, 1, 0, 0, 0, 979, 981, 1, 0, 0, 0, 980, 978, 1, 0,
+ 0, 0, 981, 982, 5, 34, 0, 0, 982, 246, 1, 0, 0, 0, 983, 985, 7, 28, 0,
+ 0, 984, 983, 1, 0, 0, 0, 985, 986, 1, 0, 0, 0, 986, 984, 1, 0, 0, 0, 986,
+ 987, 1, 0, 0, 0, 987, 988, 1, 0, 0, 0, 988, 989, 6, 123, 0, 0, 989, 248,
+ 1, 0, 0, 0, 990, 991, 5, 47, 0, 0, 991, 992, 5, 42, 0, 0, 992, 996, 1,
+ 0, 0, 0, 993, 995, 9, 0, 0, 0, 994, 993, 1, 0, 0, 0, 995, 998, 1, 0, 0,
+ 0, 996, 997, 1, 0, 0, 0, 996, 994, 1, 0, 0, 0, 997, 999, 1, 0, 0, 0, 998,
+ 996, 1, 0, 0, 0, 999, 1000, 5, 42, 0, 0, 1000, 1001, 5, 47, 0, 0, 1001,
+ 1002, 1, 0, 0, 0, 1002, 1003, 6, 124, 1, 0, 1003, 250, 1, 0, 0, 0, 1004,
+ 1005, 5, 47, 0, 0, 1005, 1006, 5, 47, 0, 0, 1006, 1010, 1, 0, 0, 0, 1007,
+ 1009, 8, 29, 0, 0, 1008, 1007, 1, 0, 0, 0, 1009, 1012, 1, 0, 0, 0, 1010,
+ 1008, 1, 0, 0, 0, 1010, 1011, 1, 0, 0, 0, 1011, 1013, 1, 0, 0, 0, 1012,
+ 1010, 1, 0, 0, 0, 1013, 1014, 6, 125, 1, 0, 1014, 252, 1, 0, 0, 0, 1015,
+ 1016, 9, 0, 0, 0, 1016, 254, 1, 0, 0, 0, 1017, 1018, 5, 92, 0, 0, 1018,
+ 1039, 7, 30, 0, 0, 1019, 1024, 5, 92, 0, 0, 1020, 1022, 7, 31, 0, 0, 1021,
+ 1020, 1, 0, 0, 0, 1021, 1022, 1, 0, 0, 0, 1022, 1023, 1, 0, 0, 0, 1023,
+ 1025, 7, 32, 0, 0, 1024, 1021, 1, 0, 0, 0, 1024, 1025, 1, 0, 0, 0, 1025,
+ 1026, 1, 0, 0, 0, 1026, 1039, 7, 32, 0, 0, 1027, 1029, 5, 92, 0, 0, 1028,
+ 1030, 7, 12, 0, 0, 1029, 1028, 1, 0, 0, 0, 1030, 1031, 1, 0, 0, 0, 1031,
+ 1029, 1, 0, 0, 0, 1031, 1032, 1, 0, 0, 0, 1032, 1033, 1, 0, 0, 0, 1033,
+ 1034, 3, 261, 130, 0, 1034, 1035, 3, 261, 130, 0, 1035, 1036, 3, 261, 130,
+ 0, 1036, 1037, 3, 261, 130, 0, 1037, 1039, 1, 0, 0, 0, 1038, 1017, 1, 0,
+ 0, 0, 1038, 1019, 1, 0, 0, 0, 1038, 1027, 1, 0, 0, 0, 1039, 256, 1, 0,
+ 0, 0, 1040, 1042, 7, 5, 0, 0, 1041, 1043, 7, 33, 0, 0, 1042, 1041, 1, 0,
+ 0, 0, 1042, 1043, 1, 0, 0, 0, 1043, 1044, 1, 0, 0, 0, 1044, 1045, 3, 265,
+ 132, 0, 1045, 258, 1, 0, 0, 0, 1046, 1047, 5, 48, 0, 0, 1047, 1049, 7,
+ 10, 0, 0, 1048, 1050, 3, 261, 130, 0, 1049, 1048, 1, 0, 0, 0, 1050, 1051,
+ 1, 0, 0, 0, 1051, 1049, 1, 0, 0, 0, 1051, 1052, 1, 0, 0, 0, 1052, 260,
+ 1, 0, 0, 0, 1053, 1054, 7, 34, 0, 0, 1054, 262, 1, 0, 0, 0, 1055, 1057,
+ 5, 48, 0, 0, 1056, 1058, 7, 11, 0, 0, 1057, 1056, 1, 0, 0, 0, 1057, 1058,
+ 1, 0, 0, 0, 1058, 1060, 1, 0, 0, 0, 1059, 1061, 7, 32, 0, 0, 1060, 1059,
+ 1, 0, 0, 0, 1061, 1062, 1, 0, 0, 0, 1062, 1060, 1, 0, 0, 0, 1062, 1063,
+ 1, 0, 0, 0, 1063, 264, 1, 0, 0, 0, 1064, 1073, 5, 48, 0, 0, 1065, 1069,
+ 7, 35, 0, 0, 1066, 1068, 7, 24, 0, 0, 1067, 1066, 1, 0, 0, 0, 1068, 1071,
+ 1, 0, 0, 0, 1069, 1067, 1, 0, 0, 0, 1069, 1070, 1, 0, 0, 0, 1070, 1073,
+ 1, 0, 0, 0, 1071, 1069, 1, 0, 0, 0, 1072, 1064, 1, 0, 0, 0, 1072, 1065,
+ 1, 0, 0, 0, 1073, 266, 1, 0, 0, 0, 1074, 1077, 3, 269, 134, 0, 1075, 1077,
+ 7, 24, 0, 0, 1076, 1074, 1, 0, 0, 0, 1076, 1075, 1, 0, 0, 0, 1077, 268,
+ 1, 0, 0, 0, 1078, 1083, 7, 36, 0, 0, 1079, 1083, 8, 37, 0, 0, 1080, 1081,
+ 7, 38, 0, 0, 1081, 1083, 7, 39, 0, 0, 1082, 1078, 1, 0, 0, 0, 1082, 1079,
+ 1, 0, 0, 0, 1082, 1080, 1, 0, 0, 0, 1083, 270, 1, 0, 0, 0, 36, 0, 290,
+ 896, 901, 907, 913, 915, 918, 921, 926, 930, 933, 935, 938, 945, 951, 958,
+ 966, 968, 976, 978, 986, 996, 1010, 1021, 1024, 1031, 1038, 1042, 1051,
+ 1057, 1062, 1069, 1072, 1076, 1082, 2, 0, 1, 0, 0, 2, 0,
+ }
+ deserializer := antlr.NewATNDeserializer(nil)
+ staticData.atn = deserializer.Deserialize(staticData.serializedATN)
+ atn := staticData.atn
+ staticData.decisionToDFA = make([]*antlr.DFA, len(atn.DecisionToState))
+ decisionToDFA := staticData.decisionToDFA
+ for index, state := range atn.DecisionToState {
+ decisionToDFA[index] = antlr.NewDFA(state, index)
+ }
+}
+
+// CypherLexerInit initializes any static state used to implement CypherLexer. By default the
+// static state used to implement the lexer is lazily initialized during the first call to
+// NewCypherLexer(). You can call this function if you wish to initialize the static state ahead
+// of time.
+func CypherLexerInit() {
+ staticData := &CypherLexerLexerStaticData
+ staticData.once.Do(cypherlexerLexerInit)
+}
+
+// NewCypherLexer produces a new lexer instance for the optional input antlr.CharStream.
+func NewCypherLexer(input antlr.CharStream) *CypherLexer {
+ CypherLexerInit()
+ l := new(CypherLexer)
+ l.BaseLexer = antlr.NewBaseLexer(input)
+ staticData := &CypherLexerLexerStaticData
+ l.Interpreter = antlr.NewLexerATNSimulator(l, staticData.atn, staticData.decisionToDFA, staticData.PredictionContextCache)
+ l.channelNames = staticData.ChannelNames
+ l.modeNames = staticData.ModeNames
+ l.RuleNames = staticData.RuleNames
+ l.LiteralNames = staticData.LiteralNames
+ l.SymbolicNames = staticData.SymbolicNames
+ l.GrammarFileName = "CypherLexer.g4"
+ // TODO: l.EOF = antlr.TokenEOF
+
+ return l
+}
+
+// CypherLexer tokens.
+const (
+ CypherLexerASSIGN = 1
+ CypherLexerADD_ASSIGN = 2
+ CypherLexerLE = 3
+ CypherLexerGE = 4
+ CypherLexerGT = 5
+ CypherLexerLT = 6
+ CypherLexerNOT_EQUAL = 7
+ CypherLexerREGEX_MATCH = 8
+ CypherLexerRANGE = 9
+ CypherLexerSEMI = 10
+ CypherLexerDOT = 11
+ CypherLexerCOMMA = 12
+ CypherLexerLPAREN = 13
+ CypherLexerRPAREN = 14
+ CypherLexerLBRACE = 15
+ CypherLexerRBRACE = 16
+ CypherLexerLBRACK = 17
+ CypherLexerRBRACK = 18
+ CypherLexerSUB = 19
+ CypherLexerPLUS = 20
+ CypherLexerDIV = 21
+ CypherLexerMOD = 22
+ CypherLexerCARET = 23
+ CypherLexerMULT = 24
+ CypherLexerESC = 25
+ CypherLexerCOLON = 26
+ CypherLexerSTICK = 27
+ CypherLexerDOLLAR = 28
+ CypherLexerCALL = 29
+ CypherLexerYIELD = 30
+ CypherLexerFILTER = 31
+ CypherLexerEXTRACT = 32
+ CypherLexerCOUNT = 33
+ CypherLexerSUM = 34
+ CypherLexerAVG = 35
+ CypherLexerMIN = 36
+ CypherLexerMAX = 37
+ CypherLexerCOLLECT = 38
+ CypherLexerANY = 39
+ CypherLexerNONE = 40
+ CypherLexerSINGLE = 41
+ CypherLexerALL = 42
+ CypherLexerASC = 43
+ CypherLexerASCENDING = 44
+ CypherLexerBY = 45
+ CypherLexerCREATE = 46
+ CypherLexerDELETE = 47
+ CypherLexerDESC = 48
+ CypherLexerDESCENDING = 49
+ CypherLexerDETACH = 50
+ CypherLexerEXISTS = 51
+ CypherLexerLIMIT = 52
+ CypherLexerMATCH = 53
+ CypherLexerMERGE = 54
+ CypherLexerON = 55
+ CypherLexerOPTIONAL = 56
+ CypherLexerORDER = 57
+ CypherLexerREMOVE = 58
+ CypherLexerRETURN = 59
+ CypherLexerSET = 60
+ CypherLexerSKIP_W = 61
+ CypherLexerWHERE = 62
+ CypherLexerWITH = 63
+ CypherLexerUNION = 64
+ CypherLexerUNWIND = 65
+ CypherLexerAND = 66
+ CypherLexerAS = 67
+ CypherLexerCONTAINS = 68
+ CypherLexerDISTINCT = 69
+ CypherLexerENDS = 70
+ CypherLexerIN = 71
+ CypherLexerIS = 72
+ CypherLexerNOT = 73
+ CypherLexerOR = 74
+ CypherLexerSTARTS = 75
+ CypherLexerXOR = 76
+ CypherLexerFALSE = 77
+ CypherLexerTRUE = 78
+ CypherLexerNULL_W = 79
+ CypherLexerCONSTRAINT = 80
+ CypherLexerDO = 81
+ CypherLexerFOR = 82
+ CypherLexerREQUIRE = 83
+ CypherLexerUNIQUE = 84
+ CypherLexerCASE = 85
+ CypherLexerWHEN = 86
+ CypherLexerTHEN = 87
+ CypherLexerELSE = 88
+ CypherLexerEND = 89
+ CypherLexerMANDATORY = 90
+ CypherLexerSCALAR = 91
+ CypherLexerOF = 92
+ CypherLexerADD = 93
+ CypherLexerDROP = 94
+ CypherLexerINDEX = 95
+ CypherLexerINDEXES = 96
+ CypherLexerVECTOR = 97
+ CypherLexerEXPLAIN = 98
+ CypherLexerPROFILE = 99
+ CypherLexerSHOW = 100
+ CypherLexerCONSTRAINTS = 101
+ CypherLexerPROCEDURES = 102
+ CypherLexerFUNCTIONS = 103
+ CypherLexerDATABASE = 104
+ CypherLexerDATABASES = 105
+ CypherLexerFULLTEXT = 106
+ CypherLexerOPTIONS = 107
+ CypherLexerEACH = 108
+ CypherLexerIF = 109
+ CypherLexerTRANSACTIONS = 110
+ CypherLexerROWS = 111
+ CypherLexerASSERT = 112
+ CypherLexerKEY = 113
+ CypherLexerNODE = 114
+ CypherLexerSHORTESTPATH = 115
+ CypherLexerALLSHORTESTPATHS = 116
+ CypherLexerFLOAT = 117
+ CypherLexerINTEGER = 118
+ CypherLexerDIGIT = 119
+ CypherLexerID = 120
+ CypherLexerESC_LITERAL = 121
+ CypherLexerCHAR_LITERAL = 122
+ CypherLexerSTRING_LITERAL = 123
+ CypherLexerWS = 124
+ CypherLexerCOMMENT = 125
+ CypherLexerLINE_COMMENT = 126
+ CypherLexerERRCHAR = 127
+ CypherLexerLetter = 128
+)
+
+// CypherLexerCOMMENTS is the CypherLexer channel.
+const CypherLexerCOMMENTS = 2
diff --git a/nornicdb/pkg/cypher/antlr/cypher_parser.go b/nornicdb/pkg/cypher/antlr/cypher_parser.go
new file mode 100644
index 0000000..d8f880b
--- /dev/null
+++ b/nornicdb/pkg/cypher/antlr/cypher_parser.go
@@ -0,0 +1,19636 @@
+// Code generated from CypherParser.g4 by ANTLR 4.13.2. DO NOT EDIT.
+
+package antlr // CypherParser
+import (
+ "fmt"
+ "strconv"
+ "sync"
+
+ "github.com/antlr4-go/antlr/v4"
+)
+
+// Suppress unused import errors
+var _ = fmt.Printf
+var _ = strconv.Itoa
+var _ = sync.Once{}
+
+type CypherParser struct {
+ *antlr.BaseParser
+}
+
+var CypherParserParserStaticData struct {
+ once sync.Once
+ serializedATN []int32
+ LiteralNames []string
+ SymbolicNames []string
+ RuleNames []string
+ PredictionContextCache *antlr.PredictionContextCache
+ atn *antlr.ATN
+ decisionToDFA []*antlr.DFA
+}
+
+func cypherparserParserInit() {
+ staticData := &CypherParserParserStaticData
+ staticData.LiteralNames = []string{
+ "", "'='", "'+='", "'<='", "'>='", "'>'", "'<'", "", "'=~'", "'..'",
+ "';'", "'.'", "','", "'('", "')'", "'{'", "'}'", "'['", "']'", "'-'",
+ "'+'", "'/'", "'%'", "'^'", "'*'", "'`'", "':'", "'|'", "'$'", "'CALL'",
+ "'YIELD'", "'FILTER'", "'EXTRACT'", "'COUNT'", "'SUM'", "'AVG'", "'MIN'",
+ "'MAX'", "'COLLECT'", "'ANY'", "'NONE'", "'SINGLE'", "'ALL'", "'ASC'",
+ "'ASCENDING'", "'BY'", "'CREATE'", "'DELETE'", "'DESC'", "'DESCENDING'",
+ "'DETACH'", "'EXISTS'", "'LIMIT'", "'MATCH'", "'MERGE'", "'ON'", "'OPTIONAL'",
+ "'ORDER'", "'REMOVE'", "'RETURN'", "'SET'", "'SKIP'", "'WHERE'", "'WITH'",
+ "'UNION'", "'UNWIND'", "'AND'", "'AS'", "'CONTAINS'", "'DISTINCT'",
+ "'ENDS'", "'IN'", "'IS'", "'NOT'", "'OR'", "'STARTS'", "'XOR'", "'FALSE'",
+ "'TRUE'", "'NULL'", "'CONSTRAINT'", "'DO'", "'FOR'", "'REQUIRE'", "'UNIQUE'",
+ "'CASE'", "'WHEN'", "'THEN'", "'ELSE'", "'END'", "'MANDATORY'", "'SCALAR'",
+ "'OF'", "'ADD'", "'DROP'", "'INDEX'", "'INDEXES'", "'VECTOR'", "'EXPLAIN'",
+ "'PROFILE'", "'SHOW'", "'CONSTRAINTS'", "'PROCEDURES'", "'FUNCTIONS'",
+ "'DATABASE'", "'DATABASES'", "'FULLTEXT'", "'OPTIONS'", "'EACH'", "'IF'",
+ "'TRANSACTIONS'", "'ROWS'", "'ASSERT'", "'KEY'", "'NODE'", "'shortestPath'",
+ "'allShortestPaths'",
+ }
+ staticData.SymbolicNames = []string{
+ "", "ASSIGN", "ADD_ASSIGN", "LE", "GE", "GT", "LT", "NOT_EQUAL", "REGEX_MATCH",
+ "RANGE", "SEMI", "DOT", "COMMA", "LPAREN", "RPAREN", "LBRACE", "RBRACE",
+ "LBRACK", "RBRACK", "SUB", "PLUS", "DIV", "MOD", "CARET", "MULT", "ESC",
+ "COLON", "STICK", "DOLLAR", "CALL", "YIELD", "FILTER", "EXTRACT", "COUNT",
+ "SUM", "AVG", "MIN", "MAX", "COLLECT", "ANY", "NONE", "SINGLE", "ALL",
+ "ASC", "ASCENDING", "BY", "CREATE", "DELETE", "DESC", "DESCENDING",
+ "DETACH", "EXISTS", "LIMIT", "MATCH", "MERGE", "ON", "OPTIONAL", "ORDER",
+ "REMOVE", "RETURN", "SET", "SKIP_W", "WHERE", "WITH", "UNION", "UNWIND",
+ "AND", "AS", "CONTAINS", "DISTINCT", "ENDS", "IN", "IS", "NOT", "OR",
+ "STARTS", "XOR", "FALSE", "TRUE", "NULL_W", "CONSTRAINT", "DO", "FOR",
+ "REQUIRE", "UNIQUE", "CASE", "WHEN", "THEN", "ELSE", "END", "MANDATORY",
+ "SCALAR", "OF", "ADD", "DROP", "INDEX", "INDEXES", "VECTOR", "EXPLAIN",
+ "PROFILE", "SHOW", "CONSTRAINTS", "PROCEDURES", "FUNCTIONS", "DATABASE",
+ "DATABASES", "FULLTEXT", "OPTIONS", "EACH", "IF", "TRANSACTIONS", "ROWS",
+ "ASSERT", "KEY", "NODE", "SHORTESTPATH", "ALLSHORTESTPATHS", "FLOAT",
+ "INTEGER", "DIGIT", "ID", "ESC_LITERAL", "CHAR_LITERAL", "STRING_LITERAL",
+ "WS", "COMMENT", "LINE_COMMENT", "ERRCHAR", "Letter",
+ }
+ staticData.RuleNames = []string{
+ "script", "query", "queryPrefix", "showCommand", "schemaCommand", "regularQuery",
+ "singleQuery", "standaloneCall", "existsSubquery", "countSubquery",
+ "callSubquery", "subqueryBody", "returnSt", "withSt", "skipSt", "limitSt",
+ "projectionBody", "projectionItems", "projectionItem", "orderItem",
+ "orderSt", "singlePartQ", "multiPartQ", "matchSt", "unwindSt", "readingStatement",
+ "updatingStatement", "deleteSt", "removeSt", "removeItem", "queryCallSt",
+ "parenExpressionChain", "yieldItems", "yieldItem", "mergeSt", "mergeAction",
+ "setSt", "setItem", "nodeLabels", "createSt", "patternWhere", "where",
+ "pattern", "expression", "xorExpression", "andExpression", "notExpression",
+ "comparisonExpression", "comparisonSigns", "addSubExpression", "multDivExpression",
+ "powerExpression", "unaryAddSubExpression", "atomicExpression", "listExpression",
+ "stringExpression", "stringExpPrefix", "nullExpression", "propertyOrLabelExpression",
+ "propertyExpression", "patternPart", "pathFunction", "patternElem",
+ "patternElemChain", "properties", "nodePattern", "atom", "lhs", "relationshipPattern",
+ "relationDetail", "relationshipTypes", "unionSt", "subqueryExist", "invocationName",
+ "functionInvocation", "parenthesizedExpression", "filterWith", "patternComprehension",
+ "relationshipsChainPattern", "listComprehension", "filterExpression",
+ "countAll", "expressionChain", "caseExpression", "parameter", "literal",
+ "rangeLit", "boolLit", "integerLit", "numLit", "stringLit", "charLit",
+ "listLit", "mapLit", "mapPair", "name", "symbol", "reservedWord",
+ }
+ staticData.PredictionContextCache = antlr.NewPredictionContextCache()
+ staticData.serializedATN = []int32{
+ 4, 1, 128, 1084, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4,
+ 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10,
+ 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7,
+ 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20,
+ 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2,
+ 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31,
+ 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7,
+ 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41,
+ 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2,
+ 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52,
+ 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7,
+ 57, 2, 58, 7, 58, 2, 59, 7, 59, 2, 60, 7, 60, 2, 61, 7, 61, 2, 62, 7, 62,
+ 2, 63, 7, 63, 2, 64, 7, 64, 2, 65, 7, 65, 2, 66, 7, 66, 2, 67, 7, 67, 2,
+ 68, 7, 68, 2, 69, 7, 69, 2, 70, 7, 70, 2, 71, 7, 71, 2, 72, 7, 72, 2, 73,
+ 7, 73, 2, 74, 7, 74, 2, 75, 7, 75, 2, 76, 7, 76, 2, 77, 7, 77, 2, 78, 7,
+ 78, 2, 79, 7, 79, 2, 80, 7, 80, 2, 81, 7, 81, 2, 82, 7, 82, 2, 83, 7, 83,
+ 2, 84, 7, 84, 2, 85, 7, 85, 2, 86, 7, 86, 2, 87, 7, 87, 2, 88, 7, 88, 2,
+ 89, 7, 89, 2, 90, 7, 90, 2, 91, 7, 91, 2, 92, 7, 92, 2, 93, 7, 93, 2, 94,
+ 7, 94, 2, 95, 7, 95, 2, 96, 7, 96, 2, 97, 7, 97, 1, 0, 1, 0, 1, 0, 5, 0,
+ 200, 8, 0, 10, 0, 12, 0, 203, 9, 0, 1, 0, 3, 0, 206, 8, 0, 1, 0, 1, 0,
+ 1, 1, 3, 1, 211, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 217, 8, 1, 1, 2, 1,
+ 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 3, 3, 231,
+ 8, 3, 3, 3, 233, 8, 3, 1, 4, 1, 4, 1, 4, 3, 4, 238, 8, 4, 1, 4, 1, 4, 3,
+ 4, 242, 8, 4, 1, 4, 1, 4, 1, 4, 3, 4, 247, 8, 4, 1, 4, 1, 4, 1, 4, 3, 4,
+ 252, 8, 4, 1, 4, 1, 4, 3, 4, 256, 8, 4, 1, 4, 3, 4, 259, 8, 4, 1, 4, 3,
+ 4, 262, 8, 4, 1, 4, 1, 4, 1, 4, 1, 4, 3, 4, 268, 8, 4, 1, 4, 1, 4, 1, 4,
+ 3, 4, 273, 8, 4, 1, 4, 1, 4, 3, 4, 277, 8, 4, 1, 4, 3, 4, 280, 8, 4, 1,
+ 4, 3, 4, 283, 8, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 3,
+ 4, 293, 8, 4, 1, 4, 1, 4, 1, 4, 3, 4, 298, 8, 4, 1, 4, 1, 4, 3, 4, 302,
+ 8, 4, 1, 4, 3, 4, 305, 8, 4, 1, 4, 3, 4, 308, 8, 4, 1, 4, 1, 4, 3, 4, 312,
+ 8, 4, 1, 4, 1, 4, 1, 4, 3, 4, 317, 8, 4, 1, 4, 1, 4, 3, 4, 321, 8, 4, 1,
+ 4, 1, 4, 1, 4, 3, 4, 326, 8, 4, 1, 4, 1, 4, 1, 4, 3, 4, 331, 8, 4, 1, 4,
+ 1, 4, 3, 4, 335, 8, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 3, 4,
+ 344, 8, 4, 1, 4, 1, 4, 1, 4, 3, 4, 349, 8, 4, 1, 4, 1, 4, 1, 4, 3, 4, 354,
+ 8, 4, 1, 4, 3, 4, 357, 8, 4, 1, 4, 3, 4, 360, 8, 4, 1, 4, 1, 4, 1, 4, 3,
+ 4, 365, 8, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 3, 4, 373, 8, 4, 3, 4,
+ 375, 8, 4, 1, 5, 1, 5, 5, 5, 379, 8, 5, 10, 5, 12, 5, 382, 9, 5, 1, 6,
+ 1, 6, 3, 6, 386, 8, 6, 1, 7, 1, 7, 1, 7, 3, 7, 391, 8, 7, 1, 7, 1, 7, 1,
+ 7, 3, 7, 396, 8, 7, 3, 7, 398, 8, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 9,
+ 1, 9, 1, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10,
+ 1, 10, 1, 10, 1, 10, 3, 10, 420, 8, 10, 3, 10, 422, 8, 10, 1, 11, 3, 11,
+ 425, 8, 11, 1, 11, 1, 11, 5, 11, 429, 8, 11, 10, 11, 12, 11, 432, 9, 11,
+ 1, 11, 3, 11, 435, 8, 11, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 3,
+ 13, 443, 8, 13, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 16, 3, 16,
+ 452, 8, 16, 1, 16, 1, 16, 3, 16, 456, 8, 16, 1, 16, 3, 16, 459, 8, 16,
+ 1, 16, 3, 16, 462, 8, 16, 1, 17, 1, 17, 3, 17, 466, 8, 17, 1, 17, 1, 17,
+ 5, 17, 470, 8, 17, 10, 17, 12, 17, 473, 9, 17, 1, 18, 1, 18, 1, 18, 3,
+ 18, 478, 8, 18, 1, 19, 1, 19, 3, 19, 482, 8, 19, 1, 20, 1, 20, 1, 20, 1,
+ 20, 1, 20, 5, 20, 489, 8, 20, 10, 20, 12, 20, 492, 9, 20, 1, 21, 5, 21,
+ 495, 8, 21, 10, 21, 12, 21, 498, 9, 21, 1, 21, 1, 21, 4, 21, 502, 8, 21,
+ 11, 21, 12, 21, 503, 1, 21, 3, 21, 507, 8, 21, 3, 21, 509, 8, 21, 1, 21,
+ 1, 21, 3, 21, 513, 8, 21, 3, 21, 515, 8, 21, 1, 22, 1, 22, 5, 22, 519,
+ 8, 22, 10, 22, 12, 22, 522, 9, 22, 1, 22, 4, 22, 525, 8, 22, 11, 22, 12,
+ 22, 526, 1, 22, 1, 22, 1, 23, 3, 23, 532, 8, 23, 1, 23, 1, 23, 1, 23, 1,
+ 24, 1, 24, 1, 24, 1, 24, 1, 24, 3, 24, 542, 8, 24, 1, 25, 1, 25, 1, 25,
+ 1, 25, 3, 25, 548, 8, 25, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 3, 26, 555,
+ 8, 26, 1, 27, 3, 27, 558, 8, 27, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1,
+ 28, 1, 28, 5, 28, 567, 8, 28, 10, 28, 12, 28, 570, 9, 28, 1, 29, 1, 29,
+ 1, 29, 1, 29, 3, 29, 576, 8, 29, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 3,
+ 30, 583, 8, 30, 1, 31, 1, 31, 3, 31, 587, 8, 31, 1, 31, 1, 31, 1, 32, 1,
+ 32, 1, 32, 5, 32, 594, 8, 32, 10, 32, 12, 32, 597, 9, 32, 1, 32, 3, 32,
+ 600, 8, 32, 1, 33, 1, 33, 1, 33, 3, 33, 605, 8, 33, 1, 33, 1, 33, 1, 34,
+ 1, 34, 1, 34, 5, 34, 612, 8, 34, 10, 34, 12, 34, 615, 9, 34, 1, 35, 1,
+ 35, 1, 35, 1, 35, 1, 36, 1, 36, 1, 36, 1, 36, 5, 36, 625, 8, 36, 10, 36,
+ 12, 36, 628, 9, 36, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1,
+ 37, 1, 37, 1, 37, 1, 37, 3, 37, 641, 8, 37, 1, 38, 1, 38, 4, 38, 645, 8,
+ 38, 11, 38, 12, 38, 646, 1, 39, 1, 39, 1, 39, 1, 40, 1, 40, 3, 40, 654,
+ 8, 40, 1, 41, 1, 41, 1, 41, 1, 42, 1, 42, 1, 42, 5, 42, 662, 8, 42, 10,
+ 42, 12, 42, 665, 9, 42, 1, 43, 1, 43, 1, 43, 5, 43, 670, 8, 43, 10, 43,
+ 12, 43, 673, 9, 43, 1, 44, 1, 44, 1, 44, 5, 44, 678, 8, 44, 10, 44, 12,
+ 44, 681, 9, 44, 1, 45, 1, 45, 1, 45, 5, 45, 686, 8, 45, 10, 45, 12, 45,
+ 689, 9, 45, 1, 46, 3, 46, 692, 8, 46, 1, 46, 1, 46, 3, 46, 696, 8, 46,
+ 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 3, 46, 703, 8, 46, 1, 47, 1, 47, 1,
+ 47, 1, 47, 5, 47, 709, 8, 47, 10, 47, 12, 47, 712, 9, 47, 1, 48, 1, 48,
+ 1, 49, 1, 49, 1, 49, 5, 49, 719, 8, 49, 10, 49, 12, 49, 722, 9, 49, 1,
+ 50, 1, 50, 1, 50, 5, 50, 727, 8, 50, 10, 50, 12, 50, 730, 9, 50, 1, 51,
+ 1, 51, 1, 51, 5, 51, 735, 8, 51, 10, 51, 12, 51, 738, 9, 51, 1, 52, 3,
+ 52, 741, 8, 52, 1, 52, 1, 52, 1, 53, 1, 53, 1, 53, 1, 53, 5, 53, 749, 8,
+ 53, 10, 53, 12, 53, 752, 9, 53, 1, 54, 1, 54, 1, 54, 1, 54, 3, 54, 758,
+ 8, 54, 1, 54, 1, 54, 3, 54, 762, 8, 54, 1, 54, 3, 54, 765, 8, 54, 1, 54,
+ 3, 54, 768, 8, 54, 1, 55, 1, 55, 1, 55, 1, 56, 1, 56, 1, 56, 1, 56, 1,
+ 56, 3, 56, 778, 8, 56, 1, 57, 1, 57, 3, 57, 782, 8, 57, 1, 57, 1, 57, 1,
+ 58, 1, 58, 3, 58, 788, 8, 58, 1, 59, 1, 59, 1, 59, 5, 59, 793, 8, 59, 10,
+ 59, 12, 59, 796, 9, 59, 1, 60, 1, 60, 1, 60, 3, 60, 801, 8, 60, 1, 60,
+ 1, 60, 1, 60, 1, 60, 3, 60, 807, 8, 60, 1, 60, 3, 60, 810, 8, 60, 1, 61,
+ 1, 61, 1, 61, 1, 61, 1, 61, 1, 62, 1, 62, 5, 62, 819, 8, 62, 10, 62, 12,
+ 62, 822, 9, 62, 1, 62, 1, 62, 1, 62, 1, 62, 3, 62, 828, 8, 62, 1, 63, 1,
+ 63, 1, 63, 1, 64, 1, 64, 3, 64, 835, 8, 64, 1, 65, 1, 65, 3, 65, 839, 8,
+ 65, 1, 65, 3, 65, 842, 8, 65, 1, 65, 3, 65, 845, 8, 65, 1, 65, 1, 65, 1,
+ 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66,
+ 1, 66, 3, 66, 861, 8, 66, 1, 67, 1, 67, 1, 67, 1, 68, 1, 68, 1, 68, 3,
+ 68, 869, 8, 68, 1, 68, 1, 68, 3, 68, 873, 8, 68, 1, 68, 1, 68, 3, 68, 877,
+ 8, 68, 1, 68, 1, 68, 3, 68, 881, 8, 68, 3, 68, 883, 8, 68, 1, 69, 1, 69,
+ 3, 69, 887, 8, 69, 1, 69, 3, 69, 890, 8, 69, 1, 69, 3, 69, 893, 8, 69,
+ 1, 69, 3, 69, 896, 8, 69, 1, 69, 1, 69, 1, 70, 1, 70, 1, 70, 1, 70, 3,
+ 70, 904, 8, 70, 1, 70, 5, 70, 907, 8, 70, 10, 70, 12, 70, 910, 9, 70, 1,
+ 71, 1, 71, 3, 71, 914, 8, 71, 1, 71, 1, 71, 1, 72, 1, 72, 1, 72, 1, 72,
+ 3, 72, 922, 8, 72, 1, 72, 1, 72, 1, 73, 1, 73, 1, 73, 5, 73, 929, 8, 73,
+ 10, 73, 12, 73, 932, 9, 73, 1, 74, 1, 74, 1, 74, 3, 74, 937, 8, 74, 1,
+ 74, 3, 74, 940, 8, 74, 1, 74, 1, 74, 1, 75, 1, 75, 1, 75, 1, 75, 1, 76,
+ 1, 76, 1, 76, 1, 76, 1, 76, 1, 77, 1, 77, 3, 77, 955, 8, 77, 1, 77, 1,
+ 77, 3, 77, 959, 8, 77, 1, 77, 1, 77, 1, 77, 1, 77, 1, 78, 1, 78, 4, 78,
+ 967, 8, 78, 11, 78, 12, 78, 968, 1, 79, 1, 79, 1, 79, 1, 79, 3, 79, 975,
+ 8, 79, 1, 79, 1, 79, 1, 80, 1, 80, 1, 80, 1, 80, 3, 80, 983, 8, 80, 1,
+ 81, 1, 81, 1, 81, 1, 81, 1, 81, 1, 82, 1, 82, 1, 82, 5, 82, 993, 8, 82,
+ 10, 82, 12, 82, 996, 9, 82, 1, 83, 1, 83, 3, 83, 1000, 8, 83, 1, 83, 1,
+ 83, 1, 83, 1, 83, 1, 83, 4, 83, 1007, 8, 83, 11, 83, 12, 83, 1008, 1, 83,
+ 1, 83, 3, 83, 1013, 8, 83, 1, 83, 1, 83, 1, 84, 1, 84, 1, 84, 3, 84, 1020,
+ 8, 84, 1, 85, 1, 85, 1, 85, 1, 85, 1, 85, 1, 85, 1, 85, 3, 85, 1029, 8,
+ 85, 1, 86, 1, 86, 3, 86, 1033, 8, 86, 1, 86, 1, 86, 3, 86, 1037, 8, 86,
+ 3, 86, 1039, 8, 86, 1, 87, 1, 87, 1, 88, 1, 88, 1, 89, 1, 89, 3, 89, 1047,
+ 8, 89, 1, 90, 1, 90, 1, 91, 1, 91, 1, 92, 1, 92, 3, 92, 1055, 8, 92, 1,
+ 92, 1, 92, 1, 93, 1, 93, 1, 93, 1, 93, 5, 93, 1063, 8, 93, 10, 93, 12,
+ 93, 1066, 9, 93, 3, 93, 1068, 8, 93, 1, 93, 1, 93, 1, 94, 1, 94, 1, 94,
+ 1, 94, 1, 95, 1, 95, 3, 95, 1078, 8, 95, 1, 96, 1, 96, 1, 97, 1, 97, 1,
+ 97, 0, 0, 98, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30,
+ 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66,
+ 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102,
+ 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132,
+ 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162,
+ 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192,
+ 194, 0, 13, 1, 0, 98, 99, 2, 0, 43, 44, 48, 49, 2, 0, 46, 46, 53, 53, 1,
+ 0, 1, 2, 2, 0, 1, 1, 3, 8, 1, 0, 19, 20, 2, 0, 21, 22, 24, 24, 1, 0, 115,
+ 116, 1, 0, 39, 42, 1, 0, 77, 78, 1, 0, 118, 119, 12, 0, 31, 42, 46, 47,
+ 51, 51, 53, 54, 58, 58, 60, 60, 77, 80, 83, 89, 93, 97, 100, 104, 106,
+ 116, 120, 121, 1, 0, 42, 94, 1176, 0, 196, 1, 0, 0, 0, 2, 210, 1, 0, 0,
+ 0, 4, 218, 1, 0, 0, 0, 6, 220, 1, 0, 0, 0, 8, 374, 1, 0, 0, 0, 10, 376,
+ 1, 0, 0, 0, 12, 385, 1, 0, 0, 0, 14, 387, 1, 0, 0, 0, 16, 399, 1, 0, 0,
+ 0, 18, 404, 1, 0, 0, 0, 20, 409, 1, 0, 0, 0, 22, 424, 1, 0, 0, 0, 24, 436,
+ 1, 0, 0, 0, 26, 439, 1, 0, 0, 0, 28, 444, 1, 0, 0, 0, 30, 447, 1, 0, 0,
+ 0, 32, 451, 1, 0, 0, 0, 34, 465, 1, 0, 0, 0, 36, 474, 1, 0, 0, 0, 38, 479,
+ 1, 0, 0, 0, 40, 483, 1, 0, 0, 0, 42, 514, 1, 0, 0, 0, 44, 524, 1, 0, 0,
+ 0, 46, 531, 1, 0, 0, 0, 48, 536, 1, 0, 0, 0, 50, 547, 1, 0, 0, 0, 52, 554,
+ 1, 0, 0, 0, 54, 557, 1, 0, 0, 0, 56, 562, 1, 0, 0, 0, 58, 575, 1, 0, 0,
+ 0, 60, 577, 1, 0, 0, 0, 62, 584, 1, 0, 0, 0, 64, 590, 1, 0, 0, 0, 66, 604,
+ 1, 0, 0, 0, 68, 608, 1, 0, 0, 0, 70, 616, 1, 0, 0, 0, 72, 620, 1, 0, 0,
+ 0, 74, 640, 1, 0, 0, 0, 76, 644, 1, 0, 0, 0, 78, 648, 1, 0, 0, 0, 80, 651,
+ 1, 0, 0, 0, 82, 655, 1, 0, 0, 0, 84, 658, 1, 0, 0, 0, 86, 666, 1, 0, 0,
+ 0, 88, 674, 1, 0, 0, 0, 90, 682, 1, 0, 0, 0, 92, 702, 1, 0, 0, 0, 94, 704,
+ 1, 0, 0, 0, 96, 713, 1, 0, 0, 0, 98, 715, 1, 0, 0, 0, 100, 723, 1, 0, 0,
+ 0, 102, 731, 1, 0, 0, 0, 104, 740, 1, 0, 0, 0, 106, 744, 1, 0, 0, 0, 108,
+ 767, 1, 0, 0, 0, 110, 769, 1, 0, 0, 0, 112, 777, 1, 0, 0, 0, 114, 779,
+ 1, 0, 0, 0, 116, 785, 1, 0, 0, 0, 118, 789, 1, 0, 0, 0, 120, 809, 1, 0,
+ 0, 0, 122, 811, 1, 0, 0, 0, 124, 827, 1, 0, 0, 0, 126, 829, 1, 0, 0, 0,
+ 128, 834, 1, 0, 0, 0, 130, 836, 1, 0, 0, 0, 132, 860, 1, 0, 0, 0, 134,
+ 862, 1, 0, 0, 0, 136, 882, 1, 0, 0, 0, 138, 884, 1, 0, 0, 0, 140, 899,
+ 1, 0, 0, 0, 142, 911, 1, 0, 0, 0, 144, 917, 1, 0, 0, 0, 146, 925, 1, 0,
+ 0, 0, 148, 933, 1, 0, 0, 0, 150, 943, 1, 0, 0, 0, 152, 947, 1, 0, 0, 0,
+ 154, 952, 1, 0, 0, 0, 156, 964, 1, 0, 0, 0, 158, 970, 1, 0, 0, 0, 160,
+ 978, 1, 0, 0, 0, 162, 984, 1, 0, 0, 0, 164, 989, 1, 0, 0, 0, 166, 997,
+ 1, 0, 0, 0, 168, 1016, 1, 0, 0, 0, 170, 1028, 1, 0, 0, 0, 172, 1030, 1,
+ 0, 0, 0, 174, 1040, 1, 0, 0, 0, 176, 1042, 1, 0, 0, 0, 178, 1046, 1, 0,
+ 0, 0, 180, 1048, 1, 0, 0, 0, 182, 1050, 1, 0, 0, 0, 184, 1052, 1, 0, 0,
+ 0, 186, 1058, 1, 0, 0, 0, 188, 1071, 1, 0, 0, 0, 190, 1077, 1, 0, 0, 0,
+ 192, 1079, 1, 0, 0, 0, 194, 1081, 1, 0, 0, 0, 196, 201, 3, 2, 1, 0, 197,
+ 198, 5, 10, 0, 0, 198, 200, 3, 2, 1, 0, 199, 197, 1, 0, 0, 0, 200, 203,
+ 1, 0, 0, 0, 201, 199, 1, 0, 0, 0, 201, 202, 1, 0, 0, 0, 202, 205, 1, 0,
+ 0, 0, 203, 201, 1, 0, 0, 0, 204, 206, 5, 10, 0, 0, 205, 204, 1, 0, 0, 0,
+ 205, 206, 1, 0, 0, 0, 206, 207, 1, 0, 0, 0, 207, 208, 5, 0, 0, 1, 208,
+ 1, 1, 0, 0, 0, 209, 211, 3, 4, 2, 0, 210, 209, 1, 0, 0, 0, 210, 211, 1,
+ 0, 0, 0, 211, 216, 1, 0, 0, 0, 212, 217, 3, 10, 5, 0, 213, 217, 3, 14,
+ 7, 0, 214, 217, 3, 8, 4, 0, 215, 217, 3, 6, 3, 0, 216, 212, 1, 0, 0, 0,
+ 216, 213, 1, 0, 0, 0, 216, 214, 1, 0, 0, 0, 216, 215, 1, 0, 0, 0, 217,
+ 3, 1, 0, 0, 0, 218, 219, 7, 0, 0, 0, 219, 5, 1, 0, 0, 0, 220, 232, 5, 100,
+ 0, 0, 221, 233, 5, 96, 0, 0, 222, 233, 5, 95, 0, 0, 223, 233, 5, 101, 0,
+ 0, 224, 233, 5, 80, 0, 0, 225, 233, 5, 102, 0, 0, 226, 233, 5, 103, 0,
+ 0, 227, 233, 5, 104, 0, 0, 228, 233, 5, 105, 0, 0, 229, 231, 5, 42, 0,
+ 0, 230, 229, 1, 0, 0, 0, 230, 231, 1, 0, 0, 0, 231, 233, 1, 0, 0, 0, 232,
+ 221, 1, 0, 0, 0, 232, 222, 1, 0, 0, 0, 232, 223, 1, 0, 0, 0, 232, 224,
+ 1, 0, 0, 0, 232, 225, 1, 0, 0, 0, 232, 226, 1, 0, 0, 0, 232, 227, 1, 0,
+ 0, 0, 232, 228, 1, 0, 0, 0, 232, 230, 1, 0, 0, 0, 233, 7, 1, 0, 0, 0, 234,
+ 235, 5, 94, 0, 0, 235, 237, 5, 95, 0, 0, 236, 238, 3, 190, 95, 0, 237,
+ 236, 1, 0, 0, 0, 237, 238, 1, 0, 0, 0, 238, 241, 1, 0, 0, 0, 239, 240,
+ 5, 109, 0, 0, 240, 242, 5, 51, 0, 0, 241, 239, 1, 0, 0, 0, 241, 242, 1,
+ 0, 0, 0, 242, 375, 1, 0, 0, 0, 243, 244, 5, 46, 0, 0, 244, 246, 5, 95,
+ 0, 0, 245, 247, 3, 190, 95, 0, 246, 245, 1, 0, 0, 0, 246, 247, 1, 0, 0,
+ 0, 247, 251, 1, 0, 0, 0, 248, 249, 5, 109, 0, 0, 249, 250, 5, 73, 0, 0,
+ 250, 252, 5, 51, 0, 0, 251, 248, 1, 0, 0, 0, 251, 252, 1, 0, 0, 0, 252,
+ 255, 1, 0, 0, 0, 253, 254, 5, 82, 0, 0, 254, 256, 3, 130, 65, 0, 255, 253,
+ 1, 0, 0, 0, 255, 256, 1, 0, 0, 0, 256, 258, 1, 0, 0, 0, 257, 259, 5, 55,
+ 0, 0, 258, 257, 1, 0, 0, 0, 258, 259, 1, 0, 0, 0, 259, 261, 1, 0, 0, 0,
+ 260, 262, 3, 62, 31, 0, 261, 260, 1, 0, 0, 0, 261, 262, 1, 0, 0, 0, 262,
+ 375, 1, 0, 0, 0, 263, 264, 5, 46, 0, 0, 264, 265, 5, 106, 0, 0, 265, 267,
+ 5, 95, 0, 0, 266, 268, 3, 190, 95, 0, 267, 266, 1, 0, 0, 0, 267, 268, 1,
+ 0, 0, 0, 268, 272, 1, 0, 0, 0, 269, 270, 5, 109, 0, 0, 270, 271, 5, 73,
+ 0, 0, 271, 273, 5, 51, 0, 0, 272, 269, 1, 0, 0, 0, 272, 273, 1, 0, 0, 0,
+ 273, 276, 1, 0, 0, 0, 274, 275, 5, 82, 0, 0, 275, 277, 3, 130, 65, 0, 276,
+ 274, 1, 0, 0, 0, 276, 277, 1, 0, 0, 0, 277, 279, 1, 0, 0, 0, 278, 280,
+ 5, 55, 0, 0, 279, 278, 1, 0, 0, 0, 279, 280, 1, 0, 0, 0, 280, 282, 1, 0,
+ 0, 0, 281, 283, 5, 108, 0, 0, 282, 281, 1, 0, 0, 0, 282, 283, 1, 0, 0,
+ 0, 283, 284, 1, 0, 0, 0, 284, 285, 5, 17, 0, 0, 285, 286, 3, 164, 82, 0,
+ 286, 287, 5, 18, 0, 0, 287, 375, 1, 0, 0, 0, 288, 289, 5, 46, 0, 0, 289,
+ 290, 5, 97, 0, 0, 290, 292, 5, 95, 0, 0, 291, 293, 3, 190, 95, 0, 292,
+ 291, 1, 0, 0, 0, 292, 293, 1, 0, 0, 0, 293, 297, 1, 0, 0, 0, 294, 295,
+ 5, 109, 0, 0, 295, 296, 5, 73, 0, 0, 296, 298, 5, 51, 0, 0, 297, 294, 1,
+ 0, 0, 0, 297, 298, 1, 0, 0, 0, 298, 301, 1, 0, 0, 0, 299, 300, 5, 82, 0,
+ 0, 300, 302, 3, 130, 65, 0, 301, 299, 1, 0, 0, 0, 301, 302, 1, 0, 0, 0,
+ 302, 304, 1, 0, 0, 0, 303, 305, 5, 55, 0, 0, 304, 303, 1, 0, 0, 0, 304,
+ 305, 1, 0, 0, 0, 305, 307, 1, 0, 0, 0, 306, 308, 3, 62, 31, 0, 307, 306,
+ 1, 0, 0, 0, 307, 308, 1, 0, 0, 0, 308, 311, 1, 0, 0, 0, 309, 310, 5, 107,
+ 0, 0, 310, 312, 3, 186, 93, 0, 311, 309, 1, 0, 0, 0, 311, 312, 1, 0, 0,
+ 0, 312, 375, 1, 0, 0, 0, 313, 314, 5, 94, 0, 0, 314, 316, 5, 80, 0, 0,
+ 315, 317, 3, 190, 95, 0, 316, 315, 1, 0, 0, 0, 316, 317, 1, 0, 0, 0, 317,
+ 320, 1, 0, 0, 0, 318, 319, 5, 109, 0, 0, 319, 321, 5, 51, 0, 0, 320, 318,
+ 1, 0, 0, 0, 320, 321, 1, 0, 0, 0, 321, 375, 1, 0, 0, 0, 322, 323, 5, 46,
+ 0, 0, 323, 325, 5, 80, 0, 0, 324, 326, 3, 190, 95, 0, 325, 324, 1, 0, 0,
+ 0, 325, 326, 1, 0, 0, 0, 326, 330, 1, 0, 0, 0, 327, 328, 5, 109, 0, 0,
+ 328, 329, 5, 73, 0, 0, 329, 331, 5, 51, 0, 0, 330, 327, 1, 0, 0, 0, 330,
+ 331, 1, 0, 0, 0, 331, 334, 1, 0, 0, 0, 332, 333, 5, 82, 0, 0, 333, 335,
+ 3, 130, 65, 0, 334, 332, 1, 0, 0, 0, 334, 335, 1, 0, 0, 0, 335, 336, 1,
+ 0, 0, 0, 336, 337, 5, 83, 0, 0, 337, 343, 3, 86, 43, 0, 338, 339, 5, 72,
+ 0, 0, 339, 344, 5, 84, 0, 0, 340, 341, 5, 72, 0, 0, 341, 342, 5, 73, 0,
+ 0, 342, 344, 5, 79, 0, 0, 343, 338, 1, 0, 0, 0, 343, 340, 1, 0, 0, 0, 344,
+ 375, 1, 0, 0, 0, 345, 346, 5, 46, 0, 0, 346, 348, 5, 80, 0, 0, 347, 349,
+ 3, 190, 95, 0, 348, 347, 1, 0, 0, 0, 348, 349, 1, 0, 0, 0, 349, 353, 1,
+ 0, 0, 0, 350, 351, 5, 109, 0, 0, 351, 352, 5, 73, 0, 0, 352, 354, 5, 51,
+ 0, 0, 353, 350, 1, 0, 0, 0, 353, 354, 1, 0, 0, 0, 354, 356, 1, 0, 0, 0,
+ 355, 357, 5, 55, 0, 0, 356, 355, 1, 0, 0, 0, 356, 357, 1, 0, 0, 0, 357,
+ 359, 1, 0, 0, 0, 358, 360, 3, 130, 65, 0, 359, 358, 1, 0, 0, 0, 359, 360,
+ 1, 0, 0, 0, 360, 361, 1, 0, 0, 0, 361, 364, 5, 112, 0, 0, 362, 365, 3,
+ 86, 43, 0, 363, 365, 3, 62, 31, 0, 364, 362, 1, 0, 0, 0, 364, 363, 1, 0,
+ 0, 0, 365, 366, 1, 0, 0, 0, 366, 372, 5, 72, 0, 0, 367, 373, 5, 84, 0,
+ 0, 368, 369, 5, 73, 0, 0, 369, 373, 5, 79, 0, 0, 370, 371, 5, 114, 0, 0,
+ 371, 373, 5, 113, 0, 0, 372, 367, 1, 0, 0, 0, 372, 368, 1, 0, 0, 0, 372,
+ 370, 1, 0, 0, 0, 373, 375, 1, 0, 0, 0, 374, 234, 1, 0, 0, 0, 374, 243,
+ 1, 0, 0, 0, 374, 263, 1, 0, 0, 0, 374, 288, 1, 0, 0, 0, 374, 313, 1, 0,
+ 0, 0, 374, 322, 1, 0, 0, 0, 374, 345, 1, 0, 0, 0, 375, 9, 1, 0, 0, 0, 376,
+ 380, 3, 12, 6, 0, 377, 379, 3, 142, 71, 0, 378, 377, 1, 0, 0, 0, 379, 382,
+ 1, 0, 0, 0, 380, 378, 1, 0, 0, 0, 380, 381, 1, 0, 0, 0, 381, 11, 1, 0,
+ 0, 0, 382, 380, 1, 0, 0, 0, 383, 386, 3, 42, 21, 0, 384, 386, 3, 44, 22,
+ 0, 385, 383, 1, 0, 0, 0, 385, 384, 1, 0, 0, 0, 386, 13, 1, 0, 0, 0, 387,
+ 388, 5, 29, 0, 0, 388, 390, 3, 146, 73, 0, 389, 391, 3, 62, 31, 0, 390,
+ 389, 1, 0, 0, 0, 390, 391, 1, 0, 0, 0, 391, 397, 1, 0, 0, 0, 392, 395,
+ 5, 30, 0, 0, 393, 396, 5, 24, 0, 0, 394, 396, 3, 64, 32, 0, 395, 393, 1,
+ 0, 0, 0, 395, 394, 1, 0, 0, 0, 396, 398, 1, 0, 0, 0, 397, 392, 1, 0, 0,
+ 0, 397, 398, 1, 0, 0, 0, 398, 15, 1, 0, 0, 0, 399, 400, 5, 51, 0, 0, 400,
+ 401, 5, 15, 0, 0, 401, 402, 3, 46, 23, 0, 402, 403, 5, 16, 0, 0, 403, 17,
+ 1, 0, 0, 0, 404, 405, 5, 33, 0, 0, 405, 406, 5, 15, 0, 0, 406, 407, 3,
+ 46, 23, 0, 407, 408, 5, 16, 0, 0, 408, 19, 1, 0, 0, 0, 409, 410, 5, 29,
+ 0, 0, 410, 411, 5, 15, 0, 0, 411, 412, 3, 22, 11, 0, 412, 421, 5, 16, 0,
+ 0, 413, 414, 5, 71, 0, 0, 414, 419, 5, 110, 0, 0, 415, 416, 5, 92, 0, 0,
+ 416, 417, 3, 178, 89, 0, 417, 418, 5, 111, 0, 0, 418, 420, 1, 0, 0, 0,
+ 419, 415, 1, 0, 0, 0, 419, 420, 1, 0, 0, 0, 420, 422, 1, 0, 0, 0, 421,
+ 413, 1, 0, 0, 0, 421, 422, 1, 0, 0, 0, 422, 21, 1, 0, 0, 0, 423, 425, 3,
+ 26, 13, 0, 424, 423, 1, 0, 0, 0, 424, 425, 1, 0, 0, 0, 425, 430, 1, 0,
+ 0, 0, 426, 429, 3, 50, 25, 0, 427, 429, 3, 52, 26, 0, 428, 426, 1, 0, 0,
+ 0, 428, 427, 1, 0, 0, 0, 429, 432, 1, 0, 0, 0, 430, 428, 1, 0, 0, 0, 430,
+ 431, 1, 0, 0, 0, 431, 434, 1, 0, 0, 0, 432, 430, 1, 0, 0, 0, 433, 435,
+ 3, 24, 12, 0, 434, 433, 1, 0, 0, 0, 434, 435, 1, 0, 0, 0, 435, 23, 1, 0,
+ 0, 0, 436, 437, 5, 59, 0, 0, 437, 438, 3, 32, 16, 0, 438, 25, 1, 0, 0,
+ 0, 439, 440, 5, 63, 0, 0, 440, 442, 3, 32, 16, 0, 441, 443, 3, 82, 41,
+ 0, 442, 441, 1, 0, 0, 0, 442, 443, 1, 0, 0, 0, 443, 27, 1, 0, 0, 0, 444,
+ 445, 5, 61, 0, 0, 445, 446, 3, 86, 43, 0, 446, 29, 1, 0, 0, 0, 447, 448,
+ 5, 52, 0, 0, 448, 449, 3, 86, 43, 0, 449, 31, 1, 0, 0, 0, 450, 452, 5,
+ 69, 0, 0, 451, 450, 1, 0, 0, 0, 451, 452, 1, 0, 0, 0, 452, 453, 1, 0, 0,
+ 0, 453, 455, 3, 34, 17, 0, 454, 456, 3, 40, 20, 0, 455, 454, 1, 0, 0, 0,
+ 455, 456, 1, 0, 0, 0, 456, 458, 1, 0, 0, 0, 457, 459, 3, 28, 14, 0, 458,
+ 457, 1, 0, 0, 0, 458, 459, 1, 0, 0, 0, 459, 461, 1, 0, 0, 0, 460, 462,
+ 3, 30, 15, 0, 461, 460, 1, 0, 0, 0, 461, 462, 1, 0, 0, 0, 462, 33, 1, 0,
+ 0, 0, 463, 466, 5, 24, 0, 0, 464, 466, 3, 36, 18, 0, 465, 463, 1, 0, 0,
+ 0, 465, 464, 1, 0, 0, 0, 466, 471, 1, 0, 0, 0, 467, 468, 5, 12, 0, 0, 468,
+ 470, 3, 36, 18, 0, 469, 467, 1, 0, 0, 0, 470, 473, 1, 0, 0, 0, 471, 469,
+ 1, 0, 0, 0, 471, 472, 1, 0, 0, 0, 472, 35, 1, 0, 0, 0, 473, 471, 1, 0,
+ 0, 0, 474, 477, 3, 86, 43, 0, 475, 476, 5, 67, 0, 0, 476, 478, 3, 192,
+ 96, 0, 477, 475, 1, 0, 0, 0, 477, 478, 1, 0, 0, 0, 478, 37, 1, 0, 0, 0,
+ 479, 481, 3, 86, 43, 0, 480, 482, 7, 1, 0, 0, 481, 480, 1, 0, 0, 0, 481,
+ 482, 1, 0, 0, 0, 482, 39, 1, 0, 0, 0, 483, 484, 5, 57, 0, 0, 484, 485,
+ 5, 45, 0, 0, 485, 490, 3, 38, 19, 0, 486, 487, 5, 12, 0, 0, 487, 489, 3,
+ 38, 19, 0, 488, 486, 1, 0, 0, 0, 489, 492, 1, 0, 0, 0, 490, 488, 1, 0,
+ 0, 0, 490, 491, 1, 0, 0, 0, 491, 41, 1, 0, 0, 0, 492, 490, 1, 0, 0, 0,
+ 493, 495, 3, 50, 25, 0, 494, 493, 1, 0, 0, 0, 495, 498, 1, 0, 0, 0, 496,
+ 494, 1, 0, 0, 0, 496, 497, 1, 0, 0, 0, 497, 508, 1, 0, 0, 0, 498, 496,
+ 1, 0, 0, 0, 499, 509, 3, 24, 12, 0, 500, 502, 3, 52, 26, 0, 501, 500, 1,
+ 0, 0, 0, 502, 503, 1, 0, 0, 0, 503, 501, 1, 0, 0, 0, 503, 504, 1, 0, 0,
+ 0, 504, 506, 1, 0, 0, 0, 505, 507, 3, 24, 12, 0, 506, 505, 1, 0, 0, 0,
+ 506, 507, 1, 0, 0, 0, 507, 509, 1, 0, 0, 0, 508, 499, 1, 0, 0, 0, 508,
+ 501, 1, 0, 0, 0, 508, 509, 1, 0, 0, 0, 509, 515, 1, 0, 0, 0, 510, 512,
+ 3, 20, 10, 0, 511, 513, 3, 40, 20, 0, 512, 511, 1, 0, 0, 0, 512, 513, 1,
+ 0, 0, 0, 513, 515, 1, 0, 0, 0, 514, 496, 1, 0, 0, 0, 514, 510, 1, 0, 0,
+ 0, 515, 43, 1, 0, 0, 0, 516, 519, 3, 50, 25, 0, 517, 519, 3, 52, 26, 0,
+ 518, 516, 1, 0, 0, 0, 518, 517, 1, 0, 0, 0, 519, 522, 1, 0, 0, 0, 520,
+ 518, 1, 0, 0, 0, 520, 521, 1, 0, 0, 0, 521, 523, 1, 0, 0, 0, 522, 520,
+ 1, 0, 0, 0, 523, 525, 3, 26, 13, 0, 524, 520, 1, 0, 0, 0, 525, 526, 1,
+ 0, 0, 0, 526, 524, 1, 0, 0, 0, 526, 527, 1, 0, 0, 0, 527, 528, 1, 0, 0,
+ 0, 528, 529, 3, 42, 21, 0, 529, 45, 1, 0, 0, 0, 530, 532, 5, 56, 0, 0,
+ 531, 530, 1, 0, 0, 0, 531, 532, 1, 0, 0, 0, 532, 533, 1, 0, 0, 0, 533,
+ 534, 5, 53, 0, 0, 534, 535, 3, 80, 40, 0, 535, 47, 1, 0, 0, 0, 536, 537,
+ 5, 65, 0, 0, 537, 538, 3, 86, 43, 0, 538, 539, 5, 67, 0, 0, 539, 541, 3,
+ 192, 96, 0, 540, 542, 3, 82, 41, 0, 541, 540, 1, 0, 0, 0, 541, 542, 1,
+ 0, 0, 0, 542, 49, 1, 0, 0, 0, 543, 548, 3, 46, 23, 0, 544, 548, 3, 48,
+ 24, 0, 545, 548, 3, 60, 30, 0, 546, 548, 3, 20, 10, 0, 547, 543, 1, 0,
+ 0, 0, 547, 544, 1, 0, 0, 0, 547, 545, 1, 0, 0, 0, 547, 546, 1, 0, 0, 0,
+ 548, 51, 1, 0, 0, 0, 549, 555, 3, 78, 39, 0, 550, 555, 3, 68, 34, 0, 551,
+ 555, 3, 54, 27, 0, 552, 555, 3, 72, 36, 0, 553, 555, 3, 56, 28, 0, 554,
+ 549, 1, 0, 0, 0, 554, 550, 1, 0, 0, 0, 554, 551, 1, 0, 0, 0, 554, 552,
+ 1, 0, 0, 0, 554, 553, 1, 0, 0, 0, 555, 53, 1, 0, 0, 0, 556, 558, 5, 50,
+ 0, 0, 557, 556, 1, 0, 0, 0, 557, 558, 1, 0, 0, 0, 558, 559, 1, 0, 0, 0,
+ 559, 560, 5, 47, 0, 0, 560, 561, 3, 164, 82, 0, 561, 55, 1, 0, 0, 0, 562,
+ 563, 5, 58, 0, 0, 563, 568, 3, 58, 29, 0, 564, 565, 5, 12, 0, 0, 565, 567,
+ 3, 58, 29, 0, 566, 564, 1, 0, 0, 0, 567, 570, 1, 0, 0, 0, 568, 566, 1,
+ 0, 0, 0, 568, 569, 1, 0, 0, 0, 569, 57, 1, 0, 0, 0, 570, 568, 1, 0, 0,
+ 0, 571, 572, 3, 192, 96, 0, 572, 573, 3, 76, 38, 0, 573, 576, 1, 0, 0,
+ 0, 574, 576, 3, 118, 59, 0, 575, 571, 1, 0, 0, 0, 575, 574, 1, 0, 0, 0,
+ 576, 59, 1, 0, 0, 0, 577, 578, 5, 29, 0, 0, 578, 579, 3, 146, 73, 0, 579,
+ 582, 3, 62, 31, 0, 580, 581, 5, 30, 0, 0, 581, 583, 3, 64, 32, 0, 582,
+ 580, 1, 0, 0, 0, 582, 583, 1, 0, 0, 0, 583, 61, 1, 0, 0, 0, 584, 586, 5,
+ 13, 0, 0, 585, 587, 3, 164, 82, 0, 586, 585, 1, 0, 0, 0, 586, 587, 1, 0,
+ 0, 0, 587, 588, 1, 0, 0, 0, 588, 589, 5, 14, 0, 0, 589, 63, 1, 0, 0, 0,
+ 590, 595, 3, 66, 33, 0, 591, 592, 5, 12, 0, 0, 592, 594, 3, 66, 33, 0,
+ 593, 591, 1, 0, 0, 0, 594, 597, 1, 0, 0, 0, 595, 593, 1, 0, 0, 0, 595,
+ 596, 1, 0, 0, 0, 596, 599, 1, 0, 0, 0, 597, 595, 1, 0, 0, 0, 598, 600,
+ 3, 82, 41, 0, 599, 598, 1, 0, 0, 0, 599, 600, 1, 0, 0, 0, 600, 65, 1, 0,
+ 0, 0, 601, 602, 3, 192, 96, 0, 602, 603, 5, 67, 0, 0, 603, 605, 1, 0, 0,
+ 0, 604, 601, 1, 0, 0, 0, 604, 605, 1, 0, 0, 0, 605, 606, 1, 0, 0, 0, 606,
+ 607, 3, 192, 96, 0, 607, 67, 1, 0, 0, 0, 608, 609, 5, 54, 0, 0, 609, 613,
+ 3, 120, 60, 0, 610, 612, 3, 70, 35, 0, 611, 610, 1, 0, 0, 0, 612, 615,
+ 1, 0, 0, 0, 613, 611, 1, 0, 0, 0, 613, 614, 1, 0, 0, 0, 614, 69, 1, 0,
+ 0, 0, 615, 613, 1, 0, 0, 0, 616, 617, 5, 55, 0, 0, 617, 618, 7, 2, 0, 0,
+ 618, 619, 3, 72, 36, 0, 619, 71, 1, 0, 0, 0, 620, 621, 5, 60, 0, 0, 621,
+ 626, 3, 74, 37, 0, 622, 623, 5, 12, 0, 0, 623, 625, 3, 74, 37, 0, 624,
+ 622, 1, 0, 0, 0, 625, 628, 1, 0, 0, 0, 626, 624, 1, 0, 0, 0, 626, 627,
+ 1, 0, 0, 0, 627, 73, 1, 0, 0, 0, 628, 626, 1, 0, 0, 0, 629, 630, 3, 118,
+ 59, 0, 630, 631, 5, 1, 0, 0, 631, 632, 3, 86, 43, 0, 632, 641, 1, 0, 0,
+ 0, 633, 634, 3, 192, 96, 0, 634, 635, 7, 3, 0, 0, 635, 636, 3, 86, 43,
+ 0, 636, 641, 1, 0, 0, 0, 637, 638, 3, 192, 96, 0, 638, 639, 3, 76, 38,
+ 0, 639, 641, 1, 0, 0, 0, 640, 629, 1, 0, 0, 0, 640, 633, 1, 0, 0, 0, 640,
+ 637, 1, 0, 0, 0, 641, 75, 1, 0, 0, 0, 642, 643, 5, 26, 0, 0, 643, 645,
+ 3, 190, 95, 0, 644, 642, 1, 0, 0, 0, 645, 646, 1, 0, 0, 0, 646, 644, 1,
+ 0, 0, 0, 646, 647, 1, 0, 0, 0, 647, 77, 1, 0, 0, 0, 648, 649, 5, 46, 0,
+ 0, 649, 650, 3, 84, 42, 0, 650, 79, 1, 0, 0, 0, 651, 653, 3, 84, 42, 0,
+ 652, 654, 3, 82, 41, 0, 653, 652, 1, 0, 0, 0, 653, 654, 1, 0, 0, 0, 654,
+ 81, 1, 0, 0, 0, 655, 656, 5, 62, 0, 0, 656, 657, 3, 86, 43, 0, 657, 83,
+ 1, 0, 0, 0, 658, 663, 3, 120, 60, 0, 659, 660, 5, 12, 0, 0, 660, 662, 3,
+ 120, 60, 0, 661, 659, 1, 0, 0, 0, 662, 665, 1, 0, 0, 0, 663, 661, 1, 0,
+ 0, 0, 663, 664, 1, 0, 0, 0, 664, 85, 1, 0, 0, 0, 665, 663, 1, 0, 0, 0,
+ 666, 671, 3, 88, 44, 0, 667, 668, 5, 74, 0, 0, 668, 670, 3, 88, 44, 0,
+ 669, 667, 1, 0, 0, 0, 670, 673, 1, 0, 0, 0, 671, 669, 1, 0, 0, 0, 671,
+ 672, 1, 0, 0, 0, 672, 87, 1, 0, 0, 0, 673, 671, 1, 0, 0, 0, 674, 679, 3,
+ 90, 45, 0, 675, 676, 5, 76, 0, 0, 676, 678, 3, 90, 45, 0, 677, 675, 1,
+ 0, 0, 0, 678, 681, 1, 0, 0, 0, 679, 677, 1, 0, 0, 0, 679, 680, 1, 0, 0,
+ 0, 680, 89, 1, 0, 0, 0, 681, 679, 1, 0, 0, 0, 682, 687, 3, 92, 46, 0, 683,
+ 684, 5, 66, 0, 0, 684, 686, 3, 92, 46, 0, 685, 683, 1, 0, 0, 0, 686, 689,
+ 1, 0, 0, 0, 687, 685, 1, 0, 0, 0, 687, 688, 1, 0, 0, 0, 688, 91, 1, 0,
+ 0, 0, 689, 687, 1, 0, 0, 0, 690, 692, 5, 73, 0, 0, 691, 690, 1, 0, 0, 0,
+ 691, 692, 1, 0, 0, 0, 692, 693, 1, 0, 0, 0, 693, 703, 3, 94, 47, 0, 694,
+ 696, 5, 73, 0, 0, 695, 694, 1, 0, 0, 0, 695, 696, 1, 0, 0, 0, 696, 697,
+ 1, 0, 0, 0, 697, 703, 3, 16, 8, 0, 698, 699, 3, 18, 9, 0, 699, 700, 3,
+ 96, 48, 0, 700, 701, 3, 86, 43, 0, 701, 703, 1, 0, 0, 0, 702, 691, 1, 0,
+ 0, 0, 702, 695, 1, 0, 0, 0, 702, 698, 1, 0, 0, 0, 703, 93, 1, 0, 0, 0,
+ 704, 710, 3, 98, 49, 0, 705, 706, 3, 96, 48, 0, 706, 707, 3, 98, 49, 0,
+ 707, 709, 1, 0, 0, 0, 708, 705, 1, 0, 0, 0, 709, 712, 1, 0, 0, 0, 710,
+ 708, 1, 0, 0, 0, 710, 711, 1, 0, 0, 0, 711, 95, 1, 0, 0, 0, 712, 710, 1,
+ 0, 0, 0, 713, 714, 7, 4, 0, 0, 714, 97, 1, 0, 0, 0, 715, 720, 3, 100, 50,
+ 0, 716, 717, 7, 5, 0, 0, 717, 719, 3, 100, 50, 0, 718, 716, 1, 0, 0, 0,
+ 719, 722, 1, 0, 0, 0, 720, 718, 1, 0, 0, 0, 720, 721, 1, 0, 0, 0, 721,
+ 99, 1, 0, 0, 0, 722, 720, 1, 0, 0, 0, 723, 728, 3, 102, 51, 0, 724, 725,
+ 7, 6, 0, 0, 725, 727, 3, 102, 51, 0, 726, 724, 1, 0, 0, 0, 727, 730, 1,
+ 0, 0, 0, 728, 726, 1, 0, 0, 0, 728, 729, 1, 0, 0, 0, 729, 101, 1, 0, 0,
+ 0, 730, 728, 1, 0, 0, 0, 731, 736, 3, 104, 52, 0, 732, 733, 5, 23, 0, 0,
+ 733, 735, 3, 104, 52, 0, 734, 732, 1, 0, 0, 0, 735, 738, 1, 0, 0, 0, 736,
+ 734, 1, 0, 0, 0, 736, 737, 1, 0, 0, 0, 737, 103, 1, 0, 0, 0, 738, 736,
+ 1, 0, 0, 0, 739, 741, 7, 5, 0, 0, 740, 739, 1, 0, 0, 0, 740, 741, 1, 0,
+ 0, 0, 741, 742, 1, 0, 0, 0, 742, 743, 3, 106, 53, 0, 743, 105, 1, 0, 0,
+ 0, 744, 750, 3, 116, 58, 0, 745, 749, 3, 110, 55, 0, 746, 749, 3, 108,
+ 54, 0, 747, 749, 3, 114, 57, 0, 748, 745, 1, 0, 0, 0, 748, 746, 1, 0, 0,
+ 0, 748, 747, 1, 0, 0, 0, 749, 752, 1, 0, 0, 0, 750, 748, 1, 0, 0, 0, 750,
+ 751, 1, 0, 0, 0, 751, 107, 1, 0, 0, 0, 752, 750, 1, 0, 0, 0, 753, 754,
+ 5, 71, 0, 0, 754, 768, 3, 116, 58, 0, 755, 764, 5, 17, 0, 0, 756, 758,
+ 3, 86, 43, 0, 757, 756, 1, 0, 0, 0, 757, 758, 1, 0, 0, 0, 758, 759, 1,
+ 0, 0, 0, 759, 761, 5, 9, 0, 0, 760, 762, 3, 86, 43, 0, 761, 760, 1, 0,
+ 0, 0, 761, 762, 1, 0, 0, 0, 762, 765, 1, 0, 0, 0, 763, 765, 3, 86, 43,
+ 0, 764, 757, 1, 0, 0, 0, 764, 763, 1, 0, 0, 0, 765, 766, 1, 0, 0, 0, 766,
+ 768, 5, 18, 0, 0, 767, 753, 1, 0, 0, 0, 767, 755, 1, 0, 0, 0, 768, 109,
+ 1, 0, 0, 0, 769, 770, 3, 112, 56, 0, 770, 771, 3, 116, 58, 0, 771, 111,
+ 1, 0, 0, 0, 772, 773, 5, 75, 0, 0, 773, 778, 5, 63, 0, 0, 774, 775, 5,
+ 70, 0, 0, 775, 778, 5, 63, 0, 0, 776, 778, 5, 68, 0, 0, 777, 772, 1, 0,
+ 0, 0, 777, 774, 1, 0, 0, 0, 777, 776, 1, 0, 0, 0, 778, 113, 1, 0, 0, 0,
+ 779, 781, 5, 72, 0, 0, 780, 782, 5, 73, 0, 0, 781, 780, 1, 0, 0, 0, 781,
+ 782, 1, 0, 0, 0, 782, 783, 1, 0, 0, 0, 783, 784, 5, 79, 0, 0, 784, 115,
+ 1, 0, 0, 0, 785, 787, 3, 118, 59, 0, 786, 788, 3, 76, 38, 0, 787, 786,
+ 1, 0, 0, 0, 787, 788, 1, 0, 0, 0, 788, 117, 1, 0, 0, 0, 789, 794, 3, 132,
+ 66, 0, 790, 791, 5, 11, 0, 0, 791, 793, 3, 190, 95, 0, 792, 790, 1, 0,
+ 0, 0, 793, 796, 1, 0, 0, 0, 794, 792, 1, 0, 0, 0, 794, 795, 1, 0, 0, 0,
+ 795, 119, 1, 0, 0, 0, 796, 794, 1, 0, 0, 0, 797, 798, 3, 192, 96, 0, 798,
+ 799, 5, 1, 0, 0, 799, 801, 1, 0, 0, 0, 800, 797, 1, 0, 0, 0, 800, 801,
+ 1, 0, 0, 0, 801, 802, 1, 0, 0, 0, 802, 810, 3, 124, 62, 0, 803, 804, 3,
+ 192, 96, 0, 804, 805, 5, 1, 0, 0, 805, 807, 1, 0, 0, 0, 806, 803, 1, 0,
+ 0, 0, 806, 807, 1, 0, 0, 0, 807, 808, 1, 0, 0, 0, 808, 810, 3, 122, 61,
+ 0, 809, 800, 1, 0, 0, 0, 809, 806, 1, 0, 0, 0, 810, 121, 1, 0, 0, 0, 811,
+ 812, 7, 7, 0, 0, 812, 813, 5, 13, 0, 0, 813, 814, 3, 124, 62, 0, 814, 815,
+ 5, 14, 0, 0, 815, 123, 1, 0, 0, 0, 816, 820, 3, 130, 65, 0, 817, 819, 3,
+ 126, 63, 0, 818, 817, 1, 0, 0, 0, 819, 822, 1, 0, 0, 0, 820, 818, 1, 0,
+ 0, 0, 820, 821, 1, 0, 0, 0, 821, 828, 1, 0, 0, 0, 822, 820, 1, 0, 0, 0,
+ 823, 824, 5, 13, 0, 0, 824, 825, 3, 124, 62, 0, 825, 826, 5, 14, 0, 0,
+ 826, 828, 1, 0, 0, 0, 827, 816, 1, 0, 0, 0, 827, 823, 1, 0, 0, 0, 828,
+ 125, 1, 0, 0, 0, 829, 830, 3, 136, 68, 0, 830, 831, 3, 130, 65, 0, 831,
+ 127, 1, 0, 0, 0, 832, 835, 3, 186, 93, 0, 833, 835, 3, 168, 84, 0, 834,
+ 832, 1, 0, 0, 0, 834, 833, 1, 0, 0, 0, 835, 129, 1, 0, 0, 0, 836, 838,
+ 5, 13, 0, 0, 837, 839, 3, 192, 96, 0, 838, 837, 1, 0, 0, 0, 838, 839, 1,
+ 0, 0, 0, 839, 841, 1, 0, 0, 0, 840, 842, 3, 76, 38, 0, 841, 840, 1, 0,
+ 0, 0, 841, 842, 1, 0, 0, 0, 842, 844, 1, 0, 0, 0, 843, 845, 3, 128, 64,
+ 0, 844, 843, 1, 0, 0, 0, 844, 845, 1, 0, 0, 0, 845, 846, 1, 0, 0, 0, 846,
+ 847, 5, 14, 0, 0, 847, 131, 1, 0, 0, 0, 848, 861, 3, 170, 85, 0, 849, 861,
+ 3, 168, 84, 0, 850, 861, 3, 166, 83, 0, 851, 861, 3, 162, 81, 0, 852, 861,
+ 3, 158, 79, 0, 853, 861, 3, 154, 77, 0, 854, 861, 3, 152, 76, 0, 855, 861,
+ 3, 156, 78, 0, 856, 861, 3, 150, 75, 0, 857, 861, 3, 148, 74, 0, 858, 861,
+ 3, 192, 96, 0, 859, 861, 3, 144, 72, 0, 860, 848, 1, 0, 0, 0, 860, 849,
+ 1, 0, 0, 0, 860, 850, 1, 0, 0, 0, 860, 851, 1, 0, 0, 0, 860, 852, 1, 0,
+ 0, 0, 860, 853, 1, 0, 0, 0, 860, 854, 1, 0, 0, 0, 860, 855, 1, 0, 0, 0,
+ 860, 856, 1, 0, 0, 0, 860, 857, 1, 0, 0, 0, 860, 858, 1, 0, 0, 0, 860,
+ 859, 1, 0, 0, 0, 861, 133, 1, 0, 0, 0, 862, 863, 3, 192, 96, 0, 863, 864,
+ 5, 1, 0, 0, 864, 135, 1, 0, 0, 0, 865, 866, 5, 6, 0, 0, 866, 868, 5, 19,
+ 0, 0, 867, 869, 3, 138, 69, 0, 868, 867, 1, 0, 0, 0, 868, 869, 1, 0, 0,
+ 0, 869, 870, 1, 0, 0, 0, 870, 872, 5, 19, 0, 0, 871, 873, 5, 5, 0, 0, 872,
+ 871, 1, 0, 0, 0, 872, 873, 1, 0, 0, 0, 873, 883, 1, 0, 0, 0, 874, 876,
+ 5, 19, 0, 0, 875, 877, 3, 138, 69, 0, 876, 875, 1, 0, 0, 0, 876, 877, 1,
+ 0, 0, 0, 877, 878, 1, 0, 0, 0, 878, 880, 5, 19, 0, 0, 879, 881, 5, 5, 0,
+ 0, 880, 879, 1, 0, 0, 0, 880, 881, 1, 0, 0, 0, 881, 883, 1, 0, 0, 0, 882,
+ 865, 1, 0, 0, 0, 882, 874, 1, 0, 0, 0, 883, 137, 1, 0, 0, 0, 884, 886,
+ 5, 17, 0, 0, 885, 887, 3, 192, 96, 0, 886, 885, 1, 0, 0, 0, 886, 887, 1,
+ 0, 0, 0, 887, 889, 1, 0, 0, 0, 888, 890, 3, 140, 70, 0, 889, 888, 1, 0,
+ 0, 0, 889, 890, 1, 0, 0, 0, 890, 892, 1, 0, 0, 0, 891, 893, 3, 172, 86,
+ 0, 892, 891, 1, 0, 0, 0, 892, 893, 1, 0, 0, 0, 893, 895, 1, 0, 0, 0, 894,
+ 896, 3, 128, 64, 0, 895, 894, 1, 0, 0, 0, 895, 896, 1, 0, 0, 0, 896, 897,
+ 1, 0, 0, 0, 897, 898, 5, 18, 0, 0, 898, 139, 1, 0, 0, 0, 899, 900, 5, 26,
+ 0, 0, 900, 908, 3, 190, 95, 0, 901, 903, 5, 27, 0, 0, 902, 904, 5, 26,
+ 0, 0, 903, 902, 1, 0, 0, 0, 903, 904, 1, 0, 0, 0, 904, 905, 1, 0, 0, 0,
+ 905, 907, 3, 190, 95, 0, 906, 901, 1, 0, 0, 0, 907, 910, 1, 0, 0, 0, 908,
+ 906, 1, 0, 0, 0, 908, 909, 1, 0, 0, 0, 909, 141, 1, 0, 0, 0, 910, 908,
+ 1, 0, 0, 0, 911, 913, 5, 64, 0, 0, 912, 914, 5, 42, 0, 0, 913, 912, 1,
+ 0, 0, 0, 913, 914, 1, 0, 0, 0, 914, 915, 1, 0, 0, 0, 915, 916, 3, 12, 6,
+ 0, 916, 143, 1, 0, 0, 0, 917, 918, 5, 51, 0, 0, 918, 921, 5, 15, 0, 0,
+ 919, 922, 3, 10, 5, 0, 920, 922, 3, 80, 40, 0, 921, 919, 1, 0, 0, 0, 921,
+ 920, 1, 0, 0, 0, 922, 923, 1, 0, 0, 0, 923, 924, 5, 16, 0, 0, 924, 145,
+ 1, 0, 0, 0, 925, 930, 3, 192, 96, 0, 926, 927, 5, 11, 0, 0, 927, 929, 3,
+ 192, 96, 0, 928, 926, 1, 0, 0, 0, 929, 932, 1, 0, 0, 0, 930, 928, 1, 0,
+ 0, 0, 930, 931, 1, 0, 0, 0, 931, 147, 1, 0, 0, 0, 932, 930, 1, 0, 0, 0,
+ 933, 934, 3, 146, 73, 0, 934, 936, 5, 13, 0, 0, 935, 937, 5, 69, 0, 0,
+ 936, 935, 1, 0, 0, 0, 936, 937, 1, 0, 0, 0, 937, 939, 1, 0, 0, 0, 938,
+ 940, 3, 164, 82, 0, 939, 938, 1, 0, 0, 0, 939, 940, 1, 0, 0, 0, 940, 941,
+ 1, 0, 0, 0, 941, 942, 5, 14, 0, 0, 942, 149, 1, 0, 0, 0, 943, 944, 5, 13,
+ 0, 0, 944, 945, 3, 86, 43, 0, 945, 946, 5, 14, 0, 0, 946, 151, 1, 0, 0,
+ 0, 947, 948, 7, 8, 0, 0, 948, 949, 5, 13, 0, 0, 949, 950, 3, 160, 80, 0,
+ 950, 951, 5, 14, 0, 0, 951, 153, 1, 0, 0, 0, 952, 954, 5, 17, 0, 0, 953,
+ 955, 3, 134, 67, 0, 954, 953, 1, 0, 0, 0, 954, 955, 1, 0, 0, 0, 955, 956,
+ 1, 0, 0, 0, 956, 958, 3, 156, 78, 0, 957, 959, 3, 82, 41, 0, 958, 957,
+ 1, 0, 0, 0, 958, 959, 1, 0, 0, 0, 959, 960, 1, 0, 0, 0, 960, 961, 5, 27,
+ 0, 0, 961, 962, 3, 86, 43, 0, 962, 963, 5, 18, 0, 0, 963, 155, 1, 0, 0,
+ 0, 964, 966, 3, 130, 65, 0, 965, 967, 3, 126, 63, 0, 966, 965, 1, 0, 0,
+ 0, 967, 968, 1, 0, 0, 0, 968, 966, 1, 0, 0, 0, 968, 969, 1, 0, 0, 0, 969,
+ 157, 1, 0, 0, 0, 970, 971, 5, 17, 0, 0, 971, 974, 3, 160, 80, 0, 972, 973,
+ 5, 27, 0, 0, 973, 975, 3, 86, 43, 0, 974, 972, 1, 0, 0, 0, 974, 975, 1,
+ 0, 0, 0, 975, 976, 1, 0, 0, 0, 976, 977, 5, 18, 0, 0, 977, 159, 1, 0, 0,
+ 0, 978, 979, 3, 192, 96, 0, 979, 980, 5, 71, 0, 0, 980, 982, 3, 86, 43,
+ 0, 981, 983, 3, 82, 41, 0, 982, 981, 1, 0, 0, 0, 982, 983, 1, 0, 0, 0,
+ 983, 161, 1, 0, 0, 0, 984, 985, 5, 33, 0, 0, 985, 986, 5, 13, 0, 0, 986,
+ 987, 5, 24, 0, 0, 987, 988, 5, 14, 0, 0, 988, 163, 1, 0, 0, 0, 989, 994,
+ 3, 86, 43, 0, 990, 991, 5, 12, 0, 0, 991, 993, 3, 86, 43, 0, 992, 990,
+ 1, 0, 0, 0, 993, 996, 1, 0, 0, 0, 994, 992, 1, 0, 0, 0, 994, 995, 1, 0,
+ 0, 0, 995, 165, 1, 0, 0, 0, 996, 994, 1, 0, 0, 0, 997, 999, 5, 85, 0, 0,
+ 998, 1000, 3, 86, 43, 0, 999, 998, 1, 0, 0, 0, 999, 1000, 1, 0, 0, 0, 1000,
+ 1006, 1, 0, 0, 0, 1001, 1002, 5, 86, 0, 0, 1002, 1003, 3, 86, 43, 0, 1003,
+ 1004, 5, 87, 0, 0, 1004, 1005, 3, 86, 43, 0, 1005, 1007, 1, 0, 0, 0, 1006,
+ 1001, 1, 0, 0, 0, 1007, 1008, 1, 0, 0, 0, 1008, 1006, 1, 0, 0, 0, 1008,
+ 1009, 1, 0, 0, 0, 1009, 1012, 1, 0, 0, 0, 1010, 1011, 5, 88, 0, 0, 1011,
+ 1013, 3, 86, 43, 0, 1012, 1010, 1, 0, 0, 0, 1012, 1013, 1, 0, 0, 0, 1013,
+ 1014, 1, 0, 0, 0, 1014, 1015, 5, 89, 0, 0, 1015, 167, 1, 0, 0, 0, 1016,
+ 1019, 5, 28, 0, 0, 1017, 1020, 3, 192, 96, 0, 1018, 1020, 3, 178, 89, 0,
+ 1019, 1017, 1, 0, 0, 0, 1019, 1018, 1, 0, 0, 0, 1020, 169, 1, 0, 0, 0,
+ 1021, 1029, 3, 174, 87, 0, 1022, 1029, 3, 178, 89, 0, 1023, 1029, 5, 79,
+ 0, 0, 1024, 1029, 3, 180, 90, 0, 1025, 1029, 3, 182, 91, 0, 1026, 1029,
+ 3, 184, 92, 0, 1027, 1029, 3, 186, 93, 0, 1028, 1021, 1, 0, 0, 0, 1028,
+ 1022, 1, 0, 0, 0, 1028, 1023, 1, 0, 0, 0, 1028, 1024, 1, 0, 0, 0, 1028,
+ 1025, 1, 0, 0, 0, 1028, 1026, 1, 0, 0, 0, 1028, 1027, 1, 0, 0, 0, 1029,
+ 171, 1, 0, 0, 0, 1030, 1032, 5, 24, 0, 0, 1031, 1033, 3, 176, 88, 0, 1032,
+ 1031, 1, 0, 0, 0, 1032, 1033, 1, 0, 0, 0, 1033, 1038, 1, 0, 0, 0, 1034,
+ 1036, 5, 9, 0, 0, 1035, 1037, 3, 176, 88, 0, 1036, 1035, 1, 0, 0, 0, 1036,
+ 1037, 1, 0, 0, 0, 1037, 1039, 1, 0, 0, 0, 1038, 1034, 1, 0, 0, 0, 1038,
+ 1039, 1, 0, 0, 0, 1039, 173, 1, 0, 0, 0, 1040, 1041, 7, 9, 0, 0, 1041,
+ 175, 1, 0, 0, 0, 1042, 1043, 7, 10, 0, 0, 1043, 177, 1, 0, 0, 0, 1044,
+ 1047, 5, 117, 0, 0, 1045, 1047, 3, 176, 88, 0, 1046, 1044, 1, 0, 0, 0,
+ 1046, 1045, 1, 0, 0, 0, 1047, 179, 1, 0, 0, 0, 1048, 1049, 5, 123, 0, 0,
+ 1049, 181, 1, 0, 0, 0, 1050, 1051, 5, 122, 0, 0, 1051, 183, 1, 0, 0, 0,
+ 1052, 1054, 5, 17, 0, 0, 1053, 1055, 3, 164, 82, 0, 1054, 1053, 1, 0, 0,
+ 0, 1054, 1055, 1, 0, 0, 0, 1055, 1056, 1, 0, 0, 0, 1056, 1057, 5, 18, 0,
+ 0, 1057, 185, 1, 0, 0, 0, 1058, 1067, 5, 15, 0, 0, 1059, 1064, 3, 188,
+ 94, 0, 1060, 1061, 5, 12, 0, 0, 1061, 1063, 3, 188, 94, 0, 1062, 1060,
+ 1, 0, 0, 0, 1063, 1066, 1, 0, 0, 0, 1064, 1062, 1, 0, 0, 0, 1064, 1065,
+ 1, 0, 0, 0, 1065, 1068, 1, 0, 0, 0, 1066, 1064, 1, 0, 0, 0, 1067, 1059,
+ 1, 0, 0, 0, 1067, 1068, 1, 0, 0, 0, 1068, 1069, 1, 0, 0, 0, 1069, 1070,
+ 5, 16, 0, 0, 1070, 187, 1, 0, 0, 0, 1071, 1072, 3, 190, 95, 0, 1072, 1073,
+ 5, 26, 0, 0, 1073, 1074, 3, 86, 43, 0, 1074, 189, 1, 0, 0, 0, 1075, 1078,
+ 3, 192, 96, 0, 1076, 1078, 3, 194, 97, 0, 1077, 1075, 1, 0, 0, 0, 1077,
+ 1076, 1, 0, 0, 0, 1078, 191, 1, 0, 0, 0, 1079, 1080, 7, 11, 0, 0, 1080,
+ 193, 1, 0, 0, 0, 1081, 1082, 7, 12, 0, 0, 1082, 195, 1, 0, 0, 0, 151, 201,
+ 205, 210, 216, 230, 232, 237, 241, 246, 251, 255, 258, 261, 267, 272, 276,
+ 279, 282, 292, 297, 301, 304, 307, 311, 316, 320, 325, 330, 334, 343, 348,
+ 353, 356, 359, 364, 372, 374, 380, 385, 390, 395, 397, 419, 421, 424, 428,
+ 430, 434, 442, 451, 455, 458, 461, 465, 471, 477, 481, 490, 496, 503, 506,
+ 508, 512, 514, 518, 520, 526, 531, 541, 547, 554, 557, 568, 575, 582, 586,
+ 595, 599, 604, 613, 626, 640, 646, 653, 663, 671, 679, 687, 691, 695, 702,
+ 710, 720, 728, 736, 740, 748, 750, 757, 761, 764, 767, 777, 781, 787, 794,
+ 800, 806, 809, 820, 827, 834, 838, 841, 844, 860, 868, 872, 876, 880, 882,
+ 886, 889, 892, 895, 903, 908, 913, 921, 930, 936, 939, 954, 958, 968, 974,
+ 982, 994, 999, 1008, 1012, 1019, 1028, 1032, 1036, 1038, 1046, 1054, 1064,
+ 1067, 1077,
+ }
+ deserializer := antlr.NewATNDeserializer(nil)
+ staticData.atn = deserializer.Deserialize(staticData.serializedATN)
+ atn := staticData.atn
+ staticData.decisionToDFA = make([]*antlr.DFA, len(atn.DecisionToState))
+ decisionToDFA := staticData.decisionToDFA
+ for index, state := range atn.DecisionToState {
+ decisionToDFA[index] = antlr.NewDFA(state, index)
+ }
+}
+
+// CypherParserInit initializes any static state used to implement CypherParser. By default the
+// static state used to implement the parser is lazily initialized during the first call to
+// NewCypherParser(). You can call this function if you wish to initialize the static state ahead
+// of time.
+func CypherParserInit() {
+ staticData := &CypherParserParserStaticData
+ staticData.once.Do(cypherparserParserInit)
+}
+
+// NewCypherParser produces a new parser instance for the optional input antlr.TokenStream.
+func NewCypherParser(input antlr.TokenStream) *CypherParser {
+ CypherParserInit()
+ this := new(CypherParser)
+ this.BaseParser = antlr.NewBaseParser(input)
+ staticData := &CypherParserParserStaticData
+ this.Interpreter = antlr.NewParserATNSimulator(this, staticData.atn, staticData.decisionToDFA, staticData.PredictionContextCache)
+ this.RuleNames = staticData.RuleNames
+ this.LiteralNames = staticData.LiteralNames
+ this.SymbolicNames = staticData.SymbolicNames
+ this.GrammarFileName = "CypherParser.g4"
+
+ return this
+}
+
+// CypherParser tokens.
+const (
+ CypherParserEOF = antlr.TokenEOF
+ CypherParserASSIGN = 1
+ CypherParserADD_ASSIGN = 2
+ CypherParserLE = 3
+ CypherParserGE = 4
+ CypherParserGT = 5
+ CypherParserLT = 6
+ CypherParserNOT_EQUAL = 7
+ CypherParserREGEX_MATCH = 8
+ CypherParserRANGE = 9
+ CypherParserSEMI = 10
+ CypherParserDOT = 11
+ CypherParserCOMMA = 12
+ CypherParserLPAREN = 13
+ CypherParserRPAREN = 14
+ CypherParserLBRACE = 15
+ CypherParserRBRACE = 16
+ CypherParserLBRACK = 17
+ CypherParserRBRACK = 18
+ CypherParserSUB = 19
+ CypherParserPLUS = 20
+ CypherParserDIV = 21
+ CypherParserMOD = 22
+ CypherParserCARET = 23
+ CypherParserMULT = 24
+ CypherParserESC = 25
+ CypherParserCOLON = 26
+ CypherParserSTICK = 27
+ CypherParserDOLLAR = 28
+ CypherParserCALL = 29
+ CypherParserYIELD = 30
+ CypherParserFILTER = 31
+ CypherParserEXTRACT = 32
+ CypherParserCOUNT = 33
+ CypherParserSUM = 34
+ CypherParserAVG = 35
+ CypherParserMIN = 36
+ CypherParserMAX = 37
+ CypherParserCOLLECT = 38
+ CypherParserANY = 39
+ CypherParserNONE = 40
+ CypherParserSINGLE = 41
+ CypherParserALL = 42
+ CypherParserASC = 43
+ CypherParserASCENDING = 44
+ CypherParserBY = 45
+ CypherParserCREATE = 46
+ CypherParserDELETE = 47
+ CypherParserDESC = 48
+ CypherParserDESCENDING = 49
+ CypherParserDETACH = 50
+ CypherParserEXISTS = 51
+ CypherParserLIMIT = 52
+ CypherParserMATCH = 53
+ CypherParserMERGE = 54
+ CypherParserON = 55
+ CypherParserOPTIONAL = 56
+ CypherParserORDER = 57
+ CypherParserREMOVE = 58
+ CypherParserRETURN = 59
+ CypherParserSET = 60
+ CypherParserSKIP_W = 61
+ CypherParserWHERE = 62
+ CypherParserWITH = 63
+ CypherParserUNION = 64
+ CypherParserUNWIND = 65
+ CypherParserAND = 66
+ CypherParserAS = 67
+ CypherParserCONTAINS = 68
+ CypherParserDISTINCT = 69
+ CypherParserENDS = 70
+ CypherParserIN = 71
+ CypherParserIS = 72
+ CypherParserNOT = 73
+ CypherParserOR = 74
+ CypherParserSTARTS = 75
+ CypherParserXOR = 76
+ CypherParserFALSE = 77
+ CypherParserTRUE = 78
+ CypherParserNULL_W = 79
+ CypherParserCONSTRAINT = 80
+ CypherParserDO = 81
+ CypherParserFOR = 82
+ CypherParserREQUIRE = 83
+ CypherParserUNIQUE = 84
+ CypherParserCASE = 85
+ CypherParserWHEN = 86
+ CypherParserTHEN = 87
+ CypherParserELSE = 88
+ CypherParserEND = 89
+ CypherParserMANDATORY = 90
+ CypherParserSCALAR = 91
+ CypherParserOF = 92
+ CypherParserADD = 93
+ CypherParserDROP = 94
+ CypherParserINDEX = 95
+ CypherParserINDEXES = 96
+ CypherParserVECTOR = 97
+ CypherParserEXPLAIN = 98
+ CypherParserPROFILE = 99
+ CypherParserSHOW = 100
+ CypherParserCONSTRAINTS = 101
+ CypherParserPROCEDURES = 102
+ CypherParserFUNCTIONS = 103
+ CypherParserDATABASE = 104
+ CypherParserDATABASES = 105
+ CypherParserFULLTEXT = 106
+ CypherParserOPTIONS = 107
+ CypherParserEACH = 108
+ CypherParserIF = 109
+ CypherParserTRANSACTIONS = 110
+ CypherParserROWS = 111
+ CypherParserASSERT = 112
+ CypherParserKEY = 113
+ CypherParserNODE = 114
+ CypherParserSHORTESTPATH = 115
+ CypherParserALLSHORTESTPATHS = 116
+ CypherParserFLOAT = 117
+ CypherParserINTEGER = 118
+ CypherParserDIGIT = 119
+ CypherParserID = 120
+ CypherParserESC_LITERAL = 121
+ CypherParserCHAR_LITERAL = 122
+ CypherParserSTRING_LITERAL = 123
+ CypherParserWS = 124
+ CypherParserCOMMENT = 125
+ CypherParserLINE_COMMENT = 126
+ CypherParserERRCHAR = 127
+ CypherParserLetter = 128
+)
+
+// CypherParser rules.
+const (
+ CypherParserRULE_script = 0
+ CypherParserRULE_query = 1
+ CypherParserRULE_queryPrefix = 2
+ CypherParserRULE_showCommand = 3
+ CypherParserRULE_schemaCommand = 4
+ CypherParserRULE_regularQuery = 5
+ CypherParserRULE_singleQuery = 6
+ CypherParserRULE_standaloneCall = 7
+ CypherParserRULE_existsSubquery = 8
+ CypherParserRULE_countSubquery = 9
+ CypherParserRULE_callSubquery = 10
+ CypherParserRULE_subqueryBody = 11
+ CypherParserRULE_returnSt = 12
+ CypherParserRULE_withSt = 13
+ CypherParserRULE_skipSt = 14
+ CypherParserRULE_limitSt = 15
+ CypherParserRULE_projectionBody = 16
+ CypherParserRULE_projectionItems = 17
+ CypherParserRULE_projectionItem = 18
+ CypherParserRULE_orderItem = 19
+ CypherParserRULE_orderSt = 20
+ CypherParserRULE_singlePartQ = 21
+ CypherParserRULE_multiPartQ = 22
+ CypherParserRULE_matchSt = 23
+ CypherParserRULE_unwindSt = 24
+ CypherParserRULE_readingStatement = 25
+ CypherParserRULE_updatingStatement = 26
+ CypherParserRULE_deleteSt = 27
+ CypherParserRULE_removeSt = 28
+ CypherParserRULE_removeItem = 29
+ CypherParserRULE_queryCallSt = 30
+ CypherParserRULE_parenExpressionChain = 31
+ CypherParserRULE_yieldItems = 32
+ CypherParserRULE_yieldItem = 33
+ CypherParserRULE_mergeSt = 34
+ CypherParserRULE_mergeAction = 35
+ CypherParserRULE_setSt = 36
+ CypherParserRULE_setItem = 37
+ CypherParserRULE_nodeLabels = 38
+ CypherParserRULE_createSt = 39
+ CypherParserRULE_patternWhere = 40
+ CypherParserRULE_where = 41
+ CypherParserRULE_pattern = 42
+ CypherParserRULE_expression = 43
+ CypherParserRULE_xorExpression = 44
+ CypherParserRULE_andExpression = 45
+ CypherParserRULE_notExpression = 46
+ CypherParserRULE_comparisonExpression = 47
+ CypherParserRULE_comparisonSigns = 48
+ CypherParserRULE_addSubExpression = 49
+ CypherParserRULE_multDivExpression = 50
+ CypherParserRULE_powerExpression = 51
+ CypherParserRULE_unaryAddSubExpression = 52
+ CypherParserRULE_atomicExpression = 53
+ CypherParserRULE_listExpression = 54
+ CypherParserRULE_stringExpression = 55
+ CypherParserRULE_stringExpPrefix = 56
+ CypherParserRULE_nullExpression = 57
+ CypherParserRULE_propertyOrLabelExpression = 58
+ CypherParserRULE_propertyExpression = 59
+ CypherParserRULE_patternPart = 60
+ CypherParserRULE_pathFunction = 61
+ CypherParserRULE_patternElem = 62
+ CypherParserRULE_patternElemChain = 63
+ CypherParserRULE_properties = 64
+ CypherParserRULE_nodePattern = 65
+ CypherParserRULE_atom = 66
+ CypherParserRULE_lhs = 67
+ CypherParserRULE_relationshipPattern = 68
+ CypherParserRULE_relationDetail = 69
+ CypherParserRULE_relationshipTypes = 70
+ CypherParserRULE_unionSt = 71
+ CypherParserRULE_subqueryExist = 72
+ CypherParserRULE_invocationName = 73
+ CypherParserRULE_functionInvocation = 74
+ CypherParserRULE_parenthesizedExpression = 75
+ CypherParserRULE_filterWith = 76
+ CypherParserRULE_patternComprehension = 77
+ CypherParserRULE_relationshipsChainPattern = 78
+ CypherParserRULE_listComprehension = 79
+ CypherParserRULE_filterExpression = 80
+ CypherParserRULE_countAll = 81
+ CypherParserRULE_expressionChain = 82
+ CypherParserRULE_caseExpression = 83
+ CypherParserRULE_parameter = 84
+ CypherParserRULE_literal = 85
+ CypherParserRULE_rangeLit = 86
+ CypherParserRULE_boolLit = 87
+ CypherParserRULE_integerLit = 88
+ CypherParserRULE_numLit = 89
+ CypherParserRULE_stringLit = 90
+ CypherParserRULE_charLit = 91
+ CypherParserRULE_listLit = 92
+ CypherParserRULE_mapLit = 93
+ CypherParserRULE_mapPair = 94
+ CypherParserRULE_name = 95
+ CypherParserRULE_symbol = 96
+ CypherParserRULE_reservedWord = 97
+)
+
+// IScriptContext is an interface to support dynamic dispatch.
+type IScriptContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ AllQuery() []IQueryContext
+ Query(i int) IQueryContext
+ EOF() antlr.TerminalNode
+ AllSEMI() []antlr.TerminalNode
+ SEMI(i int) antlr.TerminalNode
+
+ // IsScriptContext differentiates from other interfaces.
+ IsScriptContext()
+}
+
+type ScriptContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyScriptContext() *ScriptContext {
+ var p = new(ScriptContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_script
+ return p
+}
+
+func InitEmptyScriptContext(p *ScriptContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_script
+}
+
+func (*ScriptContext) IsScriptContext() {}
+
+func NewScriptContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ScriptContext {
+ var p = new(ScriptContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_script
+
+ return p
+}
+
+func (s *ScriptContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *ScriptContext) AllQuery() []IQueryContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IQueryContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IQueryContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IQueryContext); ok {
+ tst[i] = t.(IQueryContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *ScriptContext) Query(i int) IQueryContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IQueryContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IQueryContext)
+}
+
+func (s *ScriptContext) EOF() antlr.TerminalNode {
+ return s.GetToken(CypherParserEOF, 0)
+}
+
+func (s *ScriptContext) AllSEMI() []antlr.TerminalNode {
+ return s.GetTokens(CypherParserSEMI)
+}
+
+func (s *ScriptContext) SEMI(i int) antlr.TerminalNode {
+ return s.GetToken(CypherParserSEMI, i)
+}
+
+func (s *ScriptContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *ScriptContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *ScriptContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterScript(s)
+ }
+}
+
+func (s *ScriptContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitScript(s)
+ }
+}
+
+func (p *CypherParser) Script() (localctx IScriptContext) {
+ localctx = NewScriptContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 0, CypherParserRULE_script)
+ var _la int
+
+ var _alt int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(196)
+ p.Query()
+ }
+ p.SetState(201)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 0, p.GetParserRuleContext())
+ if p.HasError() {
+ goto errorExit
+ }
+ for _alt != 2 && _alt != antlr.ATNInvalidAltNumber {
+ if _alt == 1 {
+ {
+ p.SetState(197)
+ p.Match(CypherParserSEMI)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(198)
+ p.Query()
+ }
+
+ }
+ p.SetState(203)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 0, p.GetParserRuleContext())
+ if p.HasError() {
+ goto errorExit
+ }
+ }
+ p.SetState(205)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserSEMI {
+ {
+ p.SetState(204)
+ p.Match(CypherParserSEMI)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ }
+ {
+ p.SetState(207)
+ p.Match(CypherParserEOF)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IQueryContext is an interface to support dynamic dispatch.
+type IQueryContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ RegularQuery() IRegularQueryContext
+ StandaloneCall() IStandaloneCallContext
+ SchemaCommand() ISchemaCommandContext
+ ShowCommand() IShowCommandContext
+ QueryPrefix() IQueryPrefixContext
+
+ // IsQueryContext differentiates from other interfaces.
+ IsQueryContext()
+}
+
+type QueryContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyQueryContext() *QueryContext {
+ var p = new(QueryContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_query
+ return p
+}
+
+func InitEmptyQueryContext(p *QueryContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_query
+}
+
+func (*QueryContext) IsQueryContext() {}
+
+func NewQueryContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *QueryContext {
+ var p = new(QueryContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_query
+
+ return p
+}
+
+func (s *QueryContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *QueryContext) RegularQuery() IRegularQueryContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IRegularQueryContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IRegularQueryContext)
+}
+
+func (s *QueryContext) StandaloneCall() IStandaloneCallContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IStandaloneCallContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IStandaloneCallContext)
+}
+
+func (s *QueryContext) SchemaCommand() ISchemaCommandContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ISchemaCommandContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ISchemaCommandContext)
+}
+
+func (s *QueryContext) ShowCommand() IShowCommandContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IShowCommandContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IShowCommandContext)
+}
+
+func (s *QueryContext) QueryPrefix() IQueryPrefixContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IQueryPrefixContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IQueryPrefixContext)
+}
+
+func (s *QueryContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *QueryContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *QueryContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterQuery(s)
+ }
+}
+
+func (s *QueryContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitQuery(s)
+ }
+}
+
+func (p *CypherParser) Query() (localctx IQueryContext) {
+ localctx = NewQueryContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 2, CypherParserRULE_query)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ p.SetState(210)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserEXPLAIN || _la == CypherParserPROFILE {
+ {
+ p.SetState(209)
+ p.QueryPrefix()
+ }
+
+ }
+ p.SetState(216)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 3, p.GetParserRuleContext()) {
+ case 1:
+ {
+ p.SetState(212)
+ p.RegularQuery()
+ }
+
+ case 2:
+ {
+ p.SetState(213)
+ p.StandaloneCall()
+ }
+
+ case 3:
+ {
+ p.SetState(214)
+ p.SchemaCommand()
+ }
+
+ case 4:
+ {
+ p.SetState(215)
+ p.ShowCommand()
+ }
+
+ case antlr.ATNInvalidAltNumber:
+ goto errorExit
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IQueryPrefixContext is an interface to support dynamic dispatch.
+type IQueryPrefixContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ EXPLAIN() antlr.TerminalNode
+ PROFILE() antlr.TerminalNode
+
+ // IsQueryPrefixContext differentiates from other interfaces.
+ IsQueryPrefixContext()
+}
+
+type QueryPrefixContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyQueryPrefixContext() *QueryPrefixContext {
+ var p = new(QueryPrefixContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_queryPrefix
+ return p
+}
+
+func InitEmptyQueryPrefixContext(p *QueryPrefixContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_queryPrefix
+}
+
+func (*QueryPrefixContext) IsQueryPrefixContext() {}
+
+func NewQueryPrefixContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *QueryPrefixContext {
+ var p = new(QueryPrefixContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_queryPrefix
+
+ return p
+}
+
+func (s *QueryPrefixContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *QueryPrefixContext) EXPLAIN() antlr.TerminalNode {
+ return s.GetToken(CypherParserEXPLAIN, 0)
+}
+
+func (s *QueryPrefixContext) PROFILE() antlr.TerminalNode {
+ return s.GetToken(CypherParserPROFILE, 0)
+}
+
+func (s *QueryPrefixContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *QueryPrefixContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *QueryPrefixContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterQueryPrefix(s)
+ }
+}
+
+func (s *QueryPrefixContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitQueryPrefix(s)
+ }
+}
+
+func (p *CypherParser) QueryPrefix() (localctx IQueryPrefixContext) {
+ localctx = NewQueryPrefixContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 4, CypherParserRULE_queryPrefix)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(218)
+ _la = p.GetTokenStream().LA(1)
+
+ if !(_la == CypherParserEXPLAIN || _la == CypherParserPROFILE) {
+ p.GetErrorHandler().RecoverInline(p)
+ } else {
+ p.GetErrorHandler().ReportMatch(p)
+ p.Consume()
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IShowCommandContext is an interface to support dynamic dispatch.
+type IShowCommandContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ SHOW() antlr.TerminalNode
+ INDEXES() antlr.TerminalNode
+ INDEX() antlr.TerminalNode
+ CONSTRAINTS() antlr.TerminalNode
+ CONSTRAINT() antlr.TerminalNode
+ PROCEDURES() antlr.TerminalNode
+ FUNCTIONS() antlr.TerminalNode
+ DATABASE() antlr.TerminalNode
+ DATABASES() antlr.TerminalNode
+ ALL() antlr.TerminalNode
+
+ // IsShowCommandContext differentiates from other interfaces.
+ IsShowCommandContext()
+}
+
+type ShowCommandContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyShowCommandContext() *ShowCommandContext {
+ var p = new(ShowCommandContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_showCommand
+ return p
+}
+
+func InitEmptyShowCommandContext(p *ShowCommandContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_showCommand
+}
+
+func (*ShowCommandContext) IsShowCommandContext() {}
+
+func NewShowCommandContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ShowCommandContext {
+ var p = new(ShowCommandContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_showCommand
+
+ return p
+}
+
+func (s *ShowCommandContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *ShowCommandContext) SHOW() antlr.TerminalNode {
+ return s.GetToken(CypherParserSHOW, 0)
+}
+
+func (s *ShowCommandContext) INDEXES() antlr.TerminalNode {
+ return s.GetToken(CypherParserINDEXES, 0)
+}
+
+func (s *ShowCommandContext) INDEX() antlr.TerminalNode {
+ return s.GetToken(CypherParserINDEX, 0)
+}
+
+func (s *ShowCommandContext) CONSTRAINTS() antlr.TerminalNode {
+ return s.GetToken(CypherParserCONSTRAINTS, 0)
+}
+
+func (s *ShowCommandContext) CONSTRAINT() antlr.TerminalNode {
+ return s.GetToken(CypherParserCONSTRAINT, 0)
+}
+
+func (s *ShowCommandContext) PROCEDURES() antlr.TerminalNode {
+ return s.GetToken(CypherParserPROCEDURES, 0)
+}
+
+func (s *ShowCommandContext) FUNCTIONS() antlr.TerminalNode {
+ return s.GetToken(CypherParserFUNCTIONS, 0)
+}
+
+func (s *ShowCommandContext) DATABASE() antlr.TerminalNode {
+ return s.GetToken(CypherParserDATABASE, 0)
+}
+
+func (s *ShowCommandContext) DATABASES() antlr.TerminalNode {
+ return s.GetToken(CypherParserDATABASES, 0)
+}
+
+func (s *ShowCommandContext) ALL() antlr.TerminalNode {
+ return s.GetToken(CypherParserALL, 0)
+}
+
+func (s *ShowCommandContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *ShowCommandContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *ShowCommandContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterShowCommand(s)
+ }
+}
+
+func (s *ShowCommandContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitShowCommand(s)
+ }
+}
+
+func (p *CypherParser) ShowCommand() (localctx IShowCommandContext) {
+ localctx = NewShowCommandContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 6, CypherParserRULE_showCommand)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(220)
+ p.Match(CypherParserSHOW)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(232)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetTokenStream().LA(1) {
+ case CypherParserINDEXES:
+ {
+ p.SetState(221)
+ p.Match(CypherParserINDEXES)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ case CypherParserINDEX:
+ {
+ p.SetState(222)
+ p.Match(CypherParserINDEX)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ case CypherParserCONSTRAINTS:
+ {
+ p.SetState(223)
+ p.Match(CypherParserCONSTRAINTS)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ case CypherParserCONSTRAINT:
+ {
+ p.SetState(224)
+ p.Match(CypherParserCONSTRAINT)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ case CypherParserPROCEDURES:
+ {
+ p.SetState(225)
+ p.Match(CypherParserPROCEDURES)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ case CypherParserFUNCTIONS:
+ {
+ p.SetState(226)
+ p.Match(CypherParserFUNCTIONS)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ case CypherParserDATABASE:
+ {
+ p.SetState(227)
+ p.Match(CypherParserDATABASE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ case CypherParserDATABASES:
+ {
+ p.SetState(228)
+ p.Match(CypherParserDATABASES)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ case CypherParserEOF, CypherParserSEMI, CypherParserALL:
+ p.SetState(230)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserALL {
+ {
+ p.SetState(229)
+ p.Match(CypherParserALL)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ }
+
+ default:
+ p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil))
+ goto errorExit
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// ISchemaCommandContext is an interface to support dynamic dispatch.
+type ISchemaCommandContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ DROP() antlr.TerminalNode
+ INDEX() antlr.TerminalNode
+ Name() INameContext
+ IF() antlr.TerminalNode
+ EXISTS() antlr.TerminalNode
+ CREATE() antlr.TerminalNode
+ AllNOT() []antlr.TerminalNode
+ NOT(i int) antlr.TerminalNode
+ FOR() antlr.TerminalNode
+ NodePattern() INodePatternContext
+ ON() antlr.TerminalNode
+ ParenExpressionChain() IParenExpressionChainContext
+ FULLTEXT() antlr.TerminalNode
+ LBRACK() antlr.TerminalNode
+ ExpressionChain() IExpressionChainContext
+ RBRACK() antlr.TerminalNode
+ EACH() antlr.TerminalNode
+ VECTOR() antlr.TerminalNode
+ OPTIONS() antlr.TerminalNode
+ MapLit() IMapLitContext
+ CONSTRAINT() antlr.TerminalNode
+ REQUIRE() antlr.TerminalNode
+ Expression() IExpressionContext
+ IS() antlr.TerminalNode
+ UNIQUE() antlr.TerminalNode
+ NULL_W() antlr.TerminalNode
+ ASSERT() antlr.TerminalNode
+ NODE() antlr.TerminalNode
+ KEY() antlr.TerminalNode
+
+ // IsSchemaCommandContext differentiates from other interfaces.
+ IsSchemaCommandContext()
+}
+
+type SchemaCommandContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptySchemaCommandContext() *SchemaCommandContext {
+ var p = new(SchemaCommandContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_schemaCommand
+ return p
+}
+
+func InitEmptySchemaCommandContext(p *SchemaCommandContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_schemaCommand
+}
+
+func (*SchemaCommandContext) IsSchemaCommandContext() {}
+
+func NewSchemaCommandContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *SchemaCommandContext {
+ var p = new(SchemaCommandContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_schemaCommand
+
+ return p
+}
+
+func (s *SchemaCommandContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *SchemaCommandContext) DROP() antlr.TerminalNode {
+ return s.GetToken(CypherParserDROP, 0)
+}
+
+func (s *SchemaCommandContext) INDEX() antlr.TerminalNode {
+ return s.GetToken(CypherParserINDEX, 0)
+}
+
+func (s *SchemaCommandContext) Name() INameContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(INameContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(INameContext)
+}
+
+func (s *SchemaCommandContext) IF() antlr.TerminalNode {
+ return s.GetToken(CypherParserIF, 0)
+}
+
+func (s *SchemaCommandContext) EXISTS() antlr.TerminalNode {
+ return s.GetToken(CypherParserEXISTS, 0)
+}
+
+func (s *SchemaCommandContext) CREATE() antlr.TerminalNode {
+ return s.GetToken(CypherParserCREATE, 0)
+}
+
+func (s *SchemaCommandContext) AllNOT() []antlr.TerminalNode {
+ return s.GetTokens(CypherParserNOT)
+}
+
+func (s *SchemaCommandContext) NOT(i int) antlr.TerminalNode {
+ return s.GetToken(CypherParserNOT, i)
+}
+
+func (s *SchemaCommandContext) FOR() antlr.TerminalNode {
+ return s.GetToken(CypherParserFOR, 0)
+}
+
+func (s *SchemaCommandContext) NodePattern() INodePatternContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(INodePatternContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(INodePatternContext)
+}
+
+func (s *SchemaCommandContext) ON() antlr.TerminalNode {
+ return s.GetToken(CypherParserON, 0)
+}
+
+func (s *SchemaCommandContext) ParenExpressionChain() IParenExpressionChainContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IParenExpressionChainContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IParenExpressionChainContext)
+}
+
+func (s *SchemaCommandContext) FULLTEXT() antlr.TerminalNode {
+ return s.GetToken(CypherParserFULLTEXT, 0)
+}
+
+func (s *SchemaCommandContext) LBRACK() antlr.TerminalNode {
+ return s.GetToken(CypherParserLBRACK, 0)
+}
+
+func (s *SchemaCommandContext) ExpressionChain() IExpressionChainContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IExpressionChainContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IExpressionChainContext)
+}
+
+func (s *SchemaCommandContext) RBRACK() antlr.TerminalNode {
+ return s.GetToken(CypherParserRBRACK, 0)
+}
+
+func (s *SchemaCommandContext) EACH() antlr.TerminalNode {
+ return s.GetToken(CypherParserEACH, 0)
+}
+
+func (s *SchemaCommandContext) VECTOR() antlr.TerminalNode {
+ return s.GetToken(CypherParserVECTOR, 0)
+}
+
+func (s *SchemaCommandContext) OPTIONS() antlr.TerminalNode {
+ return s.GetToken(CypherParserOPTIONS, 0)
+}
+
+func (s *SchemaCommandContext) MapLit() IMapLitContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IMapLitContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IMapLitContext)
+}
+
+func (s *SchemaCommandContext) CONSTRAINT() antlr.TerminalNode {
+ return s.GetToken(CypherParserCONSTRAINT, 0)
+}
+
+func (s *SchemaCommandContext) REQUIRE() antlr.TerminalNode {
+ return s.GetToken(CypherParserREQUIRE, 0)
+}
+
+func (s *SchemaCommandContext) Expression() IExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IExpressionContext)
+}
+
+func (s *SchemaCommandContext) IS() antlr.TerminalNode {
+ return s.GetToken(CypherParserIS, 0)
+}
+
+func (s *SchemaCommandContext) UNIQUE() antlr.TerminalNode {
+ return s.GetToken(CypherParserUNIQUE, 0)
+}
+
+func (s *SchemaCommandContext) NULL_W() antlr.TerminalNode {
+ return s.GetToken(CypherParserNULL_W, 0)
+}
+
+func (s *SchemaCommandContext) ASSERT() antlr.TerminalNode {
+ return s.GetToken(CypherParserASSERT, 0)
+}
+
+func (s *SchemaCommandContext) NODE() antlr.TerminalNode {
+ return s.GetToken(CypherParserNODE, 0)
+}
+
+func (s *SchemaCommandContext) KEY() antlr.TerminalNode {
+ return s.GetToken(CypherParserKEY, 0)
+}
+
+func (s *SchemaCommandContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *SchemaCommandContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *SchemaCommandContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterSchemaCommand(s)
+ }
+}
+
+func (s *SchemaCommandContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitSchemaCommand(s)
+ }
+}
+
+func (p *CypherParser) SchemaCommand() (localctx ISchemaCommandContext) {
+ localctx = NewSchemaCommandContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 8, CypherParserRULE_schemaCommand)
+ var _la int
+
+ p.SetState(374)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 36, p.GetParserRuleContext()) {
+ case 1:
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(234)
+ p.Match(CypherParserDROP)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(235)
+ p.Match(CypherParserINDEX)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(237)
+ p.GetErrorHandler().Sync(p)
+
+ if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 6, p.GetParserRuleContext()) == 1 {
+ {
+ p.SetState(236)
+ p.Name()
+ }
+
+ } else if p.HasError() { // JIM
+ goto errorExit
+ }
+ p.SetState(241)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserIF {
+ {
+ p.SetState(239)
+ p.Match(CypherParserIF)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(240)
+ p.Match(CypherParserEXISTS)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ }
+
+ case 2:
+ p.EnterOuterAlt(localctx, 2)
+ {
+ p.SetState(243)
+ p.Match(CypherParserCREATE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(244)
+ p.Match(CypherParserINDEX)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(246)
+ p.GetErrorHandler().Sync(p)
+
+ if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 8, p.GetParserRuleContext()) == 1 {
+ {
+ p.SetState(245)
+ p.Name()
+ }
+
+ } else if p.HasError() { // JIM
+ goto errorExit
+ }
+ p.SetState(251)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserIF {
+ {
+ p.SetState(248)
+ p.Match(CypherParserIF)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(249)
+ p.Match(CypherParserNOT)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(250)
+ p.Match(CypherParserEXISTS)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ }
+ p.SetState(255)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserFOR {
+ {
+ p.SetState(253)
+ p.Match(CypherParserFOR)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(254)
+ p.NodePattern()
+ }
+
+ }
+ p.SetState(258)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserON {
+ {
+ p.SetState(257)
+ p.Match(CypherParserON)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ }
+ p.SetState(261)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserLPAREN {
+ {
+ p.SetState(260)
+ p.ParenExpressionChain()
+ }
+
+ }
+
+ case 3:
+ p.EnterOuterAlt(localctx, 3)
+ {
+ p.SetState(263)
+ p.Match(CypherParserCREATE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(264)
+ p.Match(CypherParserFULLTEXT)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(265)
+ p.Match(CypherParserINDEX)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(267)
+ p.GetErrorHandler().Sync(p)
+
+ if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 13, p.GetParserRuleContext()) == 1 {
+ {
+ p.SetState(266)
+ p.Name()
+ }
+
+ } else if p.HasError() { // JIM
+ goto errorExit
+ }
+ p.SetState(272)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserIF {
+ {
+ p.SetState(269)
+ p.Match(CypherParserIF)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(270)
+ p.Match(CypherParserNOT)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(271)
+ p.Match(CypherParserEXISTS)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ }
+ p.SetState(276)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserFOR {
+ {
+ p.SetState(274)
+ p.Match(CypherParserFOR)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(275)
+ p.NodePattern()
+ }
+
+ }
+ p.SetState(279)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserON {
+ {
+ p.SetState(278)
+ p.Match(CypherParserON)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ }
+ p.SetState(282)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserEACH {
+ {
+ p.SetState(281)
+ p.Match(CypherParserEACH)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ }
+ {
+ p.SetState(284)
+ p.Match(CypherParserLBRACK)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(285)
+ p.ExpressionChain()
+ }
+ {
+ p.SetState(286)
+ p.Match(CypherParserRBRACK)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ case 4:
+ p.EnterOuterAlt(localctx, 4)
+ {
+ p.SetState(288)
+ p.Match(CypherParserCREATE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(289)
+ p.Match(CypherParserVECTOR)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(290)
+ p.Match(CypherParserINDEX)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(292)
+ p.GetErrorHandler().Sync(p)
+
+ if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 18, p.GetParserRuleContext()) == 1 {
+ {
+ p.SetState(291)
+ p.Name()
+ }
+
+ } else if p.HasError() { // JIM
+ goto errorExit
+ }
+ p.SetState(297)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserIF {
+ {
+ p.SetState(294)
+ p.Match(CypherParserIF)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(295)
+ p.Match(CypherParserNOT)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(296)
+ p.Match(CypherParserEXISTS)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ }
+ p.SetState(301)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserFOR {
+ {
+ p.SetState(299)
+ p.Match(CypherParserFOR)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(300)
+ p.NodePattern()
+ }
+
+ }
+ p.SetState(304)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserON {
+ {
+ p.SetState(303)
+ p.Match(CypherParserON)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ }
+ p.SetState(307)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserLPAREN {
+ {
+ p.SetState(306)
+ p.ParenExpressionChain()
+ }
+
+ }
+ p.SetState(311)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserOPTIONS {
+ {
+ p.SetState(309)
+ p.Match(CypherParserOPTIONS)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(310)
+ p.MapLit()
+ }
+
+ }
+
+ case 5:
+ p.EnterOuterAlt(localctx, 5)
+ {
+ p.SetState(313)
+ p.Match(CypherParserDROP)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(314)
+ p.Match(CypherParserCONSTRAINT)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(316)
+ p.GetErrorHandler().Sync(p)
+
+ if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 24, p.GetParserRuleContext()) == 1 {
+ {
+ p.SetState(315)
+ p.Name()
+ }
+
+ } else if p.HasError() { // JIM
+ goto errorExit
+ }
+ p.SetState(320)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserIF {
+ {
+ p.SetState(318)
+ p.Match(CypherParserIF)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(319)
+ p.Match(CypherParserEXISTS)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ }
+
+ case 6:
+ p.EnterOuterAlt(localctx, 6)
+ {
+ p.SetState(322)
+ p.Match(CypherParserCREATE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(323)
+ p.Match(CypherParserCONSTRAINT)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(325)
+ p.GetErrorHandler().Sync(p)
+
+ if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 26, p.GetParserRuleContext()) == 1 {
+ {
+ p.SetState(324)
+ p.Name()
+ }
+
+ } else if p.HasError() { // JIM
+ goto errorExit
+ }
+ p.SetState(330)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserIF {
+ {
+ p.SetState(327)
+ p.Match(CypherParserIF)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(328)
+ p.Match(CypherParserNOT)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(329)
+ p.Match(CypherParserEXISTS)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ }
+ p.SetState(334)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserFOR {
+ {
+ p.SetState(332)
+ p.Match(CypherParserFOR)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(333)
+ p.NodePattern()
+ }
+
+ }
+ {
+ p.SetState(336)
+ p.Match(CypherParserREQUIRE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(337)
+ p.Expression()
+ }
+ p.SetState(343)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 29, p.GetParserRuleContext()) {
+ case 1:
+ {
+ p.SetState(338)
+ p.Match(CypherParserIS)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(339)
+ p.Match(CypherParserUNIQUE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ case 2:
+ {
+ p.SetState(340)
+ p.Match(CypherParserIS)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(341)
+ p.Match(CypherParserNOT)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(342)
+ p.Match(CypherParserNULL_W)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ case antlr.ATNInvalidAltNumber:
+ goto errorExit
+ }
+
+ case 7:
+ p.EnterOuterAlt(localctx, 7)
+ {
+ p.SetState(345)
+ p.Match(CypherParserCREATE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(346)
+ p.Match(CypherParserCONSTRAINT)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(348)
+ p.GetErrorHandler().Sync(p)
+
+ if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 30, p.GetParserRuleContext()) == 1 {
+ {
+ p.SetState(347)
+ p.Name()
+ }
+
+ } else if p.HasError() { // JIM
+ goto errorExit
+ }
+ p.SetState(353)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserIF {
+ {
+ p.SetState(350)
+ p.Match(CypherParserIF)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(351)
+ p.Match(CypherParserNOT)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(352)
+ p.Match(CypherParserEXISTS)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ }
+ p.SetState(356)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserON {
+ {
+ p.SetState(355)
+ p.Match(CypherParserON)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ }
+ p.SetState(359)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserLPAREN {
+ {
+ p.SetState(358)
+ p.NodePattern()
+ }
+
+ }
+ {
+ p.SetState(361)
+ p.Match(CypherParserASSERT)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(364)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 34, p.GetParserRuleContext()) {
+ case 1:
+ {
+ p.SetState(362)
+ p.Expression()
+ }
+
+ case 2:
+ {
+ p.SetState(363)
+ p.ParenExpressionChain()
+ }
+
+ case antlr.ATNInvalidAltNumber:
+ goto errorExit
+ }
+ {
+ p.SetState(366)
+ p.Match(CypherParserIS)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(372)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetTokenStream().LA(1) {
+ case CypherParserUNIQUE:
+ {
+ p.SetState(367)
+ p.Match(CypherParserUNIQUE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ case CypherParserNOT:
+ {
+ p.SetState(368)
+ p.Match(CypherParserNOT)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(369)
+ p.Match(CypherParserNULL_W)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ case CypherParserNODE:
+ {
+ p.SetState(370)
+ p.Match(CypherParserNODE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(371)
+ p.Match(CypherParserKEY)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ default:
+ p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil))
+ goto errorExit
+ }
+
+ case antlr.ATNInvalidAltNumber:
+ goto errorExit
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IRegularQueryContext is an interface to support dynamic dispatch.
+type IRegularQueryContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ SingleQuery() ISingleQueryContext
+ AllUnionSt() []IUnionStContext
+ UnionSt(i int) IUnionStContext
+
+ // IsRegularQueryContext differentiates from other interfaces.
+ IsRegularQueryContext()
+}
+
+type RegularQueryContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyRegularQueryContext() *RegularQueryContext {
+ var p = new(RegularQueryContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_regularQuery
+ return p
+}
+
+func InitEmptyRegularQueryContext(p *RegularQueryContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_regularQuery
+}
+
+func (*RegularQueryContext) IsRegularQueryContext() {}
+
+func NewRegularQueryContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *RegularQueryContext {
+ var p = new(RegularQueryContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_regularQuery
+
+ return p
+}
+
+func (s *RegularQueryContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *RegularQueryContext) SingleQuery() ISingleQueryContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ISingleQueryContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ISingleQueryContext)
+}
+
+func (s *RegularQueryContext) AllUnionSt() []IUnionStContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IUnionStContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IUnionStContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IUnionStContext); ok {
+ tst[i] = t.(IUnionStContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *RegularQueryContext) UnionSt(i int) IUnionStContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IUnionStContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IUnionStContext)
+}
+
+func (s *RegularQueryContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *RegularQueryContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *RegularQueryContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterRegularQuery(s)
+ }
+}
+
+func (s *RegularQueryContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitRegularQuery(s)
+ }
+}
+
+func (p *CypherParser) RegularQuery() (localctx IRegularQueryContext) {
+ localctx = NewRegularQueryContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 10, CypherParserRULE_regularQuery)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(376)
+ p.SingleQuery()
+ }
+ p.SetState(380)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for _la == CypherParserUNION {
+ {
+ p.SetState(377)
+ p.UnionSt()
+ }
+
+ p.SetState(382)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// ISingleQueryContext is an interface to support dynamic dispatch.
+type ISingleQueryContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ SinglePartQ() ISinglePartQContext
+ MultiPartQ() IMultiPartQContext
+
+ // IsSingleQueryContext differentiates from other interfaces.
+ IsSingleQueryContext()
+}
+
+type SingleQueryContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptySingleQueryContext() *SingleQueryContext {
+ var p = new(SingleQueryContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_singleQuery
+ return p
+}
+
+func InitEmptySingleQueryContext(p *SingleQueryContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_singleQuery
+}
+
+func (*SingleQueryContext) IsSingleQueryContext() {}
+
+func NewSingleQueryContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *SingleQueryContext {
+ var p = new(SingleQueryContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_singleQuery
+
+ return p
+}
+
+func (s *SingleQueryContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *SingleQueryContext) SinglePartQ() ISinglePartQContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ISinglePartQContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ISinglePartQContext)
+}
+
+func (s *SingleQueryContext) MultiPartQ() IMultiPartQContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IMultiPartQContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IMultiPartQContext)
+}
+
+func (s *SingleQueryContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *SingleQueryContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *SingleQueryContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterSingleQuery(s)
+ }
+}
+
+func (s *SingleQueryContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitSingleQuery(s)
+ }
+}
+
+func (p *CypherParser) SingleQuery() (localctx ISingleQueryContext) {
+ localctx = NewSingleQueryContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 12, CypherParserRULE_singleQuery)
+ p.SetState(385)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 38, p.GetParserRuleContext()) {
+ case 1:
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(383)
+ p.SinglePartQ()
+ }
+
+ case 2:
+ p.EnterOuterAlt(localctx, 2)
+ {
+ p.SetState(384)
+ p.MultiPartQ()
+ }
+
+ case antlr.ATNInvalidAltNumber:
+ goto errorExit
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IStandaloneCallContext is an interface to support dynamic dispatch.
+type IStandaloneCallContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ CALL() antlr.TerminalNode
+ InvocationName() IInvocationNameContext
+ ParenExpressionChain() IParenExpressionChainContext
+ YIELD() antlr.TerminalNode
+ MULT() antlr.TerminalNode
+ YieldItems() IYieldItemsContext
+
+ // IsStandaloneCallContext differentiates from other interfaces.
+ IsStandaloneCallContext()
+}
+
+type StandaloneCallContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyStandaloneCallContext() *StandaloneCallContext {
+ var p = new(StandaloneCallContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_standaloneCall
+ return p
+}
+
+func InitEmptyStandaloneCallContext(p *StandaloneCallContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_standaloneCall
+}
+
+func (*StandaloneCallContext) IsStandaloneCallContext() {}
+
+func NewStandaloneCallContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *StandaloneCallContext {
+ var p = new(StandaloneCallContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_standaloneCall
+
+ return p
+}
+
+func (s *StandaloneCallContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *StandaloneCallContext) CALL() antlr.TerminalNode {
+ return s.GetToken(CypherParserCALL, 0)
+}
+
+func (s *StandaloneCallContext) InvocationName() IInvocationNameContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IInvocationNameContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IInvocationNameContext)
+}
+
+func (s *StandaloneCallContext) ParenExpressionChain() IParenExpressionChainContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IParenExpressionChainContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IParenExpressionChainContext)
+}
+
+func (s *StandaloneCallContext) YIELD() antlr.TerminalNode {
+ return s.GetToken(CypherParserYIELD, 0)
+}
+
+func (s *StandaloneCallContext) MULT() antlr.TerminalNode {
+ return s.GetToken(CypherParserMULT, 0)
+}
+
+func (s *StandaloneCallContext) YieldItems() IYieldItemsContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IYieldItemsContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IYieldItemsContext)
+}
+
+func (s *StandaloneCallContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *StandaloneCallContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *StandaloneCallContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterStandaloneCall(s)
+ }
+}
+
+func (s *StandaloneCallContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitStandaloneCall(s)
+ }
+}
+
+func (p *CypherParser) StandaloneCall() (localctx IStandaloneCallContext) {
+ localctx = NewStandaloneCallContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 14, CypherParserRULE_standaloneCall)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(387)
+ p.Match(CypherParserCALL)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(388)
+ p.InvocationName()
+ }
+ p.SetState(390)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserLPAREN {
+ {
+ p.SetState(389)
+ p.ParenExpressionChain()
+ }
+
+ }
+ p.SetState(397)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserYIELD {
+ {
+ p.SetState(392)
+ p.Match(CypherParserYIELD)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(395)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetTokenStream().LA(1) {
+ case CypherParserMULT:
+ {
+ p.SetState(393)
+ p.Match(CypherParserMULT)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ case CypherParserFILTER, CypherParserEXTRACT, CypherParserCOUNT, CypherParserSUM, CypherParserAVG, CypherParserMIN, CypherParserMAX, CypherParserCOLLECT, CypherParserANY, CypherParserNONE, CypherParserSINGLE, CypherParserALL, CypherParserCREATE, CypherParserDELETE, CypherParserEXISTS, CypherParserMATCH, CypherParserMERGE, CypherParserREMOVE, CypherParserSET, CypherParserFALSE, CypherParserTRUE, CypherParserNULL_W, CypherParserCONSTRAINT, CypherParserREQUIRE, CypherParserUNIQUE, CypherParserCASE, CypherParserWHEN, CypherParserTHEN, CypherParserELSE, CypherParserEND, CypherParserADD, CypherParserDROP, CypherParserINDEX, CypherParserINDEXES, CypherParserVECTOR, CypherParserSHOW, CypherParserCONSTRAINTS, CypherParserPROCEDURES, CypherParserFUNCTIONS, CypherParserDATABASE, CypherParserFULLTEXT, CypherParserOPTIONS, CypherParserEACH, CypherParserIF, CypherParserTRANSACTIONS, CypherParserROWS, CypherParserASSERT, CypherParserKEY, CypherParserNODE, CypherParserSHORTESTPATH, CypherParserALLSHORTESTPATHS, CypherParserID, CypherParserESC_LITERAL:
+ {
+ p.SetState(394)
+ p.YieldItems()
+ }
+
+ default:
+ p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil))
+ goto errorExit
+ }
+
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IExistsSubqueryContext is an interface to support dynamic dispatch.
+type IExistsSubqueryContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ EXISTS() antlr.TerminalNode
+ LBRACE() antlr.TerminalNode
+ MatchSt() IMatchStContext
+ RBRACE() antlr.TerminalNode
+
+ // IsExistsSubqueryContext differentiates from other interfaces.
+ IsExistsSubqueryContext()
+}
+
+type ExistsSubqueryContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyExistsSubqueryContext() *ExistsSubqueryContext {
+ var p = new(ExistsSubqueryContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_existsSubquery
+ return p
+}
+
+func InitEmptyExistsSubqueryContext(p *ExistsSubqueryContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_existsSubquery
+}
+
+func (*ExistsSubqueryContext) IsExistsSubqueryContext() {}
+
+func NewExistsSubqueryContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ExistsSubqueryContext {
+ var p = new(ExistsSubqueryContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_existsSubquery
+
+ return p
+}
+
+func (s *ExistsSubqueryContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *ExistsSubqueryContext) EXISTS() antlr.TerminalNode {
+ return s.GetToken(CypherParserEXISTS, 0)
+}
+
+func (s *ExistsSubqueryContext) LBRACE() antlr.TerminalNode {
+ return s.GetToken(CypherParserLBRACE, 0)
+}
+
+func (s *ExistsSubqueryContext) MatchSt() IMatchStContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IMatchStContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IMatchStContext)
+}
+
+func (s *ExistsSubqueryContext) RBRACE() antlr.TerminalNode {
+ return s.GetToken(CypherParserRBRACE, 0)
+}
+
+func (s *ExistsSubqueryContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *ExistsSubqueryContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *ExistsSubqueryContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterExistsSubquery(s)
+ }
+}
+
+func (s *ExistsSubqueryContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitExistsSubquery(s)
+ }
+}
+
+func (p *CypherParser) ExistsSubquery() (localctx IExistsSubqueryContext) {
+ localctx = NewExistsSubqueryContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 16, CypherParserRULE_existsSubquery)
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(399)
+ p.Match(CypherParserEXISTS)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(400)
+ p.Match(CypherParserLBRACE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(401)
+ p.MatchSt()
+ }
+ {
+ p.SetState(402)
+ p.Match(CypherParserRBRACE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// ICountSubqueryContext is an interface to support dynamic dispatch.
+type ICountSubqueryContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ COUNT() antlr.TerminalNode
+ LBRACE() antlr.TerminalNode
+ MatchSt() IMatchStContext
+ RBRACE() antlr.TerminalNode
+
+ // IsCountSubqueryContext differentiates from other interfaces.
+ IsCountSubqueryContext()
+}
+
+type CountSubqueryContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyCountSubqueryContext() *CountSubqueryContext {
+ var p = new(CountSubqueryContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_countSubquery
+ return p
+}
+
+func InitEmptyCountSubqueryContext(p *CountSubqueryContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_countSubquery
+}
+
+func (*CountSubqueryContext) IsCountSubqueryContext() {}
+
+func NewCountSubqueryContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *CountSubqueryContext {
+ var p = new(CountSubqueryContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_countSubquery
+
+ return p
+}
+
+func (s *CountSubqueryContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *CountSubqueryContext) COUNT() antlr.TerminalNode {
+ return s.GetToken(CypherParserCOUNT, 0)
+}
+
+func (s *CountSubqueryContext) LBRACE() antlr.TerminalNode {
+ return s.GetToken(CypherParserLBRACE, 0)
+}
+
+func (s *CountSubqueryContext) MatchSt() IMatchStContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IMatchStContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IMatchStContext)
+}
+
+func (s *CountSubqueryContext) RBRACE() antlr.TerminalNode {
+ return s.GetToken(CypherParserRBRACE, 0)
+}
+
+func (s *CountSubqueryContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *CountSubqueryContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *CountSubqueryContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterCountSubquery(s)
+ }
+}
+
+func (s *CountSubqueryContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitCountSubquery(s)
+ }
+}
+
+func (p *CypherParser) CountSubquery() (localctx ICountSubqueryContext) {
+ localctx = NewCountSubqueryContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 18, CypherParserRULE_countSubquery)
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(404)
+ p.Match(CypherParserCOUNT)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(405)
+ p.Match(CypherParserLBRACE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(406)
+ p.MatchSt()
+ }
+ {
+ p.SetState(407)
+ p.Match(CypherParserRBRACE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// ICallSubqueryContext is an interface to support dynamic dispatch.
+type ICallSubqueryContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ CALL() antlr.TerminalNode
+ LBRACE() antlr.TerminalNode
+ SubqueryBody() ISubqueryBodyContext
+ RBRACE() antlr.TerminalNode
+ IN() antlr.TerminalNode
+ TRANSACTIONS() antlr.TerminalNode
+ OF() antlr.TerminalNode
+ NumLit() INumLitContext
+ ROWS() antlr.TerminalNode
+
+ // IsCallSubqueryContext differentiates from other interfaces.
+ IsCallSubqueryContext()
+}
+
+type CallSubqueryContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyCallSubqueryContext() *CallSubqueryContext {
+ var p = new(CallSubqueryContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_callSubquery
+ return p
+}
+
+func InitEmptyCallSubqueryContext(p *CallSubqueryContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_callSubquery
+}
+
+func (*CallSubqueryContext) IsCallSubqueryContext() {}
+
+func NewCallSubqueryContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *CallSubqueryContext {
+ var p = new(CallSubqueryContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_callSubquery
+
+ return p
+}
+
+func (s *CallSubqueryContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *CallSubqueryContext) CALL() antlr.TerminalNode {
+ return s.GetToken(CypherParserCALL, 0)
+}
+
+func (s *CallSubqueryContext) LBRACE() antlr.TerminalNode {
+ return s.GetToken(CypherParserLBRACE, 0)
+}
+
+func (s *CallSubqueryContext) SubqueryBody() ISubqueryBodyContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ISubqueryBodyContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ISubqueryBodyContext)
+}
+
+func (s *CallSubqueryContext) RBRACE() antlr.TerminalNode {
+ return s.GetToken(CypherParserRBRACE, 0)
+}
+
+func (s *CallSubqueryContext) IN() antlr.TerminalNode {
+ return s.GetToken(CypherParserIN, 0)
+}
+
+func (s *CallSubqueryContext) TRANSACTIONS() antlr.TerminalNode {
+ return s.GetToken(CypherParserTRANSACTIONS, 0)
+}
+
+func (s *CallSubqueryContext) OF() antlr.TerminalNode {
+ return s.GetToken(CypherParserOF, 0)
+}
+
+func (s *CallSubqueryContext) NumLit() INumLitContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(INumLitContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(INumLitContext)
+}
+
+func (s *CallSubqueryContext) ROWS() antlr.TerminalNode {
+ return s.GetToken(CypherParserROWS, 0)
+}
+
+func (s *CallSubqueryContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *CallSubqueryContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *CallSubqueryContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterCallSubquery(s)
+ }
+}
+
+func (s *CallSubqueryContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitCallSubquery(s)
+ }
+}
+
+func (p *CypherParser) CallSubquery() (localctx ICallSubqueryContext) {
+ localctx = NewCallSubqueryContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 20, CypherParserRULE_callSubquery)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(409)
+ p.Match(CypherParserCALL)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(410)
+ p.Match(CypherParserLBRACE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(411)
+ p.SubqueryBody()
+ }
+ {
+ p.SetState(412)
+ p.Match(CypherParserRBRACE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(421)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserIN {
+ {
+ p.SetState(413)
+ p.Match(CypherParserIN)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(414)
+ p.Match(CypherParserTRANSACTIONS)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(419)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserOF {
+ {
+ p.SetState(415)
+ p.Match(CypherParserOF)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(416)
+ p.NumLit()
+ }
+ {
+ p.SetState(417)
+ p.Match(CypherParserROWS)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ }
+
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// ISubqueryBodyContext is an interface to support dynamic dispatch.
+type ISubqueryBodyContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ WithSt() IWithStContext
+ AllReadingStatement() []IReadingStatementContext
+ ReadingStatement(i int) IReadingStatementContext
+ AllUpdatingStatement() []IUpdatingStatementContext
+ UpdatingStatement(i int) IUpdatingStatementContext
+ ReturnSt() IReturnStContext
+
+ // IsSubqueryBodyContext differentiates from other interfaces.
+ IsSubqueryBodyContext()
+}
+
+type SubqueryBodyContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptySubqueryBodyContext() *SubqueryBodyContext {
+ var p = new(SubqueryBodyContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_subqueryBody
+ return p
+}
+
+func InitEmptySubqueryBodyContext(p *SubqueryBodyContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_subqueryBody
+}
+
+func (*SubqueryBodyContext) IsSubqueryBodyContext() {}
+
+func NewSubqueryBodyContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *SubqueryBodyContext {
+ var p = new(SubqueryBodyContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_subqueryBody
+
+ return p
+}
+
+func (s *SubqueryBodyContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *SubqueryBodyContext) WithSt() IWithStContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IWithStContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IWithStContext)
+}
+
+func (s *SubqueryBodyContext) AllReadingStatement() []IReadingStatementContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IReadingStatementContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IReadingStatementContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IReadingStatementContext); ok {
+ tst[i] = t.(IReadingStatementContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *SubqueryBodyContext) ReadingStatement(i int) IReadingStatementContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IReadingStatementContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IReadingStatementContext)
+}
+
+func (s *SubqueryBodyContext) AllUpdatingStatement() []IUpdatingStatementContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IUpdatingStatementContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IUpdatingStatementContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IUpdatingStatementContext); ok {
+ tst[i] = t.(IUpdatingStatementContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *SubqueryBodyContext) UpdatingStatement(i int) IUpdatingStatementContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IUpdatingStatementContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IUpdatingStatementContext)
+}
+
+func (s *SubqueryBodyContext) ReturnSt() IReturnStContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IReturnStContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IReturnStContext)
+}
+
+func (s *SubqueryBodyContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *SubqueryBodyContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *SubqueryBodyContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterSubqueryBody(s)
+ }
+}
+
+func (s *SubqueryBodyContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitSubqueryBody(s)
+ }
+}
+
+func (p *CypherParser) SubqueryBody() (localctx ISubqueryBodyContext) {
+ localctx = NewSubqueryBodyContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 22, CypherParserRULE_subqueryBody)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ p.SetState(424)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserWITH {
+ {
+ p.SetState(423)
+ p.WithSt()
+ }
+
+ }
+ p.SetState(430)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for (int64((_la-29)) & ^0x3f) == 0 && ((int64(1)<<(_la-29))&71590871041) != 0 {
+ p.SetState(428)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetTokenStream().LA(1) {
+ case CypherParserCALL, CypherParserMATCH, CypherParserOPTIONAL, CypherParserUNWIND:
+ {
+ p.SetState(426)
+ p.ReadingStatement()
+ }
+
+ case CypherParserCREATE, CypherParserDELETE, CypherParserDETACH, CypherParserMERGE, CypherParserREMOVE, CypherParserSET:
+ {
+ p.SetState(427)
+ p.UpdatingStatement()
+ }
+
+ default:
+ p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil))
+ goto errorExit
+ }
+
+ p.SetState(432)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+ p.SetState(434)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserRETURN {
+ {
+ p.SetState(433)
+ p.ReturnSt()
+ }
+
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IReturnStContext is an interface to support dynamic dispatch.
+type IReturnStContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ RETURN() antlr.TerminalNode
+ ProjectionBody() IProjectionBodyContext
+
+ // IsReturnStContext differentiates from other interfaces.
+ IsReturnStContext()
+}
+
+type ReturnStContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyReturnStContext() *ReturnStContext {
+ var p = new(ReturnStContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_returnSt
+ return p
+}
+
+func InitEmptyReturnStContext(p *ReturnStContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_returnSt
+}
+
+func (*ReturnStContext) IsReturnStContext() {}
+
+func NewReturnStContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ReturnStContext {
+ var p = new(ReturnStContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_returnSt
+
+ return p
+}
+
+func (s *ReturnStContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *ReturnStContext) RETURN() antlr.TerminalNode {
+ return s.GetToken(CypherParserRETURN, 0)
+}
+
+func (s *ReturnStContext) ProjectionBody() IProjectionBodyContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IProjectionBodyContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IProjectionBodyContext)
+}
+
+func (s *ReturnStContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *ReturnStContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *ReturnStContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterReturnSt(s)
+ }
+}
+
+func (s *ReturnStContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitReturnSt(s)
+ }
+}
+
+func (p *CypherParser) ReturnSt() (localctx IReturnStContext) {
+ localctx = NewReturnStContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 24, CypherParserRULE_returnSt)
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(436)
+ p.Match(CypherParserRETURN)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(437)
+ p.ProjectionBody()
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IWithStContext is an interface to support dynamic dispatch.
+type IWithStContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ WITH() antlr.TerminalNode
+ ProjectionBody() IProjectionBodyContext
+ Where() IWhereContext
+
+ // IsWithStContext differentiates from other interfaces.
+ IsWithStContext()
+}
+
+type WithStContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyWithStContext() *WithStContext {
+ var p = new(WithStContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_withSt
+ return p
+}
+
+func InitEmptyWithStContext(p *WithStContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_withSt
+}
+
+func (*WithStContext) IsWithStContext() {}
+
+func NewWithStContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *WithStContext {
+ var p = new(WithStContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_withSt
+
+ return p
+}
+
+func (s *WithStContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *WithStContext) WITH() antlr.TerminalNode {
+ return s.GetToken(CypherParserWITH, 0)
+}
+
+func (s *WithStContext) ProjectionBody() IProjectionBodyContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IProjectionBodyContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IProjectionBodyContext)
+}
+
+func (s *WithStContext) Where() IWhereContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IWhereContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IWhereContext)
+}
+
+func (s *WithStContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *WithStContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *WithStContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterWithSt(s)
+ }
+}
+
+func (s *WithStContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitWithSt(s)
+ }
+}
+
+func (p *CypherParser) WithSt() (localctx IWithStContext) {
+ localctx = NewWithStContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 26, CypherParserRULE_withSt)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(439)
+ p.Match(CypherParserWITH)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(440)
+ p.ProjectionBody()
+ }
+ p.SetState(442)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserWHERE {
+ {
+ p.SetState(441)
+ p.Where()
+ }
+
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// ISkipStContext is an interface to support dynamic dispatch.
+type ISkipStContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ SKIP_W() antlr.TerminalNode
+ Expression() IExpressionContext
+
+ // IsSkipStContext differentiates from other interfaces.
+ IsSkipStContext()
+}
+
+type SkipStContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptySkipStContext() *SkipStContext {
+ var p = new(SkipStContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_skipSt
+ return p
+}
+
+func InitEmptySkipStContext(p *SkipStContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_skipSt
+}
+
+func (*SkipStContext) IsSkipStContext() {}
+
+func NewSkipStContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *SkipStContext {
+ var p = new(SkipStContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_skipSt
+
+ return p
+}
+
+func (s *SkipStContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *SkipStContext) SKIP_W() antlr.TerminalNode {
+ return s.GetToken(CypherParserSKIP_W, 0)
+}
+
+func (s *SkipStContext) Expression() IExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IExpressionContext)
+}
+
+func (s *SkipStContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *SkipStContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *SkipStContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterSkipSt(s)
+ }
+}
+
+func (s *SkipStContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitSkipSt(s)
+ }
+}
+
+func (p *CypherParser) SkipSt() (localctx ISkipStContext) {
+ localctx = NewSkipStContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 28, CypherParserRULE_skipSt)
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(444)
+ p.Match(CypherParserSKIP_W)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(445)
+ p.Expression()
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// ILimitStContext is an interface to support dynamic dispatch.
+type ILimitStContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ LIMIT() antlr.TerminalNode
+ Expression() IExpressionContext
+
+ // IsLimitStContext differentiates from other interfaces.
+ IsLimitStContext()
+}
+
+type LimitStContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyLimitStContext() *LimitStContext {
+ var p = new(LimitStContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_limitSt
+ return p
+}
+
+func InitEmptyLimitStContext(p *LimitStContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_limitSt
+}
+
+func (*LimitStContext) IsLimitStContext() {}
+
+func NewLimitStContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *LimitStContext {
+ var p = new(LimitStContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_limitSt
+
+ return p
+}
+
+func (s *LimitStContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *LimitStContext) LIMIT() antlr.TerminalNode {
+ return s.GetToken(CypherParserLIMIT, 0)
+}
+
+func (s *LimitStContext) Expression() IExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IExpressionContext)
+}
+
+func (s *LimitStContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *LimitStContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *LimitStContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterLimitSt(s)
+ }
+}
+
+func (s *LimitStContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitLimitSt(s)
+ }
+}
+
+func (p *CypherParser) LimitSt() (localctx ILimitStContext) {
+ localctx = NewLimitStContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 30, CypherParserRULE_limitSt)
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(447)
+ p.Match(CypherParserLIMIT)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(448)
+ p.Expression()
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IProjectionBodyContext is an interface to support dynamic dispatch.
+type IProjectionBodyContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ ProjectionItems() IProjectionItemsContext
+ DISTINCT() antlr.TerminalNode
+ OrderSt() IOrderStContext
+ SkipSt() ISkipStContext
+ LimitSt() ILimitStContext
+
+ // IsProjectionBodyContext differentiates from other interfaces.
+ IsProjectionBodyContext()
+}
+
+type ProjectionBodyContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyProjectionBodyContext() *ProjectionBodyContext {
+ var p = new(ProjectionBodyContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_projectionBody
+ return p
+}
+
+func InitEmptyProjectionBodyContext(p *ProjectionBodyContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_projectionBody
+}
+
+func (*ProjectionBodyContext) IsProjectionBodyContext() {}
+
+func NewProjectionBodyContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ProjectionBodyContext {
+ var p = new(ProjectionBodyContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_projectionBody
+
+ return p
+}
+
+func (s *ProjectionBodyContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *ProjectionBodyContext) ProjectionItems() IProjectionItemsContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IProjectionItemsContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IProjectionItemsContext)
+}
+
+func (s *ProjectionBodyContext) DISTINCT() antlr.TerminalNode {
+ return s.GetToken(CypherParserDISTINCT, 0)
+}
+
+func (s *ProjectionBodyContext) OrderSt() IOrderStContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IOrderStContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IOrderStContext)
+}
+
+func (s *ProjectionBodyContext) SkipSt() ISkipStContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ISkipStContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ISkipStContext)
+}
+
+func (s *ProjectionBodyContext) LimitSt() ILimitStContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ILimitStContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ILimitStContext)
+}
+
+func (s *ProjectionBodyContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *ProjectionBodyContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *ProjectionBodyContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterProjectionBody(s)
+ }
+}
+
+func (s *ProjectionBodyContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitProjectionBody(s)
+ }
+}
+
+func (p *CypherParser) ProjectionBody() (localctx IProjectionBodyContext) {
+ localctx = NewProjectionBodyContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 32, CypherParserRULE_projectionBody)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ p.SetState(451)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserDISTINCT {
+ {
+ p.SetState(450)
+ p.Match(CypherParserDISTINCT)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ }
+ {
+ p.SetState(453)
+ p.ProjectionItems()
+ }
+ p.SetState(455)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserORDER {
+ {
+ p.SetState(454)
+ p.OrderSt()
+ }
+
+ }
+ p.SetState(458)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserSKIP_W {
+ {
+ p.SetState(457)
+ p.SkipSt()
+ }
+
+ }
+ p.SetState(461)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserLIMIT {
+ {
+ p.SetState(460)
+ p.LimitSt()
+ }
+
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IProjectionItemsContext is an interface to support dynamic dispatch.
+type IProjectionItemsContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ MULT() antlr.TerminalNode
+ AllProjectionItem() []IProjectionItemContext
+ ProjectionItem(i int) IProjectionItemContext
+ AllCOMMA() []antlr.TerminalNode
+ COMMA(i int) antlr.TerminalNode
+
+ // IsProjectionItemsContext differentiates from other interfaces.
+ IsProjectionItemsContext()
+}
+
+type ProjectionItemsContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyProjectionItemsContext() *ProjectionItemsContext {
+ var p = new(ProjectionItemsContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_projectionItems
+ return p
+}
+
+func InitEmptyProjectionItemsContext(p *ProjectionItemsContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_projectionItems
+}
+
+func (*ProjectionItemsContext) IsProjectionItemsContext() {}
+
+func NewProjectionItemsContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ProjectionItemsContext {
+ var p = new(ProjectionItemsContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_projectionItems
+
+ return p
+}
+
+func (s *ProjectionItemsContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *ProjectionItemsContext) MULT() antlr.TerminalNode {
+ return s.GetToken(CypherParserMULT, 0)
+}
+
+func (s *ProjectionItemsContext) AllProjectionItem() []IProjectionItemContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IProjectionItemContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IProjectionItemContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IProjectionItemContext); ok {
+ tst[i] = t.(IProjectionItemContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *ProjectionItemsContext) ProjectionItem(i int) IProjectionItemContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IProjectionItemContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IProjectionItemContext)
+}
+
+func (s *ProjectionItemsContext) AllCOMMA() []antlr.TerminalNode {
+ return s.GetTokens(CypherParserCOMMA)
+}
+
+func (s *ProjectionItemsContext) COMMA(i int) antlr.TerminalNode {
+ return s.GetToken(CypherParserCOMMA, i)
+}
+
+func (s *ProjectionItemsContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *ProjectionItemsContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *ProjectionItemsContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterProjectionItems(s)
+ }
+}
+
+func (s *ProjectionItemsContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitProjectionItems(s)
+ }
+}
+
+func (p *CypherParser) ProjectionItems() (localctx IProjectionItemsContext) {
+ localctx = NewProjectionItemsContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 34, CypherParserRULE_projectionItems)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ p.SetState(465)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetTokenStream().LA(1) {
+ case CypherParserMULT:
+ {
+ p.SetState(463)
+ p.Match(CypherParserMULT)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ case CypherParserLPAREN, CypherParserLBRACE, CypherParserLBRACK, CypherParserSUB, CypherParserPLUS, CypherParserDOLLAR, CypherParserFILTER, CypherParserEXTRACT, CypherParserCOUNT, CypherParserSUM, CypherParserAVG, CypherParserMIN, CypherParserMAX, CypherParserCOLLECT, CypherParserANY, CypherParserNONE, CypherParserSINGLE, CypherParserALL, CypherParserCREATE, CypherParserDELETE, CypherParserEXISTS, CypherParserMATCH, CypherParserMERGE, CypherParserREMOVE, CypherParserSET, CypherParserNOT, CypherParserFALSE, CypherParserTRUE, CypherParserNULL_W, CypherParserCONSTRAINT, CypherParserREQUIRE, CypherParserUNIQUE, CypherParserCASE, CypherParserWHEN, CypherParserTHEN, CypherParserELSE, CypherParserEND, CypherParserADD, CypherParserDROP, CypherParserINDEX, CypherParserINDEXES, CypherParserVECTOR, CypherParserSHOW, CypherParserCONSTRAINTS, CypherParserPROCEDURES, CypherParserFUNCTIONS, CypherParserDATABASE, CypherParserFULLTEXT, CypherParserOPTIONS, CypherParserEACH, CypherParserIF, CypherParserTRANSACTIONS, CypherParserROWS, CypherParserASSERT, CypherParserKEY, CypherParserNODE, CypherParserSHORTESTPATH, CypherParserALLSHORTESTPATHS, CypherParserFLOAT, CypherParserINTEGER, CypherParserDIGIT, CypherParserID, CypherParserESC_LITERAL, CypherParserCHAR_LITERAL, CypherParserSTRING_LITERAL:
+ {
+ p.SetState(464)
+ p.ProjectionItem()
+ }
+
+ default:
+ p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil))
+ goto errorExit
+ }
+ p.SetState(471)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for _la == CypherParserCOMMA {
+ {
+ p.SetState(467)
+ p.Match(CypherParserCOMMA)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(468)
+ p.ProjectionItem()
+ }
+
+ p.SetState(473)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IProjectionItemContext is an interface to support dynamic dispatch.
+type IProjectionItemContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ Expression() IExpressionContext
+ AS() antlr.TerminalNode
+ Symbol() ISymbolContext
+
+ // IsProjectionItemContext differentiates from other interfaces.
+ IsProjectionItemContext()
+}
+
+type ProjectionItemContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyProjectionItemContext() *ProjectionItemContext {
+ var p = new(ProjectionItemContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_projectionItem
+ return p
+}
+
+func InitEmptyProjectionItemContext(p *ProjectionItemContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_projectionItem
+}
+
+func (*ProjectionItemContext) IsProjectionItemContext() {}
+
+func NewProjectionItemContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ProjectionItemContext {
+ var p = new(ProjectionItemContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_projectionItem
+
+ return p
+}
+
+func (s *ProjectionItemContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *ProjectionItemContext) Expression() IExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IExpressionContext)
+}
+
+func (s *ProjectionItemContext) AS() antlr.TerminalNode {
+ return s.GetToken(CypherParserAS, 0)
+}
+
+func (s *ProjectionItemContext) Symbol() ISymbolContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ISymbolContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ISymbolContext)
+}
+
+func (s *ProjectionItemContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *ProjectionItemContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *ProjectionItemContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterProjectionItem(s)
+ }
+}
+
+func (s *ProjectionItemContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitProjectionItem(s)
+ }
+}
+
+func (p *CypherParser) ProjectionItem() (localctx IProjectionItemContext) {
+ localctx = NewProjectionItemContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 36, CypherParserRULE_projectionItem)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(474)
+ p.Expression()
+ }
+ p.SetState(477)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserAS {
+ {
+ p.SetState(475)
+ p.Match(CypherParserAS)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(476)
+ p.Symbol()
+ }
+
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IOrderItemContext is an interface to support dynamic dispatch.
+type IOrderItemContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ Expression() IExpressionContext
+ ASCENDING() antlr.TerminalNode
+ ASC() antlr.TerminalNode
+ DESCENDING() antlr.TerminalNode
+ DESC() antlr.TerminalNode
+
+ // IsOrderItemContext differentiates from other interfaces.
+ IsOrderItemContext()
+}
+
+type OrderItemContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyOrderItemContext() *OrderItemContext {
+ var p = new(OrderItemContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_orderItem
+ return p
+}
+
+func InitEmptyOrderItemContext(p *OrderItemContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_orderItem
+}
+
+func (*OrderItemContext) IsOrderItemContext() {}
+
+func NewOrderItemContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *OrderItemContext {
+ var p = new(OrderItemContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_orderItem
+
+ return p
+}
+
+func (s *OrderItemContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *OrderItemContext) Expression() IExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IExpressionContext)
+}
+
+func (s *OrderItemContext) ASCENDING() antlr.TerminalNode {
+ return s.GetToken(CypherParserASCENDING, 0)
+}
+
+func (s *OrderItemContext) ASC() antlr.TerminalNode {
+ return s.GetToken(CypherParserASC, 0)
+}
+
+func (s *OrderItemContext) DESCENDING() antlr.TerminalNode {
+ return s.GetToken(CypherParserDESCENDING, 0)
+}
+
+func (s *OrderItemContext) DESC() antlr.TerminalNode {
+ return s.GetToken(CypherParserDESC, 0)
+}
+
+func (s *OrderItemContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *OrderItemContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *OrderItemContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterOrderItem(s)
+ }
+}
+
+func (s *OrderItemContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitOrderItem(s)
+ }
+}
+
+func (p *CypherParser) OrderItem() (localctx IOrderItemContext) {
+ localctx = NewOrderItemContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 38, CypherParserRULE_orderItem)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(479)
+ p.Expression()
+ }
+ p.SetState(481)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if (int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&870813209198592) != 0 {
+ {
+ p.SetState(480)
+ _la = p.GetTokenStream().LA(1)
+
+ if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&870813209198592) != 0) {
+ p.GetErrorHandler().RecoverInline(p)
+ } else {
+ p.GetErrorHandler().ReportMatch(p)
+ p.Consume()
+ }
+ }
+
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IOrderStContext is an interface to support dynamic dispatch.
+type IOrderStContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ ORDER() antlr.TerminalNode
+ BY() antlr.TerminalNode
+ AllOrderItem() []IOrderItemContext
+ OrderItem(i int) IOrderItemContext
+ AllCOMMA() []antlr.TerminalNode
+ COMMA(i int) antlr.TerminalNode
+
+ // IsOrderStContext differentiates from other interfaces.
+ IsOrderStContext()
+}
+
+type OrderStContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyOrderStContext() *OrderStContext {
+ var p = new(OrderStContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_orderSt
+ return p
+}
+
+func InitEmptyOrderStContext(p *OrderStContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_orderSt
+}
+
+func (*OrderStContext) IsOrderStContext() {}
+
+func NewOrderStContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *OrderStContext {
+ var p = new(OrderStContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_orderSt
+
+ return p
+}
+
+func (s *OrderStContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *OrderStContext) ORDER() antlr.TerminalNode {
+ return s.GetToken(CypherParserORDER, 0)
+}
+
+func (s *OrderStContext) BY() antlr.TerminalNode {
+ return s.GetToken(CypherParserBY, 0)
+}
+
+func (s *OrderStContext) AllOrderItem() []IOrderItemContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IOrderItemContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IOrderItemContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IOrderItemContext); ok {
+ tst[i] = t.(IOrderItemContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *OrderStContext) OrderItem(i int) IOrderItemContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IOrderItemContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IOrderItemContext)
+}
+
+func (s *OrderStContext) AllCOMMA() []antlr.TerminalNode {
+ return s.GetTokens(CypherParserCOMMA)
+}
+
+func (s *OrderStContext) COMMA(i int) antlr.TerminalNode {
+ return s.GetToken(CypherParserCOMMA, i)
+}
+
+func (s *OrderStContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *OrderStContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *OrderStContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterOrderSt(s)
+ }
+}
+
+func (s *OrderStContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitOrderSt(s)
+ }
+}
+
+func (p *CypherParser) OrderSt() (localctx IOrderStContext) {
+ localctx = NewOrderStContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 40, CypherParserRULE_orderSt)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(483)
+ p.Match(CypherParserORDER)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(484)
+ p.Match(CypherParserBY)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(485)
+ p.OrderItem()
+ }
+ p.SetState(490)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for _la == CypherParserCOMMA {
+ {
+ p.SetState(486)
+ p.Match(CypherParserCOMMA)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(487)
+ p.OrderItem()
+ }
+
+ p.SetState(492)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// ISinglePartQContext is an interface to support dynamic dispatch.
+type ISinglePartQContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ AllReadingStatement() []IReadingStatementContext
+ ReadingStatement(i int) IReadingStatementContext
+ ReturnSt() IReturnStContext
+ AllUpdatingStatement() []IUpdatingStatementContext
+ UpdatingStatement(i int) IUpdatingStatementContext
+ CallSubquery() ICallSubqueryContext
+ OrderSt() IOrderStContext
+
+ // IsSinglePartQContext differentiates from other interfaces.
+ IsSinglePartQContext()
+}
+
+type SinglePartQContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptySinglePartQContext() *SinglePartQContext {
+ var p = new(SinglePartQContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_singlePartQ
+ return p
+}
+
+func InitEmptySinglePartQContext(p *SinglePartQContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_singlePartQ
+}
+
+func (*SinglePartQContext) IsSinglePartQContext() {}
+
+func NewSinglePartQContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *SinglePartQContext {
+ var p = new(SinglePartQContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_singlePartQ
+
+ return p
+}
+
+func (s *SinglePartQContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *SinglePartQContext) AllReadingStatement() []IReadingStatementContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IReadingStatementContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IReadingStatementContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IReadingStatementContext); ok {
+ tst[i] = t.(IReadingStatementContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *SinglePartQContext) ReadingStatement(i int) IReadingStatementContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IReadingStatementContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IReadingStatementContext)
+}
+
+func (s *SinglePartQContext) ReturnSt() IReturnStContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IReturnStContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IReturnStContext)
+}
+
+func (s *SinglePartQContext) AllUpdatingStatement() []IUpdatingStatementContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IUpdatingStatementContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IUpdatingStatementContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IUpdatingStatementContext); ok {
+ tst[i] = t.(IUpdatingStatementContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *SinglePartQContext) UpdatingStatement(i int) IUpdatingStatementContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IUpdatingStatementContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IUpdatingStatementContext)
+}
+
+func (s *SinglePartQContext) CallSubquery() ICallSubqueryContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ICallSubqueryContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ICallSubqueryContext)
+}
+
+func (s *SinglePartQContext) OrderSt() IOrderStContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IOrderStContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IOrderStContext)
+}
+
+func (s *SinglePartQContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *SinglePartQContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *SinglePartQContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterSinglePartQ(s)
+ }
+}
+
+func (s *SinglePartQContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitSinglePartQ(s)
+ }
+}
+
+func (p *CypherParser) SinglePartQ() (localctx ISinglePartQContext) {
+ localctx = NewSinglePartQContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 42, CypherParserRULE_singlePartQ)
+ var _la int
+
+ p.SetState(514)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 63, p.GetParserRuleContext()) {
+ case 1:
+ p.EnterOuterAlt(localctx, 1)
+ p.SetState(496)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for (int64((_la-29)) & ^0x3f) == 0 && ((int64(1)<<(_la-29))&68870471681) != 0 {
+ {
+ p.SetState(493)
+ p.ReadingStatement()
+ }
+
+ p.SetState(498)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+ p.SetState(508)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ switch p.GetTokenStream().LA(1) {
+ case CypherParserRETURN:
+ {
+ p.SetState(499)
+ p.ReturnSt()
+ }
+
+ case CypherParserCREATE, CypherParserDELETE, CypherParserDETACH, CypherParserMERGE, CypherParserREMOVE, CypherParserSET:
+ p.SetState(501)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for ok := true; ok; ok = ((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&1460503285407416320) != 0) {
+ {
+ p.SetState(500)
+ p.UpdatingStatement()
+ }
+
+ p.SetState(503)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+ p.SetState(506)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserRETURN {
+ {
+ p.SetState(505)
+ p.ReturnSt()
+ }
+
+ }
+
+ case CypherParserEOF, CypherParserSEMI, CypherParserRBRACE, CypherParserUNION:
+
+ default:
+ }
+
+ case 2:
+ p.EnterOuterAlt(localctx, 2)
+ {
+ p.SetState(510)
+ p.CallSubquery()
+ }
+ p.SetState(512)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserORDER {
+ {
+ p.SetState(511)
+ p.OrderSt()
+ }
+
+ }
+
+ case antlr.ATNInvalidAltNumber:
+ goto errorExit
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IMultiPartQContext is an interface to support dynamic dispatch.
+type IMultiPartQContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ SinglePartQ() ISinglePartQContext
+ AllWithSt() []IWithStContext
+ WithSt(i int) IWithStContext
+ AllReadingStatement() []IReadingStatementContext
+ ReadingStatement(i int) IReadingStatementContext
+ AllUpdatingStatement() []IUpdatingStatementContext
+ UpdatingStatement(i int) IUpdatingStatementContext
+
+ // IsMultiPartQContext differentiates from other interfaces.
+ IsMultiPartQContext()
+}
+
+type MultiPartQContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyMultiPartQContext() *MultiPartQContext {
+ var p = new(MultiPartQContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_multiPartQ
+ return p
+}
+
+func InitEmptyMultiPartQContext(p *MultiPartQContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_multiPartQ
+}
+
+func (*MultiPartQContext) IsMultiPartQContext() {}
+
+func NewMultiPartQContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *MultiPartQContext {
+ var p = new(MultiPartQContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_multiPartQ
+
+ return p
+}
+
+func (s *MultiPartQContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *MultiPartQContext) SinglePartQ() ISinglePartQContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ISinglePartQContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ISinglePartQContext)
+}
+
+func (s *MultiPartQContext) AllWithSt() []IWithStContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IWithStContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IWithStContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IWithStContext); ok {
+ tst[i] = t.(IWithStContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *MultiPartQContext) WithSt(i int) IWithStContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IWithStContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IWithStContext)
+}
+
+func (s *MultiPartQContext) AllReadingStatement() []IReadingStatementContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IReadingStatementContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IReadingStatementContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IReadingStatementContext); ok {
+ tst[i] = t.(IReadingStatementContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *MultiPartQContext) ReadingStatement(i int) IReadingStatementContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IReadingStatementContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IReadingStatementContext)
+}
+
+func (s *MultiPartQContext) AllUpdatingStatement() []IUpdatingStatementContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IUpdatingStatementContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IUpdatingStatementContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IUpdatingStatementContext); ok {
+ tst[i] = t.(IUpdatingStatementContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *MultiPartQContext) UpdatingStatement(i int) IUpdatingStatementContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IUpdatingStatementContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IUpdatingStatementContext)
+}
+
+func (s *MultiPartQContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *MultiPartQContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *MultiPartQContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterMultiPartQ(s)
+ }
+}
+
+func (s *MultiPartQContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitMultiPartQ(s)
+ }
+}
+
+func (p *CypherParser) MultiPartQ() (localctx IMultiPartQContext) {
+ localctx = NewMultiPartQContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 44, CypherParserRULE_multiPartQ)
+ var _la int
+
+ var _alt int
+
+ p.EnterOuterAlt(localctx, 1)
+ p.SetState(524)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _alt = 1
+ for ok := true; ok; ok = _alt != 2 && _alt != antlr.ATNInvalidAltNumber {
+ switch _alt {
+ case 1:
+ p.SetState(520)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for (int64((_la-29)) & ^0x3f) == 0 && ((int64(1)<<(_la-29))&71590871041) != 0 {
+ p.SetState(518)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetTokenStream().LA(1) {
+ case CypherParserCALL, CypherParserMATCH, CypherParserOPTIONAL, CypherParserUNWIND:
+ {
+ p.SetState(516)
+ p.ReadingStatement()
+ }
+
+ case CypherParserCREATE, CypherParserDELETE, CypherParserDETACH, CypherParserMERGE, CypherParserREMOVE, CypherParserSET:
+ {
+ p.SetState(517)
+ p.UpdatingStatement()
+ }
+
+ default:
+ p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil))
+ goto errorExit
+ }
+
+ p.SetState(522)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+ {
+ p.SetState(523)
+ p.WithSt()
+ }
+
+ default:
+ p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil))
+ goto errorExit
+ }
+
+ p.SetState(526)
+ p.GetErrorHandler().Sync(p)
+ _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 66, p.GetParserRuleContext())
+ if p.HasError() {
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(528)
+ p.SinglePartQ()
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IMatchStContext is an interface to support dynamic dispatch.
+type IMatchStContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ MATCH() antlr.TerminalNode
+ PatternWhere() IPatternWhereContext
+ OPTIONAL() antlr.TerminalNode
+
+ // IsMatchStContext differentiates from other interfaces.
+ IsMatchStContext()
+}
+
+type MatchStContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyMatchStContext() *MatchStContext {
+ var p = new(MatchStContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_matchSt
+ return p
+}
+
+func InitEmptyMatchStContext(p *MatchStContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_matchSt
+}
+
+func (*MatchStContext) IsMatchStContext() {}
+
+func NewMatchStContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *MatchStContext {
+ var p = new(MatchStContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_matchSt
+
+ return p
+}
+
+func (s *MatchStContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *MatchStContext) MATCH() antlr.TerminalNode {
+ return s.GetToken(CypherParserMATCH, 0)
+}
+
+func (s *MatchStContext) PatternWhere() IPatternWhereContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IPatternWhereContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IPatternWhereContext)
+}
+
+func (s *MatchStContext) OPTIONAL() antlr.TerminalNode {
+ return s.GetToken(CypherParserOPTIONAL, 0)
+}
+
+func (s *MatchStContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *MatchStContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *MatchStContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterMatchSt(s)
+ }
+}
+
+func (s *MatchStContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitMatchSt(s)
+ }
+}
+
+func (p *CypherParser) MatchSt() (localctx IMatchStContext) {
+ localctx = NewMatchStContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 46, CypherParserRULE_matchSt)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ p.SetState(531)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserOPTIONAL {
+ {
+ p.SetState(530)
+ p.Match(CypherParserOPTIONAL)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ }
+ {
+ p.SetState(533)
+ p.Match(CypherParserMATCH)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(534)
+ p.PatternWhere()
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IUnwindStContext is an interface to support dynamic dispatch.
+type IUnwindStContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ UNWIND() antlr.TerminalNode
+ Expression() IExpressionContext
+ AS() antlr.TerminalNode
+ Symbol() ISymbolContext
+ Where() IWhereContext
+
+ // IsUnwindStContext differentiates from other interfaces.
+ IsUnwindStContext()
+}
+
+type UnwindStContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyUnwindStContext() *UnwindStContext {
+ var p = new(UnwindStContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_unwindSt
+ return p
+}
+
+func InitEmptyUnwindStContext(p *UnwindStContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_unwindSt
+}
+
+func (*UnwindStContext) IsUnwindStContext() {}
+
+func NewUnwindStContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *UnwindStContext {
+ var p = new(UnwindStContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_unwindSt
+
+ return p
+}
+
+func (s *UnwindStContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *UnwindStContext) UNWIND() antlr.TerminalNode {
+ return s.GetToken(CypherParserUNWIND, 0)
+}
+
+func (s *UnwindStContext) Expression() IExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IExpressionContext)
+}
+
+func (s *UnwindStContext) AS() antlr.TerminalNode {
+ return s.GetToken(CypherParserAS, 0)
+}
+
+func (s *UnwindStContext) Symbol() ISymbolContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ISymbolContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ISymbolContext)
+}
+
+func (s *UnwindStContext) Where() IWhereContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IWhereContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IWhereContext)
+}
+
+func (s *UnwindStContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *UnwindStContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *UnwindStContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterUnwindSt(s)
+ }
+}
+
+func (s *UnwindStContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitUnwindSt(s)
+ }
+}
+
+func (p *CypherParser) UnwindSt() (localctx IUnwindStContext) {
+ localctx = NewUnwindStContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 48, CypherParserRULE_unwindSt)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(536)
+ p.Match(CypherParserUNWIND)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(537)
+ p.Expression()
+ }
+ {
+ p.SetState(538)
+ p.Match(CypherParserAS)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(539)
+ p.Symbol()
+ }
+ p.SetState(541)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserWHERE {
+ {
+ p.SetState(540)
+ p.Where()
+ }
+
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IReadingStatementContext is an interface to support dynamic dispatch.
+type IReadingStatementContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ MatchSt() IMatchStContext
+ UnwindSt() IUnwindStContext
+ QueryCallSt() IQueryCallStContext
+ CallSubquery() ICallSubqueryContext
+
+ // IsReadingStatementContext differentiates from other interfaces.
+ IsReadingStatementContext()
+}
+
+type ReadingStatementContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyReadingStatementContext() *ReadingStatementContext {
+ var p = new(ReadingStatementContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_readingStatement
+ return p
+}
+
+func InitEmptyReadingStatementContext(p *ReadingStatementContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_readingStatement
+}
+
+func (*ReadingStatementContext) IsReadingStatementContext() {}
+
+func NewReadingStatementContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ReadingStatementContext {
+ var p = new(ReadingStatementContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_readingStatement
+
+ return p
+}
+
+func (s *ReadingStatementContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *ReadingStatementContext) MatchSt() IMatchStContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IMatchStContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IMatchStContext)
+}
+
+func (s *ReadingStatementContext) UnwindSt() IUnwindStContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IUnwindStContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IUnwindStContext)
+}
+
+func (s *ReadingStatementContext) QueryCallSt() IQueryCallStContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IQueryCallStContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IQueryCallStContext)
+}
+
+func (s *ReadingStatementContext) CallSubquery() ICallSubqueryContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ICallSubqueryContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ICallSubqueryContext)
+}
+
+func (s *ReadingStatementContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *ReadingStatementContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *ReadingStatementContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterReadingStatement(s)
+ }
+}
+
+func (s *ReadingStatementContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitReadingStatement(s)
+ }
+}
+
+func (p *CypherParser) ReadingStatement() (localctx IReadingStatementContext) {
+ localctx = NewReadingStatementContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 50, CypherParserRULE_readingStatement)
+ p.SetState(547)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 69, p.GetParserRuleContext()) {
+ case 1:
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(543)
+ p.MatchSt()
+ }
+
+ case 2:
+ p.EnterOuterAlt(localctx, 2)
+ {
+ p.SetState(544)
+ p.UnwindSt()
+ }
+
+ case 3:
+ p.EnterOuterAlt(localctx, 3)
+ {
+ p.SetState(545)
+ p.QueryCallSt()
+ }
+
+ case 4:
+ p.EnterOuterAlt(localctx, 4)
+ {
+ p.SetState(546)
+ p.CallSubquery()
+ }
+
+ case antlr.ATNInvalidAltNumber:
+ goto errorExit
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IUpdatingStatementContext is an interface to support dynamic dispatch.
+type IUpdatingStatementContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ CreateSt() ICreateStContext
+ MergeSt() IMergeStContext
+ DeleteSt() IDeleteStContext
+ SetSt() ISetStContext
+ RemoveSt() IRemoveStContext
+
+ // IsUpdatingStatementContext differentiates from other interfaces.
+ IsUpdatingStatementContext()
+}
+
+type UpdatingStatementContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyUpdatingStatementContext() *UpdatingStatementContext {
+ var p = new(UpdatingStatementContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_updatingStatement
+ return p
+}
+
+func InitEmptyUpdatingStatementContext(p *UpdatingStatementContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_updatingStatement
+}
+
+func (*UpdatingStatementContext) IsUpdatingStatementContext() {}
+
+func NewUpdatingStatementContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *UpdatingStatementContext {
+ var p = new(UpdatingStatementContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_updatingStatement
+
+ return p
+}
+
+func (s *UpdatingStatementContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *UpdatingStatementContext) CreateSt() ICreateStContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ICreateStContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ICreateStContext)
+}
+
+func (s *UpdatingStatementContext) MergeSt() IMergeStContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IMergeStContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IMergeStContext)
+}
+
+func (s *UpdatingStatementContext) DeleteSt() IDeleteStContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IDeleteStContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IDeleteStContext)
+}
+
+func (s *UpdatingStatementContext) SetSt() ISetStContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ISetStContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ISetStContext)
+}
+
+func (s *UpdatingStatementContext) RemoveSt() IRemoveStContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IRemoveStContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IRemoveStContext)
+}
+
+func (s *UpdatingStatementContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *UpdatingStatementContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *UpdatingStatementContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterUpdatingStatement(s)
+ }
+}
+
+func (s *UpdatingStatementContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitUpdatingStatement(s)
+ }
+}
+
+func (p *CypherParser) UpdatingStatement() (localctx IUpdatingStatementContext) {
+ localctx = NewUpdatingStatementContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 52, CypherParserRULE_updatingStatement)
+ p.SetState(554)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetTokenStream().LA(1) {
+ case CypherParserCREATE:
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(549)
+ p.CreateSt()
+ }
+
+ case CypherParserMERGE:
+ p.EnterOuterAlt(localctx, 2)
+ {
+ p.SetState(550)
+ p.MergeSt()
+ }
+
+ case CypherParserDELETE, CypherParserDETACH:
+ p.EnterOuterAlt(localctx, 3)
+ {
+ p.SetState(551)
+ p.DeleteSt()
+ }
+
+ case CypherParserSET:
+ p.EnterOuterAlt(localctx, 4)
+ {
+ p.SetState(552)
+ p.SetSt()
+ }
+
+ case CypherParserREMOVE:
+ p.EnterOuterAlt(localctx, 5)
+ {
+ p.SetState(553)
+ p.RemoveSt()
+ }
+
+ default:
+ p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil))
+ goto errorExit
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IDeleteStContext is an interface to support dynamic dispatch.
+type IDeleteStContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ DELETE() antlr.TerminalNode
+ ExpressionChain() IExpressionChainContext
+ DETACH() antlr.TerminalNode
+
+ // IsDeleteStContext differentiates from other interfaces.
+ IsDeleteStContext()
+}
+
+type DeleteStContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyDeleteStContext() *DeleteStContext {
+ var p = new(DeleteStContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_deleteSt
+ return p
+}
+
+func InitEmptyDeleteStContext(p *DeleteStContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_deleteSt
+}
+
+func (*DeleteStContext) IsDeleteStContext() {}
+
+func NewDeleteStContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *DeleteStContext {
+ var p = new(DeleteStContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_deleteSt
+
+ return p
+}
+
+func (s *DeleteStContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *DeleteStContext) DELETE() antlr.TerminalNode {
+ return s.GetToken(CypherParserDELETE, 0)
+}
+
+func (s *DeleteStContext) ExpressionChain() IExpressionChainContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IExpressionChainContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IExpressionChainContext)
+}
+
+func (s *DeleteStContext) DETACH() antlr.TerminalNode {
+ return s.GetToken(CypherParserDETACH, 0)
+}
+
+func (s *DeleteStContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *DeleteStContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *DeleteStContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterDeleteSt(s)
+ }
+}
+
+func (s *DeleteStContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitDeleteSt(s)
+ }
+}
+
+func (p *CypherParser) DeleteSt() (localctx IDeleteStContext) {
+ localctx = NewDeleteStContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 54, CypherParserRULE_deleteSt)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ p.SetState(557)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserDETACH {
+ {
+ p.SetState(556)
+ p.Match(CypherParserDETACH)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ }
+ {
+ p.SetState(559)
+ p.Match(CypherParserDELETE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(560)
+ p.ExpressionChain()
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IRemoveStContext is an interface to support dynamic dispatch.
+type IRemoveStContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ REMOVE() antlr.TerminalNode
+ AllRemoveItem() []IRemoveItemContext
+ RemoveItem(i int) IRemoveItemContext
+ AllCOMMA() []antlr.TerminalNode
+ COMMA(i int) antlr.TerminalNode
+
+ // IsRemoveStContext differentiates from other interfaces.
+ IsRemoveStContext()
+}
+
+type RemoveStContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyRemoveStContext() *RemoveStContext {
+ var p = new(RemoveStContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_removeSt
+ return p
+}
+
+func InitEmptyRemoveStContext(p *RemoveStContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_removeSt
+}
+
+func (*RemoveStContext) IsRemoveStContext() {}
+
+func NewRemoveStContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *RemoveStContext {
+ var p = new(RemoveStContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_removeSt
+
+ return p
+}
+
+func (s *RemoveStContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *RemoveStContext) REMOVE() antlr.TerminalNode {
+ return s.GetToken(CypherParserREMOVE, 0)
+}
+
+func (s *RemoveStContext) AllRemoveItem() []IRemoveItemContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IRemoveItemContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IRemoveItemContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IRemoveItemContext); ok {
+ tst[i] = t.(IRemoveItemContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *RemoveStContext) RemoveItem(i int) IRemoveItemContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IRemoveItemContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IRemoveItemContext)
+}
+
+func (s *RemoveStContext) AllCOMMA() []antlr.TerminalNode {
+ return s.GetTokens(CypherParserCOMMA)
+}
+
+func (s *RemoveStContext) COMMA(i int) antlr.TerminalNode {
+ return s.GetToken(CypherParserCOMMA, i)
+}
+
+func (s *RemoveStContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *RemoveStContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *RemoveStContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterRemoveSt(s)
+ }
+}
+
+func (s *RemoveStContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitRemoveSt(s)
+ }
+}
+
+func (p *CypherParser) RemoveSt() (localctx IRemoveStContext) {
+ localctx = NewRemoveStContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 56, CypherParserRULE_removeSt)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(562)
+ p.Match(CypherParserREMOVE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(563)
+ p.RemoveItem()
+ }
+ p.SetState(568)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for _la == CypherParserCOMMA {
+ {
+ p.SetState(564)
+ p.Match(CypherParserCOMMA)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(565)
+ p.RemoveItem()
+ }
+
+ p.SetState(570)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IRemoveItemContext is an interface to support dynamic dispatch.
+type IRemoveItemContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ Symbol() ISymbolContext
+ NodeLabels() INodeLabelsContext
+ PropertyExpression() IPropertyExpressionContext
+
+ // IsRemoveItemContext differentiates from other interfaces.
+ IsRemoveItemContext()
+}
+
+type RemoveItemContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyRemoveItemContext() *RemoveItemContext {
+ var p = new(RemoveItemContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_removeItem
+ return p
+}
+
+func InitEmptyRemoveItemContext(p *RemoveItemContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_removeItem
+}
+
+func (*RemoveItemContext) IsRemoveItemContext() {}
+
+func NewRemoveItemContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *RemoveItemContext {
+ var p = new(RemoveItemContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_removeItem
+
+ return p
+}
+
+func (s *RemoveItemContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *RemoveItemContext) Symbol() ISymbolContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ISymbolContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ISymbolContext)
+}
+
+func (s *RemoveItemContext) NodeLabels() INodeLabelsContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(INodeLabelsContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(INodeLabelsContext)
+}
+
+func (s *RemoveItemContext) PropertyExpression() IPropertyExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IPropertyExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IPropertyExpressionContext)
+}
+
+func (s *RemoveItemContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *RemoveItemContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *RemoveItemContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterRemoveItem(s)
+ }
+}
+
+func (s *RemoveItemContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitRemoveItem(s)
+ }
+}
+
+func (p *CypherParser) RemoveItem() (localctx IRemoveItemContext) {
+ localctx = NewRemoveItemContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 58, CypherParserRULE_removeItem)
+ p.SetState(575)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 73, p.GetParserRuleContext()) {
+ case 1:
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(571)
+ p.Symbol()
+ }
+ {
+ p.SetState(572)
+ p.NodeLabels()
+ }
+
+ case 2:
+ p.EnterOuterAlt(localctx, 2)
+ {
+ p.SetState(574)
+ p.PropertyExpression()
+ }
+
+ case antlr.ATNInvalidAltNumber:
+ goto errorExit
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IQueryCallStContext is an interface to support dynamic dispatch.
+type IQueryCallStContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ CALL() antlr.TerminalNode
+ InvocationName() IInvocationNameContext
+ ParenExpressionChain() IParenExpressionChainContext
+ YIELD() antlr.TerminalNode
+ YieldItems() IYieldItemsContext
+
+ // IsQueryCallStContext differentiates from other interfaces.
+ IsQueryCallStContext()
+}
+
+type QueryCallStContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyQueryCallStContext() *QueryCallStContext {
+ var p = new(QueryCallStContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_queryCallSt
+ return p
+}
+
+func InitEmptyQueryCallStContext(p *QueryCallStContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_queryCallSt
+}
+
+func (*QueryCallStContext) IsQueryCallStContext() {}
+
+func NewQueryCallStContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *QueryCallStContext {
+ var p = new(QueryCallStContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_queryCallSt
+
+ return p
+}
+
+func (s *QueryCallStContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *QueryCallStContext) CALL() antlr.TerminalNode {
+ return s.GetToken(CypherParserCALL, 0)
+}
+
+func (s *QueryCallStContext) InvocationName() IInvocationNameContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IInvocationNameContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IInvocationNameContext)
+}
+
+func (s *QueryCallStContext) ParenExpressionChain() IParenExpressionChainContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IParenExpressionChainContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IParenExpressionChainContext)
+}
+
+func (s *QueryCallStContext) YIELD() antlr.TerminalNode {
+ return s.GetToken(CypherParserYIELD, 0)
+}
+
+func (s *QueryCallStContext) YieldItems() IYieldItemsContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IYieldItemsContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IYieldItemsContext)
+}
+
+func (s *QueryCallStContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *QueryCallStContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *QueryCallStContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterQueryCallSt(s)
+ }
+}
+
+func (s *QueryCallStContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitQueryCallSt(s)
+ }
+}
+
+func (p *CypherParser) QueryCallSt() (localctx IQueryCallStContext) {
+ localctx = NewQueryCallStContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 60, CypherParserRULE_queryCallSt)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(577)
+ p.Match(CypherParserCALL)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(578)
+ p.InvocationName()
+ }
+ {
+ p.SetState(579)
+ p.ParenExpressionChain()
+ }
+ p.SetState(582)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserYIELD {
+ {
+ p.SetState(580)
+ p.Match(CypherParserYIELD)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(581)
+ p.YieldItems()
+ }
+
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IParenExpressionChainContext is an interface to support dynamic dispatch.
+type IParenExpressionChainContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ LPAREN() antlr.TerminalNode
+ RPAREN() antlr.TerminalNode
+ ExpressionChain() IExpressionChainContext
+
+ // IsParenExpressionChainContext differentiates from other interfaces.
+ IsParenExpressionChainContext()
+}
+
+type ParenExpressionChainContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyParenExpressionChainContext() *ParenExpressionChainContext {
+ var p = new(ParenExpressionChainContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_parenExpressionChain
+ return p
+}
+
+func InitEmptyParenExpressionChainContext(p *ParenExpressionChainContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_parenExpressionChain
+}
+
+func (*ParenExpressionChainContext) IsParenExpressionChainContext() {}
+
+func NewParenExpressionChainContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ParenExpressionChainContext {
+ var p = new(ParenExpressionChainContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_parenExpressionChain
+
+ return p
+}
+
+func (s *ParenExpressionChainContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *ParenExpressionChainContext) LPAREN() antlr.TerminalNode {
+ return s.GetToken(CypherParserLPAREN, 0)
+}
+
+func (s *ParenExpressionChainContext) RPAREN() antlr.TerminalNode {
+ return s.GetToken(CypherParserRPAREN, 0)
+}
+
+func (s *ParenExpressionChainContext) ExpressionChain() IExpressionChainContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IExpressionChainContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IExpressionChainContext)
+}
+
+func (s *ParenExpressionChainContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *ParenExpressionChainContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *ParenExpressionChainContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterParenExpressionChain(s)
+ }
+}
+
+func (s *ParenExpressionChainContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitParenExpressionChain(s)
+ }
+}
+
+func (p *CypherParser) ParenExpressionChain() (localctx IParenExpressionChainContext) {
+ localctx = NewParenExpressionChainContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 62, CypherParserRULE_parenExpressionChain)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(584)
+ p.Match(CypherParserLPAREN)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(586)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if ((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&1470645178784718848) != 0) || ((int64((_la-73)) & ^0x3f) == 0 && ((int64(1)<<(_la-73))&2251795417136369) != 0) {
+ {
+ p.SetState(585)
+ p.ExpressionChain()
+ }
+
+ }
+ {
+ p.SetState(588)
+ p.Match(CypherParserRPAREN)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IYieldItemsContext is an interface to support dynamic dispatch.
+type IYieldItemsContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ AllYieldItem() []IYieldItemContext
+ YieldItem(i int) IYieldItemContext
+ AllCOMMA() []antlr.TerminalNode
+ COMMA(i int) antlr.TerminalNode
+ Where() IWhereContext
+
+ // IsYieldItemsContext differentiates from other interfaces.
+ IsYieldItemsContext()
+}
+
+type YieldItemsContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyYieldItemsContext() *YieldItemsContext {
+ var p = new(YieldItemsContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_yieldItems
+ return p
+}
+
+func InitEmptyYieldItemsContext(p *YieldItemsContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_yieldItems
+}
+
+func (*YieldItemsContext) IsYieldItemsContext() {}
+
+func NewYieldItemsContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *YieldItemsContext {
+ var p = new(YieldItemsContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_yieldItems
+
+ return p
+}
+
+func (s *YieldItemsContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *YieldItemsContext) AllYieldItem() []IYieldItemContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IYieldItemContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IYieldItemContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IYieldItemContext); ok {
+ tst[i] = t.(IYieldItemContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *YieldItemsContext) YieldItem(i int) IYieldItemContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IYieldItemContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IYieldItemContext)
+}
+
+func (s *YieldItemsContext) AllCOMMA() []antlr.TerminalNode {
+ return s.GetTokens(CypherParserCOMMA)
+}
+
+func (s *YieldItemsContext) COMMA(i int) antlr.TerminalNode {
+ return s.GetToken(CypherParserCOMMA, i)
+}
+
+func (s *YieldItemsContext) Where() IWhereContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IWhereContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IWhereContext)
+}
+
+func (s *YieldItemsContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *YieldItemsContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *YieldItemsContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterYieldItems(s)
+ }
+}
+
+func (s *YieldItemsContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitYieldItems(s)
+ }
+}
+
+func (p *CypherParser) YieldItems() (localctx IYieldItemsContext) {
+ localctx = NewYieldItemsContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 64, CypherParserRULE_yieldItems)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(590)
+ p.YieldItem()
+ }
+ p.SetState(595)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for _la == CypherParserCOMMA {
+ {
+ p.SetState(591)
+ p.Match(CypherParserCOMMA)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(592)
+ p.YieldItem()
+ }
+
+ p.SetState(597)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+ p.SetState(599)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserWHERE {
+ {
+ p.SetState(598)
+ p.Where()
+ }
+
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IYieldItemContext is an interface to support dynamic dispatch.
+type IYieldItemContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ AllSymbol() []ISymbolContext
+ Symbol(i int) ISymbolContext
+ AS() antlr.TerminalNode
+
+ // IsYieldItemContext differentiates from other interfaces.
+ IsYieldItemContext()
+}
+
+type YieldItemContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyYieldItemContext() *YieldItemContext {
+ var p = new(YieldItemContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_yieldItem
+ return p
+}
+
+func InitEmptyYieldItemContext(p *YieldItemContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_yieldItem
+}
+
+func (*YieldItemContext) IsYieldItemContext() {}
+
+func NewYieldItemContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *YieldItemContext {
+ var p = new(YieldItemContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_yieldItem
+
+ return p
+}
+
+func (s *YieldItemContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *YieldItemContext) AllSymbol() []ISymbolContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(ISymbolContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]ISymbolContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(ISymbolContext); ok {
+ tst[i] = t.(ISymbolContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *YieldItemContext) Symbol(i int) ISymbolContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ISymbolContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ISymbolContext)
+}
+
+func (s *YieldItemContext) AS() antlr.TerminalNode {
+ return s.GetToken(CypherParserAS, 0)
+}
+
+func (s *YieldItemContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *YieldItemContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *YieldItemContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterYieldItem(s)
+ }
+}
+
+func (s *YieldItemContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitYieldItem(s)
+ }
+}
+
+func (p *CypherParser) YieldItem() (localctx IYieldItemContext) {
+ localctx = NewYieldItemContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 66, CypherParserRULE_yieldItem)
+ p.EnterOuterAlt(localctx, 1)
+ p.SetState(604)
+ p.GetErrorHandler().Sync(p)
+
+ if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 78, p.GetParserRuleContext()) == 1 {
+ {
+ p.SetState(601)
+ p.Symbol()
+ }
+ {
+ p.SetState(602)
+ p.Match(CypherParserAS)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ } else if p.HasError() { // JIM
+ goto errorExit
+ }
+ {
+ p.SetState(606)
+ p.Symbol()
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IMergeStContext is an interface to support dynamic dispatch.
+type IMergeStContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ MERGE() antlr.TerminalNode
+ PatternPart() IPatternPartContext
+ AllMergeAction() []IMergeActionContext
+ MergeAction(i int) IMergeActionContext
+
+ // IsMergeStContext differentiates from other interfaces.
+ IsMergeStContext()
+}
+
+type MergeStContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyMergeStContext() *MergeStContext {
+ var p = new(MergeStContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_mergeSt
+ return p
+}
+
+func InitEmptyMergeStContext(p *MergeStContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_mergeSt
+}
+
+func (*MergeStContext) IsMergeStContext() {}
+
+func NewMergeStContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *MergeStContext {
+ var p = new(MergeStContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_mergeSt
+
+ return p
+}
+
+func (s *MergeStContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *MergeStContext) MERGE() antlr.TerminalNode {
+ return s.GetToken(CypherParserMERGE, 0)
+}
+
+func (s *MergeStContext) PatternPart() IPatternPartContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IPatternPartContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IPatternPartContext)
+}
+
+func (s *MergeStContext) AllMergeAction() []IMergeActionContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IMergeActionContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IMergeActionContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IMergeActionContext); ok {
+ tst[i] = t.(IMergeActionContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *MergeStContext) MergeAction(i int) IMergeActionContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IMergeActionContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IMergeActionContext)
+}
+
+func (s *MergeStContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *MergeStContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *MergeStContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterMergeSt(s)
+ }
+}
+
+func (s *MergeStContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitMergeSt(s)
+ }
+}
+
+func (p *CypherParser) MergeSt() (localctx IMergeStContext) {
+ localctx = NewMergeStContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 68, CypherParserRULE_mergeSt)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(608)
+ p.Match(CypherParserMERGE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(609)
+ p.PatternPart()
+ }
+ p.SetState(613)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for _la == CypherParserON {
+ {
+ p.SetState(610)
+ p.MergeAction()
+ }
+
+ p.SetState(615)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IMergeActionContext is an interface to support dynamic dispatch.
+type IMergeActionContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ ON() antlr.TerminalNode
+ SetSt() ISetStContext
+ MATCH() antlr.TerminalNode
+ CREATE() antlr.TerminalNode
+
+ // IsMergeActionContext differentiates from other interfaces.
+ IsMergeActionContext()
+}
+
+type MergeActionContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyMergeActionContext() *MergeActionContext {
+ var p = new(MergeActionContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_mergeAction
+ return p
+}
+
+func InitEmptyMergeActionContext(p *MergeActionContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_mergeAction
+}
+
+func (*MergeActionContext) IsMergeActionContext() {}
+
+func NewMergeActionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *MergeActionContext {
+ var p = new(MergeActionContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_mergeAction
+
+ return p
+}
+
+func (s *MergeActionContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *MergeActionContext) ON() antlr.TerminalNode {
+ return s.GetToken(CypherParserON, 0)
+}
+
+func (s *MergeActionContext) SetSt() ISetStContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ISetStContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ISetStContext)
+}
+
+func (s *MergeActionContext) MATCH() antlr.TerminalNode {
+ return s.GetToken(CypherParserMATCH, 0)
+}
+
+func (s *MergeActionContext) CREATE() antlr.TerminalNode {
+ return s.GetToken(CypherParserCREATE, 0)
+}
+
+func (s *MergeActionContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *MergeActionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *MergeActionContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterMergeAction(s)
+ }
+}
+
+func (s *MergeActionContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitMergeAction(s)
+ }
+}
+
+func (p *CypherParser) MergeAction() (localctx IMergeActionContext) {
+ localctx = NewMergeActionContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 70, CypherParserRULE_mergeAction)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(616)
+ p.Match(CypherParserON)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(617)
+ _la = p.GetTokenStream().LA(1)
+
+ if !(_la == CypherParserCREATE || _la == CypherParserMATCH) {
+ p.GetErrorHandler().RecoverInline(p)
+ } else {
+ p.GetErrorHandler().ReportMatch(p)
+ p.Consume()
+ }
+ }
+ {
+ p.SetState(618)
+ p.SetSt()
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// ISetStContext is an interface to support dynamic dispatch.
+type ISetStContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ SET() antlr.TerminalNode
+ AllSetItem() []ISetItemContext
+ SetItem(i int) ISetItemContext
+ AllCOMMA() []antlr.TerminalNode
+ COMMA(i int) antlr.TerminalNode
+
+ // IsSetStContext differentiates from other interfaces.
+ IsSetStContext()
+}
+
+type SetStContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptySetStContext() *SetStContext {
+ var p = new(SetStContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_setSt
+ return p
+}
+
+func InitEmptySetStContext(p *SetStContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_setSt
+}
+
+func (*SetStContext) IsSetStContext() {}
+
+func NewSetStContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *SetStContext {
+ var p = new(SetStContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_setSt
+
+ return p
+}
+
+func (s *SetStContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *SetStContext) SET() antlr.TerminalNode {
+ return s.GetToken(CypherParserSET, 0)
+}
+
+func (s *SetStContext) AllSetItem() []ISetItemContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(ISetItemContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]ISetItemContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(ISetItemContext); ok {
+ tst[i] = t.(ISetItemContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *SetStContext) SetItem(i int) ISetItemContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ISetItemContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ISetItemContext)
+}
+
+func (s *SetStContext) AllCOMMA() []antlr.TerminalNode {
+ return s.GetTokens(CypherParserCOMMA)
+}
+
+func (s *SetStContext) COMMA(i int) antlr.TerminalNode {
+ return s.GetToken(CypherParserCOMMA, i)
+}
+
+func (s *SetStContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *SetStContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *SetStContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterSetSt(s)
+ }
+}
+
+func (s *SetStContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitSetSt(s)
+ }
+}
+
+func (p *CypherParser) SetSt() (localctx ISetStContext) {
+ localctx = NewSetStContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 72, CypherParserRULE_setSt)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(620)
+ p.Match(CypherParserSET)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(621)
+ p.SetItem()
+ }
+ p.SetState(626)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for _la == CypherParserCOMMA {
+ {
+ p.SetState(622)
+ p.Match(CypherParserCOMMA)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(623)
+ p.SetItem()
+ }
+
+ p.SetState(628)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// ISetItemContext is an interface to support dynamic dispatch.
+type ISetItemContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ PropertyExpression() IPropertyExpressionContext
+ ASSIGN() antlr.TerminalNode
+ Expression() IExpressionContext
+ Symbol() ISymbolContext
+ ADD_ASSIGN() antlr.TerminalNode
+ NodeLabels() INodeLabelsContext
+
+ // IsSetItemContext differentiates from other interfaces.
+ IsSetItemContext()
+}
+
+type SetItemContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptySetItemContext() *SetItemContext {
+ var p = new(SetItemContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_setItem
+ return p
+}
+
+func InitEmptySetItemContext(p *SetItemContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_setItem
+}
+
+func (*SetItemContext) IsSetItemContext() {}
+
+func NewSetItemContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *SetItemContext {
+ var p = new(SetItemContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_setItem
+
+ return p
+}
+
+func (s *SetItemContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *SetItemContext) PropertyExpression() IPropertyExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IPropertyExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IPropertyExpressionContext)
+}
+
+func (s *SetItemContext) ASSIGN() antlr.TerminalNode {
+ return s.GetToken(CypherParserASSIGN, 0)
+}
+
+func (s *SetItemContext) Expression() IExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IExpressionContext)
+}
+
+func (s *SetItemContext) Symbol() ISymbolContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ISymbolContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ISymbolContext)
+}
+
+func (s *SetItemContext) ADD_ASSIGN() antlr.TerminalNode {
+ return s.GetToken(CypherParserADD_ASSIGN, 0)
+}
+
+func (s *SetItemContext) NodeLabels() INodeLabelsContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(INodeLabelsContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(INodeLabelsContext)
+}
+
+func (s *SetItemContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *SetItemContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *SetItemContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterSetItem(s)
+ }
+}
+
+func (s *SetItemContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitSetItem(s)
+ }
+}
+
+func (p *CypherParser) SetItem() (localctx ISetItemContext) {
+ localctx = NewSetItemContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 74, CypherParserRULE_setItem)
+ var _la int
+
+ p.SetState(640)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 81, p.GetParserRuleContext()) {
+ case 1:
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(629)
+ p.PropertyExpression()
+ }
+ {
+ p.SetState(630)
+ p.Match(CypherParserASSIGN)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(631)
+ p.Expression()
+ }
+
+ case 2:
+ p.EnterOuterAlt(localctx, 2)
+ {
+ p.SetState(633)
+ p.Symbol()
+ }
+ {
+ p.SetState(634)
+ _la = p.GetTokenStream().LA(1)
+
+ if !(_la == CypherParserASSIGN || _la == CypherParserADD_ASSIGN) {
+ p.GetErrorHandler().RecoverInline(p)
+ } else {
+ p.GetErrorHandler().ReportMatch(p)
+ p.Consume()
+ }
+ }
+ {
+ p.SetState(635)
+ p.Expression()
+ }
+
+ case 3:
+ p.EnterOuterAlt(localctx, 3)
+ {
+ p.SetState(637)
+ p.Symbol()
+ }
+ {
+ p.SetState(638)
+ p.NodeLabels()
+ }
+
+ case antlr.ATNInvalidAltNumber:
+ goto errorExit
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// INodeLabelsContext is an interface to support dynamic dispatch.
+type INodeLabelsContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ AllCOLON() []antlr.TerminalNode
+ COLON(i int) antlr.TerminalNode
+ AllName() []INameContext
+ Name(i int) INameContext
+
+ // IsNodeLabelsContext differentiates from other interfaces.
+ IsNodeLabelsContext()
+}
+
+type NodeLabelsContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyNodeLabelsContext() *NodeLabelsContext {
+ var p = new(NodeLabelsContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_nodeLabels
+ return p
+}
+
+func InitEmptyNodeLabelsContext(p *NodeLabelsContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_nodeLabels
+}
+
+func (*NodeLabelsContext) IsNodeLabelsContext() {}
+
+func NewNodeLabelsContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *NodeLabelsContext {
+ var p = new(NodeLabelsContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_nodeLabels
+
+ return p
+}
+
+func (s *NodeLabelsContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *NodeLabelsContext) AllCOLON() []antlr.TerminalNode {
+ return s.GetTokens(CypherParserCOLON)
+}
+
+func (s *NodeLabelsContext) COLON(i int) antlr.TerminalNode {
+ return s.GetToken(CypherParserCOLON, i)
+}
+
+func (s *NodeLabelsContext) AllName() []INameContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(INameContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]INameContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(INameContext); ok {
+ tst[i] = t.(INameContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *NodeLabelsContext) Name(i int) INameContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(INameContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(INameContext)
+}
+
+func (s *NodeLabelsContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *NodeLabelsContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *NodeLabelsContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterNodeLabels(s)
+ }
+}
+
+func (s *NodeLabelsContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitNodeLabels(s)
+ }
+}
+
+func (p *CypherParser) NodeLabels() (localctx INodeLabelsContext) {
+ localctx = NewNodeLabelsContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 76, CypherParserRULE_nodeLabels)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ p.SetState(644)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for ok := true; ok; ok = _la == CypherParserCOLON {
+ {
+ p.SetState(642)
+ p.Match(CypherParserCOLON)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(643)
+ p.Name()
+ }
+
+ p.SetState(646)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// ICreateStContext is an interface to support dynamic dispatch.
+type ICreateStContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ CREATE() antlr.TerminalNode
+ Pattern() IPatternContext
+
+ // IsCreateStContext differentiates from other interfaces.
+ IsCreateStContext()
+}
+
+type CreateStContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyCreateStContext() *CreateStContext {
+ var p = new(CreateStContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_createSt
+ return p
+}
+
+func InitEmptyCreateStContext(p *CreateStContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_createSt
+}
+
+func (*CreateStContext) IsCreateStContext() {}
+
+func NewCreateStContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *CreateStContext {
+ var p = new(CreateStContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_createSt
+
+ return p
+}
+
+func (s *CreateStContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *CreateStContext) CREATE() antlr.TerminalNode {
+ return s.GetToken(CypherParserCREATE, 0)
+}
+
+func (s *CreateStContext) Pattern() IPatternContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IPatternContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IPatternContext)
+}
+
+func (s *CreateStContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *CreateStContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *CreateStContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterCreateSt(s)
+ }
+}
+
+func (s *CreateStContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitCreateSt(s)
+ }
+}
+
+func (p *CypherParser) CreateSt() (localctx ICreateStContext) {
+ localctx = NewCreateStContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 78, CypherParserRULE_createSt)
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(648)
+ p.Match(CypherParserCREATE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(649)
+ p.Pattern()
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IPatternWhereContext is an interface to support dynamic dispatch.
+type IPatternWhereContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ Pattern() IPatternContext
+ Where() IWhereContext
+
+ // IsPatternWhereContext differentiates from other interfaces.
+ IsPatternWhereContext()
+}
+
+type PatternWhereContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyPatternWhereContext() *PatternWhereContext {
+ var p = new(PatternWhereContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_patternWhere
+ return p
+}
+
+func InitEmptyPatternWhereContext(p *PatternWhereContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_patternWhere
+}
+
+func (*PatternWhereContext) IsPatternWhereContext() {}
+
+func NewPatternWhereContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *PatternWhereContext {
+ var p = new(PatternWhereContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_patternWhere
+
+ return p
+}
+
+func (s *PatternWhereContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *PatternWhereContext) Pattern() IPatternContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IPatternContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IPatternContext)
+}
+
+func (s *PatternWhereContext) Where() IWhereContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IWhereContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IWhereContext)
+}
+
+func (s *PatternWhereContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *PatternWhereContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *PatternWhereContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterPatternWhere(s)
+ }
+}
+
+func (s *PatternWhereContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitPatternWhere(s)
+ }
+}
+
+func (p *CypherParser) PatternWhere() (localctx IPatternWhereContext) {
+ localctx = NewPatternWhereContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 80, CypherParserRULE_patternWhere)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(651)
+ p.Pattern()
+ }
+ p.SetState(653)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserWHERE {
+ {
+ p.SetState(652)
+ p.Where()
+ }
+
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IWhereContext is an interface to support dynamic dispatch.
+type IWhereContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ WHERE() antlr.TerminalNode
+ Expression() IExpressionContext
+
+ // IsWhereContext differentiates from other interfaces.
+ IsWhereContext()
+}
+
+type WhereContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyWhereContext() *WhereContext {
+ var p = new(WhereContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_where
+ return p
+}
+
+func InitEmptyWhereContext(p *WhereContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_where
+}
+
+func (*WhereContext) IsWhereContext() {}
+
+func NewWhereContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *WhereContext {
+ var p = new(WhereContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_where
+
+ return p
+}
+
+func (s *WhereContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *WhereContext) WHERE() antlr.TerminalNode {
+ return s.GetToken(CypherParserWHERE, 0)
+}
+
+func (s *WhereContext) Expression() IExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IExpressionContext)
+}
+
+func (s *WhereContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *WhereContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *WhereContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterWhere(s)
+ }
+}
+
+func (s *WhereContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitWhere(s)
+ }
+}
+
+func (p *CypherParser) Where() (localctx IWhereContext) {
+ localctx = NewWhereContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 82, CypherParserRULE_where)
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(655)
+ p.Match(CypherParserWHERE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(656)
+ p.Expression()
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IPatternContext is an interface to support dynamic dispatch.
+type IPatternContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ AllPatternPart() []IPatternPartContext
+ PatternPart(i int) IPatternPartContext
+ AllCOMMA() []antlr.TerminalNode
+ COMMA(i int) antlr.TerminalNode
+
+ // IsPatternContext differentiates from other interfaces.
+ IsPatternContext()
+}
+
+type PatternContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyPatternContext() *PatternContext {
+ var p = new(PatternContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_pattern
+ return p
+}
+
+func InitEmptyPatternContext(p *PatternContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_pattern
+}
+
+func (*PatternContext) IsPatternContext() {}
+
+func NewPatternContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *PatternContext {
+ var p = new(PatternContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_pattern
+
+ return p
+}
+
+func (s *PatternContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *PatternContext) AllPatternPart() []IPatternPartContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IPatternPartContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IPatternPartContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IPatternPartContext); ok {
+ tst[i] = t.(IPatternPartContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *PatternContext) PatternPart(i int) IPatternPartContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IPatternPartContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IPatternPartContext)
+}
+
+func (s *PatternContext) AllCOMMA() []antlr.TerminalNode {
+ return s.GetTokens(CypherParserCOMMA)
+}
+
+func (s *PatternContext) COMMA(i int) antlr.TerminalNode {
+ return s.GetToken(CypherParserCOMMA, i)
+}
+
+func (s *PatternContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *PatternContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *PatternContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterPattern(s)
+ }
+}
+
+func (s *PatternContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitPattern(s)
+ }
+}
+
+func (p *CypherParser) Pattern() (localctx IPatternContext) {
+ localctx = NewPatternContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 84, CypherParserRULE_pattern)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(658)
+ p.PatternPart()
+ }
+ p.SetState(663)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for _la == CypherParserCOMMA {
+ {
+ p.SetState(659)
+ p.Match(CypherParserCOMMA)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(660)
+ p.PatternPart()
+ }
+
+ p.SetState(665)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IExpressionContext is an interface to support dynamic dispatch.
+type IExpressionContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ AllXorExpression() []IXorExpressionContext
+ XorExpression(i int) IXorExpressionContext
+ AllOR() []antlr.TerminalNode
+ OR(i int) antlr.TerminalNode
+
+ // IsExpressionContext differentiates from other interfaces.
+ IsExpressionContext()
+}
+
+type ExpressionContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyExpressionContext() *ExpressionContext {
+ var p = new(ExpressionContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_expression
+ return p
+}
+
+func InitEmptyExpressionContext(p *ExpressionContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_expression
+}
+
+func (*ExpressionContext) IsExpressionContext() {}
+
+func NewExpressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ExpressionContext {
+ var p = new(ExpressionContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_expression
+
+ return p
+}
+
+func (s *ExpressionContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *ExpressionContext) AllXorExpression() []IXorExpressionContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IXorExpressionContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IXorExpressionContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IXorExpressionContext); ok {
+ tst[i] = t.(IXorExpressionContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *ExpressionContext) XorExpression(i int) IXorExpressionContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IXorExpressionContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IXorExpressionContext)
+}
+
+func (s *ExpressionContext) AllOR() []antlr.TerminalNode {
+ return s.GetTokens(CypherParserOR)
+}
+
+func (s *ExpressionContext) OR(i int) antlr.TerminalNode {
+ return s.GetToken(CypherParserOR, i)
+}
+
+func (s *ExpressionContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *ExpressionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *ExpressionContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterExpression(s)
+ }
+}
+
+func (s *ExpressionContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitExpression(s)
+ }
+}
+
+func (p *CypherParser) Expression() (localctx IExpressionContext) {
+ localctx = NewExpressionContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 86, CypherParserRULE_expression)
+ var _alt int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(666)
+ p.XorExpression()
+ }
+ p.SetState(671)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 85, p.GetParserRuleContext())
+ if p.HasError() {
+ goto errorExit
+ }
+ for _alt != 2 && _alt != antlr.ATNInvalidAltNumber {
+ if _alt == 1 {
+ {
+ p.SetState(667)
+ p.Match(CypherParserOR)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(668)
+ p.XorExpression()
+ }
+
+ }
+ p.SetState(673)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 85, p.GetParserRuleContext())
+ if p.HasError() {
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IXorExpressionContext is an interface to support dynamic dispatch.
+type IXorExpressionContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ AllAndExpression() []IAndExpressionContext
+ AndExpression(i int) IAndExpressionContext
+ AllXOR() []antlr.TerminalNode
+ XOR(i int) antlr.TerminalNode
+
+ // IsXorExpressionContext differentiates from other interfaces.
+ IsXorExpressionContext()
+}
+
+type XorExpressionContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyXorExpressionContext() *XorExpressionContext {
+ var p = new(XorExpressionContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_xorExpression
+ return p
+}
+
+func InitEmptyXorExpressionContext(p *XorExpressionContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_xorExpression
+}
+
+func (*XorExpressionContext) IsXorExpressionContext() {}
+
+func NewXorExpressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *XorExpressionContext {
+ var p = new(XorExpressionContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_xorExpression
+
+ return p
+}
+
+func (s *XorExpressionContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *XorExpressionContext) AllAndExpression() []IAndExpressionContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IAndExpressionContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IAndExpressionContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IAndExpressionContext); ok {
+ tst[i] = t.(IAndExpressionContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *XorExpressionContext) AndExpression(i int) IAndExpressionContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IAndExpressionContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IAndExpressionContext)
+}
+
+func (s *XorExpressionContext) AllXOR() []antlr.TerminalNode {
+ return s.GetTokens(CypherParserXOR)
+}
+
+func (s *XorExpressionContext) XOR(i int) antlr.TerminalNode {
+ return s.GetToken(CypherParserXOR, i)
+}
+
+func (s *XorExpressionContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *XorExpressionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *XorExpressionContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterXorExpression(s)
+ }
+}
+
+func (s *XorExpressionContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitXorExpression(s)
+ }
+}
+
+func (p *CypherParser) XorExpression() (localctx IXorExpressionContext) {
+ localctx = NewXorExpressionContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 88, CypherParserRULE_xorExpression)
+ var _alt int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(674)
+ p.AndExpression()
+ }
+ p.SetState(679)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 86, p.GetParserRuleContext())
+ if p.HasError() {
+ goto errorExit
+ }
+ for _alt != 2 && _alt != antlr.ATNInvalidAltNumber {
+ if _alt == 1 {
+ {
+ p.SetState(675)
+ p.Match(CypherParserXOR)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(676)
+ p.AndExpression()
+ }
+
+ }
+ p.SetState(681)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 86, p.GetParserRuleContext())
+ if p.HasError() {
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IAndExpressionContext is an interface to support dynamic dispatch.
+type IAndExpressionContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ AllNotExpression() []INotExpressionContext
+ NotExpression(i int) INotExpressionContext
+ AllAND() []antlr.TerminalNode
+ AND(i int) antlr.TerminalNode
+
+ // IsAndExpressionContext differentiates from other interfaces.
+ IsAndExpressionContext()
+}
+
+type AndExpressionContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyAndExpressionContext() *AndExpressionContext {
+ var p = new(AndExpressionContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_andExpression
+ return p
+}
+
+func InitEmptyAndExpressionContext(p *AndExpressionContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_andExpression
+}
+
+func (*AndExpressionContext) IsAndExpressionContext() {}
+
+func NewAndExpressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *AndExpressionContext {
+ var p = new(AndExpressionContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_andExpression
+
+ return p
+}
+
+func (s *AndExpressionContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *AndExpressionContext) AllNotExpression() []INotExpressionContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(INotExpressionContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]INotExpressionContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(INotExpressionContext); ok {
+ tst[i] = t.(INotExpressionContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *AndExpressionContext) NotExpression(i int) INotExpressionContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(INotExpressionContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(INotExpressionContext)
+}
+
+func (s *AndExpressionContext) AllAND() []antlr.TerminalNode {
+ return s.GetTokens(CypherParserAND)
+}
+
+func (s *AndExpressionContext) AND(i int) antlr.TerminalNode {
+ return s.GetToken(CypherParserAND, i)
+}
+
+func (s *AndExpressionContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *AndExpressionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *AndExpressionContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterAndExpression(s)
+ }
+}
+
+func (s *AndExpressionContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitAndExpression(s)
+ }
+}
+
+func (p *CypherParser) AndExpression() (localctx IAndExpressionContext) {
+ localctx = NewAndExpressionContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 90, CypherParserRULE_andExpression)
+ var _alt int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(682)
+ p.NotExpression()
+ }
+ p.SetState(687)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 87, p.GetParserRuleContext())
+ if p.HasError() {
+ goto errorExit
+ }
+ for _alt != 2 && _alt != antlr.ATNInvalidAltNumber {
+ if _alt == 1 {
+ {
+ p.SetState(683)
+ p.Match(CypherParserAND)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(684)
+ p.NotExpression()
+ }
+
+ }
+ p.SetState(689)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 87, p.GetParserRuleContext())
+ if p.HasError() {
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// INotExpressionContext is an interface to support dynamic dispatch.
+type INotExpressionContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ ComparisonExpression() IComparisonExpressionContext
+ NOT() antlr.TerminalNode
+ ExistsSubquery() IExistsSubqueryContext
+ CountSubquery() ICountSubqueryContext
+ ComparisonSigns() IComparisonSignsContext
+ Expression() IExpressionContext
+
+ // IsNotExpressionContext differentiates from other interfaces.
+ IsNotExpressionContext()
+}
+
+type NotExpressionContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyNotExpressionContext() *NotExpressionContext {
+ var p = new(NotExpressionContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_notExpression
+ return p
+}
+
+func InitEmptyNotExpressionContext(p *NotExpressionContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_notExpression
+}
+
+func (*NotExpressionContext) IsNotExpressionContext() {}
+
+func NewNotExpressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *NotExpressionContext {
+ var p = new(NotExpressionContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_notExpression
+
+ return p
+}
+
+func (s *NotExpressionContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *NotExpressionContext) ComparisonExpression() IComparisonExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IComparisonExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IComparisonExpressionContext)
+}
+
+func (s *NotExpressionContext) NOT() antlr.TerminalNode {
+ return s.GetToken(CypherParserNOT, 0)
+}
+
+func (s *NotExpressionContext) ExistsSubquery() IExistsSubqueryContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IExistsSubqueryContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IExistsSubqueryContext)
+}
+
+func (s *NotExpressionContext) CountSubquery() ICountSubqueryContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ICountSubqueryContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ICountSubqueryContext)
+}
+
+func (s *NotExpressionContext) ComparisonSigns() IComparisonSignsContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IComparisonSignsContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IComparisonSignsContext)
+}
+
+func (s *NotExpressionContext) Expression() IExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IExpressionContext)
+}
+
+func (s *NotExpressionContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *NotExpressionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *NotExpressionContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterNotExpression(s)
+ }
+}
+
+func (s *NotExpressionContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitNotExpression(s)
+ }
+}
+
+func (p *CypherParser) NotExpression() (localctx INotExpressionContext) {
+ localctx = NewNotExpressionContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 92, CypherParserRULE_notExpression)
+ var _la int
+
+ p.SetState(702)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 90, p.GetParserRuleContext()) {
+ case 1:
+ p.EnterOuterAlt(localctx, 1)
+ p.SetState(691)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserNOT {
+ {
+ p.SetState(690)
+ p.Match(CypherParserNOT)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ }
+ {
+ p.SetState(693)
+ p.ComparisonExpression()
+ }
+
+ case 2:
+ p.EnterOuterAlt(localctx, 2)
+ p.SetState(695)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserNOT {
+ {
+ p.SetState(694)
+ p.Match(CypherParserNOT)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ }
+ {
+ p.SetState(697)
+ p.ExistsSubquery()
+ }
+
+ case 3:
+ p.EnterOuterAlt(localctx, 3)
+ {
+ p.SetState(698)
+ p.CountSubquery()
+ }
+ {
+ p.SetState(699)
+ p.ComparisonSigns()
+ }
+ {
+ p.SetState(700)
+ p.Expression()
+ }
+
+ case antlr.ATNInvalidAltNumber:
+ goto errorExit
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IComparisonExpressionContext is an interface to support dynamic dispatch.
+type IComparisonExpressionContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ AllAddSubExpression() []IAddSubExpressionContext
+ AddSubExpression(i int) IAddSubExpressionContext
+ AllComparisonSigns() []IComparisonSignsContext
+ ComparisonSigns(i int) IComparisonSignsContext
+
+ // IsComparisonExpressionContext differentiates from other interfaces.
+ IsComparisonExpressionContext()
+}
+
+type ComparisonExpressionContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyComparisonExpressionContext() *ComparisonExpressionContext {
+ var p = new(ComparisonExpressionContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_comparisonExpression
+ return p
+}
+
+func InitEmptyComparisonExpressionContext(p *ComparisonExpressionContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_comparisonExpression
+}
+
+func (*ComparisonExpressionContext) IsComparisonExpressionContext() {}
+
+func NewComparisonExpressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ComparisonExpressionContext {
+ var p = new(ComparisonExpressionContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_comparisonExpression
+
+ return p
+}
+
+func (s *ComparisonExpressionContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *ComparisonExpressionContext) AllAddSubExpression() []IAddSubExpressionContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IAddSubExpressionContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IAddSubExpressionContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IAddSubExpressionContext); ok {
+ tst[i] = t.(IAddSubExpressionContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *ComparisonExpressionContext) AddSubExpression(i int) IAddSubExpressionContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IAddSubExpressionContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IAddSubExpressionContext)
+}
+
+func (s *ComparisonExpressionContext) AllComparisonSigns() []IComparisonSignsContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IComparisonSignsContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IComparisonSignsContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IComparisonSignsContext); ok {
+ tst[i] = t.(IComparisonSignsContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *ComparisonExpressionContext) ComparisonSigns(i int) IComparisonSignsContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IComparisonSignsContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IComparisonSignsContext)
+}
+
+func (s *ComparisonExpressionContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *ComparisonExpressionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *ComparisonExpressionContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterComparisonExpression(s)
+ }
+}
+
+func (s *ComparisonExpressionContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitComparisonExpression(s)
+ }
+}
+
+func (p *CypherParser) ComparisonExpression() (localctx IComparisonExpressionContext) {
+ localctx = NewComparisonExpressionContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 94, CypherParserRULE_comparisonExpression)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(704)
+ p.AddSubExpression()
+ }
+ p.SetState(710)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for (int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&506) != 0 {
+ {
+ p.SetState(705)
+ p.ComparisonSigns()
+ }
+ {
+ p.SetState(706)
+ p.AddSubExpression()
+ }
+
+ p.SetState(712)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IComparisonSignsContext is an interface to support dynamic dispatch.
+type IComparisonSignsContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ ASSIGN() antlr.TerminalNode
+ LE() antlr.TerminalNode
+ GE() antlr.TerminalNode
+ GT() antlr.TerminalNode
+ LT() antlr.TerminalNode
+ NOT_EQUAL() antlr.TerminalNode
+ REGEX_MATCH() antlr.TerminalNode
+
+ // IsComparisonSignsContext differentiates from other interfaces.
+ IsComparisonSignsContext()
+}
+
+type ComparisonSignsContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyComparisonSignsContext() *ComparisonSignsContext {
+ var p = new(ComparisonSignsContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_comparisonSigns
+ return p
+}
+
+func InitEmptyComparisonSignsContext(p *ComparisonSignsContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_comparisonSigns
+}
+
+func (*ComparisonSignsContext) IsComparisonSignsContext() {}
+
+func NewComparisonSignsContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ComparisonSignsContext {
+ var p = new(ComparisonSignsContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_comparisonSigns
+
+ return p
+}
+
+func (s *ComparisonSignsContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *ComparisonSignsContext) ASSIGN() antlr.TerminalNode {
+ return s.GetToken(CypherParserASSIGN, 0)
+}
+
+func (s *ComparisonSignsContext) LE() antlr.TerminalNode {
+ return s.GetToken(CypherParserLE, 0)
+}
+
+func (s *ComparisonSignsContext) GE() antlr.TerminalNode {
+ return s.GetToken(CypherParserGE, 0)
+}
+
+func (s *ComparisonSignsContext) GT() antlr.TerminalNode {
+ return s.GetToken(CypherParserGT, 0)
+}
+
+func (s *ComparisonSignsContext) LT() antlr.TerminalNode {
+ return s.GetToken(CypherParserLT, 0)
+}
+
+func (s *ComparisonSignsContext) NOT_EQUAL() antlr.TerminalNode {
+ return s.GetToken(CypherParserNOT_EQUAL, 0)
+}
+
+func (s *ComparisonSignsContext) REGEX_MATCH() antlr.TerminalNode {
+ return s.GetToken(CypherParserREGEX_MATCH, 0)
+}
+
+func (s *ComparisonSignsContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *ComparisonSignsContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *ComparisonSignsContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterComparisonSigns(s)
+ }
+}
+
+func (s *ComparisonSignsContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitComparisonSigns(s)
+ }
+}
+
+func (p *CypherParser) ComparisonSigns() (localctx IComparisonSignsContext) {
+ localctx = NewComparisonSignsContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 96, CypherParserRULE_comparisonSigns)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(713)
+ _la = p.GetTokenStream().LA(1)
+
+ if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&506) != 0) {
+ p.GetErrorHandler().RecoverInline(p)
+ } else {
+ p.GetErrorHandler().ReportMatch(p)
+ p.Consume()
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IAddSubExpressionContext is an interface to support dynamic dispatch.
+type IAddSubExpressionContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ AllMultDivExpression() []IMultDivExpressionContext
+ MultDivExpression(i int) IMultDivExpressionContext
+ AllPLUS() []antlr.TerminalNode
+ PLUS(i int) antlr.TerminalNode
+ AllSUB() []antlr.TerminalNode
+ SUB(i int) antlr.TerminalNode
+
+ // IsAddSubExpressionContext differentiates from other interfaces.
+ IsAddSubExpressionContext()
+}
+
+type AddSubExpressionContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyAddSubExpressionContext() *AddSubExpressionContext {
+ var p = new(AddSubExpressionContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_addSubExpression
+ return p
+}
+
+func InitEmptyAddSubExpressionContext(p *AddSubExpressionContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_addSubExpression
+}
+
+func (*AddSubExpressionContext) IsAddSubExpressionContext() {}
+
+func NewAddSubExpressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *AddSubExpressionContext {
+ var p = new(AddSubExpressionContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_addSubExpression
+
+ return p
+}
+
+func (s *AddSubExpressionContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *AddSubExpressionContext) AllMultDivExpression() []IMultDivExpressionContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IMultDivExpressionContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IMultDivExpressionContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IMultDivExpressionContext); ok {
+ tst[i] = t.(IMultDivExpressionContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *AddSubExpressionContext) MultDivExpression(i int) IMultDivExpressionContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IMultDivExpressionContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IMultDivExpressionContext)
+}
+
+func (s *AddSubExpressionContext) AllPLUS() []antlr.TerminalNode {
+ return s.GetTokens(CypherParserPLUS)
+}
+
+func (s *AddSubExpressionContext) PLUS(i int) antlr.TerminalNode {
+ return s.GetToken(CypherParserPLUS, i)
+}
+
+func (s *AddSubExpressionContext) AllSUB() []antlr.TerminalNode {
+ return s.GetTokens(CypherParserSUB)
+}
+
+func (s *AddSubExpressionContext) SUB(i int) antlr.TerminalNode {
+ return s.GetToken(CypherParserSUB, i)
+}
+
+func (s *AddSubExpressionContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *AddSubExpressionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *AddSubExpressionContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterAddSubExpression(s)
+ }
+}
+
+func (s *AddSubExpressionContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitAddSubExpression(s)
+ }
+}
+
+func (p *CypherParser) AddSubExpression() (localctx IAddSubExpressionContext) {
+ localctx = NewAddSubExpressionContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 98, CypherParserRULE_addSubExpression)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(715)
+ p.MultDivExpression()
+ }
+ p.SetState(720)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for _la == CypherParserSUB || _la == CypherParserPLUS {
+ {
+ p.SetState(716)
+ _la = p.GetTokenStream().LA(1)
+
+ if !(_la == CypherParserSUB || _la == CypherParserPLUS) {
+ p.GetErrorHandler().RecoverInline(p)
+ } else {
+ p.GetErrorHandler().ReportMatch(p)
+ p.Consume()
+ }
+ }
+ {
+ p.SetState(717)
+ p.MultDivExpression()
+ }
+
+ p.SetState(722)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IMultDivExpressionContext is an interface to support dynamic dispatch.
+type IMultDivExpressionContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ AllPowerExpression() []IPowerExpressionContext
+ PowerExpression(i int) IPowerExpressionContext
+ AllMULT() []antlr.TerminalNode
+ MULT(i int) antlr.TerminalNode
+ AllDIV() []antlr.TerminalNode
+ DIV(i int) antlr.TerminalNode
+ AllMOD() []antlr.TerminalNode
+ MOD(i int) antlr.TerminalNode
+
+ // IsMultDivExpressionContext differentiates from other interfaces.
+ IsMultDivExpressionContext()
+}
+
+type MultDivExpressionContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyMultDivExpressionContext() *MultDivExpressionContext {
+ var p = new(MultDivExpressionContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_multDivExpression
+ return p
+}
+
+func InitEmptyMultDivExpressionContext(p *MultDivExpressionContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_multDivExpression
+}
+
+func (*MultDivExpressionContext) IsMultDivExpressionContext() {}
+
+func NewMultDivExpressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *MultDivExpressionContext {
+ var p = new(MultDivExpressionContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_multDivExpression
+
+ return p
+}
+
+func (s *MultDivExpressionContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *MultDivExpressionContext) AllPowerExpression() []IPowerExpressionContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IPowerExpressionContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IPowerExpressionContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IPowerExpressionContext); ok {
+ tst[i] = t.(IPowerExpressionContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *MultDivExpressionContext) PowerExpression(i int) IPowerExpressionContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IPowerExpressionContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IPowerExpressionContext)
+}
+
+func (s *MultDivExpressionContext) AllMULT() []antlr.TerminalNode {
+ return s.GetTokens(CypherParserMULT)
+}
+
+func (s *MultDivExpressionContext) MULT(i int) antlr.TerminalNode {
+ return s.GetToken(CypherParserMULT, i)
+}
+
+func (s *MultDivExpressionContext) AllDIV() []antlr.TerminalNode {
+ return s.GetTokens(CypherParserDIV)
+}
+
+func (s *MultDivExpressionContext) DIV(i int) antlr.TerminalNode {
+ return s.GetToken(CypherParserDIV, i)
+}
+
+func (s *MultDivExpressionContext) AllMOD() []antlr.TerminalNode {
+ return s.GetTokens(CypherParserMOD)
+}
+
+func (s *MultDivExpressionContext) MOD(i int) antlr.TerminalNode {
+ return s.GetToken(CypherParserMOD, i)
+}
+
+func (s *MultDivExpressionContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *MultDivExpressionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *MultDivExpressionContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterMultDivExpression(s)
+ }
+}
+
+func (s *MultDivExpressionContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitMultDivExpression(s)
+ }
+}
+
+func (p *CypherParser) MultDivExpression() (localctx IMultDivExpressionContext) {
+ localctx = NewMultDivExpressionContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 100, CypherParserRULE_multDivExpression)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(723)
+ p.PowerExpression()
+ }
+ p.SetState(728)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for (int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&23068672) != 0 {
+ {
+ p.SetState(724)
+ _la = p.GetTokenStream().LA(1)
+
+ if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&23068672) != 0) {
+ p.GetErrorHandler().RecoverInline(p)
+ } else {
+ p.GetErrorHandler().ReportMatch(p)
+ p.Consume()
+ }
+ }
+ {
+ p.SetState(725)
+ p.PowerExpression()
+ }
+
+ p.SetState(730)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IPowerExpressionContext is an interface to support dynamic dispatch.
+type IPowerExpressionContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ AllUnaryAddSubExpression() []IUnaryAddSubExpressionContext
+ UnaryAddSubExpression(i int) IUnaryAddSubExpressionContext
+ AllCARET() []antlr.TerminalNode
+ CARET(i int) antlr.TerminalNode
+
+ // IsPowerExpressionContext differentiates from other interfaces.
+ IsPowerExpressionContext()
+}
+
+type PowerExpressionContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyPowerExpressionContext() *PowerExpressionContext {
+ var p = new(PowerExpressionContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_powerExpression
+ return p
+}
+
+func InitEmptyPowerExpressionContext(p *PowerExpressionContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_powerExpression
+}
+
+func (*PowerExpressionContext) IsPowerExpressionContext() {}
+
+func NewPowerExpressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *PowerExpressionContext {
+ var p = new(PowerExpressionContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_powerExpression
+
+ return p
+}
+
+func (s *PowerExpressionContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *PowerExpressionContext) AllUnaryAddSubExpression() []IUnaryAddSubExpressionContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IUnaryAddSubExpressionContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IUnaryAddSubExpressionContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IUnaryAddSubExpressionContext); ok {
+ tst[i] = t.(IUnaryAddSubExpressionContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *PowerExpressionContext) UnaryAddSubExpression(i int) IUnaryAddSubExpressionContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IUnaryAddSubExpressionContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IUnaryAddSubExpressionContext)
+}
+
+func (s *PowerExpressionContext) AllCARET() []antlr.TerminalNode {
+ return s.GetTokens(CypherParserCARET)
+}
+
+func (s *PowerExpressionContext) CARET(i int) antlr.TerminalNode {
+ return s.GetToken(CypherParserCARET, i)
+}
+
+func (s *PowerExpressionContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *PowerExpressionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *PowerExpressionContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterPowerExpression(s)
+ }
+}
+
+func (s *PowerExpressionContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitPowerExpression(s)
+ }
+}
+
+func (p *CypherParser) PowerExpression() (localctx IPowerExpressionContext) {
+ localctx = NewPowerExpressionContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 102, CypherParserRULE_powerExpression)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(731)
+ p.UnaryAddSubExpression()
+ }
+ p.SetState(736)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for _la == CypherParserCARET {
+ {
+ p.SetState(732)
+ p.Match(CypherParserCARET)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(733)
+ p.UnaryAddSubExpression()
+ }
+
+ p.SetState(738)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IUnaryAddSubExpressionContext is an interface to support dynamic dispatch.
+type IUnaryAddSubExpressionContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ AtomicExpression() IAtomicExpressionContext
+ PLUS() antlr.TerminalNode
+ SUB() antlr.TerminalNode
+
+ // IsUnaryAddSubExpressionContext differentiates from other interfaces.
+ IsUnaryAddSubExpressionContext()
+}
+
+type UnaryAddSubExpressionContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyUnaryAddSubExpressionContext() *UnaryAddSubExpressionContext {
+ var p = new(UnaryAddSubExpressionContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_unaryAddSubExpression
+ return p
+}
+
+func InitEmptyUnaryAddSubExpressionContext(p *UnaryAddSubExpressionContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_unaryAddSubExpression
+}
+
+func (*UnaryAddSubExpressionContext) IsUnaryAddSubExpressionContext() {}
+
+func NewUnaryAddSubExpressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *UnaryAddSubExpressionContext {
+ var p = new(UnaryAddSubExpressionContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_unaryAddSubExpression
+
+ return p
+}
+
+func (s *UnaryAddSubExpressionContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *UnaryAddSubExpressionContext) AtomicExpression() IAtomicExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IAtomicExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IAtomicExpressionContext)
+}
+
+func (s *UnaryAddSubExpressionContext) PLUS() antlr.TerminalNode {
+ return s.GetToken(CypherParserPLUS, 0)
+}
+
+func (s *UnaryAddSubExpressionContext) SUB() antlr.TerminalNode {
+ return s.GetToken(CypherParserSUB, 0)
+}
+
+func (s *UnaryAddSubExpressionContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *UnaryAddSubExpressionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *UnaryAddSubExpressionContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterUnaryAddSubExpression(s)
+ }
+}
+
+func (s *UnaryAddSubExpressionContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitUnaryAddSubExpression(s)
+ }
+}
+
+func (p *CypherParser) UnaryAddSubExpression() (localctx IUnaryAddSubExpressionContext) {
+ localctx = NewUnaryAddSubExpressionContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 104, CypherParserRULE_unaryAddSubExpression)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ p.SetState(740)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserSUB || _la == CypherParserPLUS {
+ {
+ p.SetState(739)
+ _la = p.GetTokenStream().LA(1)
+
+ if !(_la == CypherParserSUB || _la == CypherParserPLUS) {
+ p.GetErrorHandler().RecoverInline(p)
+ } else {
+ p.GetErrorHandler().ReportMatch(p)
+ p.Consume()
+ }
+ }
+
+ }
+ {
+ p.SetState(742)
+ p.AtomicExpression()
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IAtomicExpressionContext is an interface to support dynamic dispatch.
+type IAtomicExpressionContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ PropertyOrLabelExpression() IPropertyOrLabelExpressionContext
+ AllStringExpression() []IStringExpressionContext
+ StringExpression(i int) IStringExpressionContext
+ AllListExpression() []IListExpressionContext
+ ListExpression(i int) IListExpressionContext
+ AllNullExpression() []INullExpressionContext
+ NullExpression(i int) INullExpressionContext
+
+ // IsAtomicExpressionContext differentiates from other interfaces.
+ IsAtomicExpressionContext()
+}
+
+type AtomicExpressionContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyAtomicExpressionContext() *AtomicExpressionContext {
+ var p = new(AtomicExpressionContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_atomicExpression
+ return p
+}
+
+func InitEmptyAtomicExpressionContext(p *AtomicExpressionContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_atomicExpression
+}
+
+func (*AtomicExpressionContext) IsAtomicExpressionContext() {}
+
+func NewAtomicExpressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *AtomicExpressionContext {
+ var p = new(AtomicExpressionContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_atomicExpression
+
+ return p
+}
+
+func (s *AtomicExpressionContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *AtomicExpressionContext) PropertyOrLabelExpression() IPropertyOrLabelExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IPropertyOrLabelExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IPropertyOrLabelExpressionContext)
+}
+
+func (s *AtomicExpressionContext) AllStringExpression() []IStringExpressionContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IStringExpressionContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IStringExpressionContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IStringExpressionContext); ok {
+ tst[i] = t.(IStringExpressionContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *AtomicExpressionContext) StringExpression(i int) IStringExpressionContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IStringExpressionContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IStringExpressionContext)
+}
+
+func (s *AtomicExpressionContext) AllListExpression() []IListExpressionContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IListExpressionContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IListExpressionContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IListExpressionContext); ok {
+ tst[i] = t.(IListExpressionContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *AtomicExpressionContext) ListExpression(i int) IListExpressionContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IListExpressionContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IListExpressionContext)
+}
+
+func (s *AtomicExpressionContext) AllNullExpression() []INullExpressionContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(INullExpressionContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]INullExpressionContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(INullExpressionContext); ok {
+ tst[i] = t.(INullExpressionContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *AtomicExpressionContext) NullExpression(i int) INullExpressionContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(INullExpressionContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(INullExpressionContext)
+}
+
+func (s *AtomicExpressionContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *AtomicExpressionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *AtomicExpressionContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterAtomicExpression(s)
+ }
+}
+
+func (s *AtomicExpressionContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitAtomicExpression(s)
+ }
+}
+
+func (p *CypherParser) AtomicExpression() (localctx IAtomicExpressionContext) {
+ localctx = NewAtomicExpressionContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 106, CypherParserRULE_atomicExpression)
+ var _alt int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(744)
+ p.PropertyOrLabelExpression()
+ }
+ p.SetState(750)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 97, p.GetParserRuleContext())
+ if p.HasError() {
+ goto errorExit
+ }
+ for _alt != 2 && _alt != antlr.ATNInvalidAltNumber {
+ if _alt == 1 {
+ p.SetState(748)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetTokenStream().LA(1) {
+ case CypherParserCONTAINS, CypherParserENDS, CypherParserSTARTS:
+ {
+ p.SetState(745)
+ p.StringExpression()
+ }
+
+ case CypherParserLBRACK, CypherParserIN:
+ {
+ p.SetState(746)
+ p.ListExpression()
+ }
+
+ case CypherParserIS:
+ {
+ p.SetState(747)
+ p.NullExpression()
+ }
+
+ default:
+ p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil))
+ goto errorExit
+ }
+
+ }
+ p.SetState(752)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 97, p.GetParserRuleContext())
+ if p.HasError() {
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IListExpressionContext is an interface to support dynamic dispatch.
+type IListExpressionContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ IN() antlr.TerminalNode
+ PropertyOrLabelExpression() IPropertyOrLabelExpressionContext
+ LBRACK() antlr.TerminalNode
+ RBRACK() antlr.TerminalNode
+ RANGE() antlr.TerminalNode
+ AllExpression() []IExpressionContext
+ Expression(i int) IExpressionContext
+
+ // IsListExpressionContext differentiates from other interfaces.
+ IsListExpressionContext()
+}
+
+type ListExpressionContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyListExpressionContext() *ListExpressionContext {
+ var p = new(ListExpressionContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_listExpression
+ return p
+}
+
+func InitEmptyListExpressionContext(p *ListExpressionContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_listExpression
+}
+
+func (*ListExpressionContext) IsListExpressionContext() {}
+
+func NewListExpressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ListExpressionContext {
+ var p = new(ListExpressionContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_listExpression
+
+ return p
+}
+
+func (s *ListExpressionContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *ListExpressionContext) IN() antlr.TerminalNode {
+ return s.GetToken(CypherParserIN, 0)
+}
+
+func (s *ListExpressionContext) PropertyOrLabelExpression() IPropertyOrLabelExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IPropertyOrLabelExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IPropertyOrLabelExpressionContext)
+}
+
+func (s *ListExpressionContext) LBRACK() antlr.TerminalNode {
+ return s.GetToken(CypherParserLBRACK, 0)
+}
+
+func (s *ListExpressionContext) RBRACK() antlr.TerminalNode {
+ return s.GetToken(CypherParserRBRACK, 0)
+}
+
+func (s *ListExpressionContext) RANGE() antlr.TerminalNode {
+ return s.GetToken(CypherParserRANGE, 0)
+}
+
+func (s *ListExpressionContext) AllExpression() []IExpressionContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IExpressionContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IExpressionContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IExpressionContext); ok {
+ tst[i] = t.(IExpressionContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *ListExpressionContext) Expression(i int) IExpressionContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IExpressionContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IExpressionContext)
+}
+
+func (s *ListExpressionContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *ListExpressionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *ListExpressionContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterListExpression(s)
+ }
+}
+
+func (s *ListExpressionContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitListExpression(s)
+ }
+}
+
+func (p *CypherParser) ListExpression() (localctx IListExpressionContext) {
+ localctx = NewListExpressionContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 108, CypherParserRULE_listExpression)
+ var _la int
+
+ p.SetState(767)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetTokenStream().LA(1) {
+ case CypherParserIN:
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(753)
+ p.Match(CypherParserIN)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(754)
+ p.PropertyOrLabelExpression()
+ }
+
+ case CypherParserLBRACK:
+ p.EnterOuterAlt(localctx, 2)
+ {
+ p.SetState(755)
+ p.Match(CypherParserLBRACK)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(764)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 100, p.GetParserRuleContext()) {
+ case 1:
+ p.SetState(757)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if ((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&1470645178784718848) != 0) || ((int64((_la-73)) & ^0x3f) == 0 && ((int64(1)<<(_la-73))&2251795417136369) != 0) {
+ {
+ p.SetState(756)
+ p.Expression()
+ }
+
+ }
+ {
+ p.SetState(759)
+ p.Match(CypherParserRANGE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(761)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if ((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&1470645178784718848) != 0) || ((int64((_la-73)) & ^0x3f) == 0 && ((int64(1)<<(_la-73))&2251795417136369) != 0) {
+ {
+ p.SetState(760)
+ p.Expression()
+ }
+
+ }
+
+ case 2:
+ {
+ p.SetState(763)
+ p.Expression()
+ }
+
+ case antlr.ATNInvalidAltNumber:
+ goto errorExit
+ }
+ {
+ p.SetState(766)
+ p.Match(CypherParserRBRACK)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ default:
+ p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil))
+ goto errorExit
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IStringExpressionContext is an interface to support dynamic dispatch.
+type IStringExpressionContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ StringExpPrefix() IStringExpPrefixContext
+ PropertyOrLabelExpression() IPropertyOrLabelExpressionContext
+
+ // IsStringExpressionContext differentiates from other interfaces.
+ IsStringExpressionContext()
+}
+
+type StringExpressionContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyStringExpressionContext() *StringExpressionContext {
+ var p = new(StringExpressionContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_stringExpression
+ return p
+}
+
+func InitEmptyStringExpressionContext(p *StringExpressionContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_stringExpression
+}
+
+func (*StringExpressionContext) IsStringExpressionContext() {}
+
+func NewStringExpressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *StringExpressionContext {
+ var p = new(StringExpressionContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_stringExpression
+
+ return p
+}
+
+func (s *StringExpressionContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *StringExpressionContext) StringExpPrefix() IStringExpPrefixContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IStringExpPrefixContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IStringExpPrefixContext)
+}
+
+func (s *StringExpressionContext) PropertyOrLabelExpression() IPropertyOrLabelExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IPropertyOrLabelExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IPropertyOrLabelExpressionContext)
+}
+
+func (s *StringExpressionContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *StringExpressionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *StringExpressionContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterStringExpression(s)
+ }
+}
+
+func (s *StringExpressionContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitStringExpression(s)
+ }
+}
+
+func (p *CypherParser) StringExpression() (localctx IStringExpressionContext) {
+ localctx = NewStringExpressionContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 110, CypherParserRULE_stringExpression)
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(769)
+ p.StringExpPrefix()
+ }
+ {
+ p.SetState(770)
+ p.PropertyOrLabelExpression()
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IStringExpPrefixContext is an interface to support dynamic dispatch.
+type IStringExpPrefixContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ STARTS() antlr.TerminalNode
+ WITH() antlr.TerminalNode
+ ENDS() antlr.TerminalNode
+ CONTAINS() antlr.TerminalNode
+
+ // IsStringExpPrefixContext differentiates from other interfaces.
+ IsStringExpPrefixContext()
+}
+
+type StringExpPrefixContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyStringExpPrefixContext() *StringExpPrefixContext {
+ var p = new(StringExpPrefixContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_stringExpPrefix
+ return p
+}
+
+func InitEmptyStringExpPrefixContext(p *StringExpPrefixContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_stringExpPrefix
+}
+
+func (*StringExpPrefixContext) IsStringExpPrefixContext() {}
+
+func NewStringExpPrefixContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *StringExpPrefixContext {
+ var p = new(StringExpPrefixContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_stringExpPrefix
+
+ return p
+}
+
+func (s *StringExpPrefixContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *StringExpPrefixContext) STARTS() antlr.TerminalNode {
+ return s.GetToken(CypherParserSTARTS, 0)
+}
+
+func (s *StringExpPrefixContext) WITH() antlr.TerminalNode {
+ return s.GetToken(CypherParserWITH, 0)
+}
+
+func (s *StringExpPrefixContext) ENDS() antlr.TerminalNode {
+ return s.GetToken(CypherParserENDS, 0)
+}
+
+func (s *StringExpPrefixContext) CONTAINS() antlr.TerminalNode {
+ return s.GetToken(CypherParserCONTAINS, 0)
+}
+
+func (s *StringExpPrefixContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *StringExpPrefixContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *StringExpPrefixContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterStringExpPrefix(s)
+ }
+}
+
+func (s *StringExpPrefixContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitStringExpPrefix(s)
+ }
+}
+
+func (p *CypherParser) StringExpPrefix() (localctx IStringExpPrefixContext) {
+ localctx = NewStringExpPrefixContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 112, CypherParserRULE_stringExpPrefix)
+ p.SetState(777)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetTokenStream().LA(1) {
+ case CypherParserSTARTS:
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(772)
+ p.Match(CypherParserSTARTS)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(773)
+ p.Match(CypherParserWITH)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ case CypherParserENDS:
+ p.EnterOuterAlt(localctx, 2)
+ {
+ p.SetState(774)
+ p.Match(CypherParserENDS)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(775)
+ p.Match(CypherParserWITH)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ case CypherParserCONTAINS:
+ p.EnterOuterAlt(localctx, 3)
+ {
+ p.SetState(776)
+ p.Match(CypherParserCONTAINS)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ default:
+ p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil))
+ goto errorExit
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// INullExpressionContext is an interface to support dynamic dispatch.
+type INullExpressionContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ IS() antlr.TerminalNode
+ NULL_W() antlr.TerminalNode
+ NOT() antlr.TerminalNode
+
+ // IsNullExpressionContext differentiates from other interfaces.
+ IsNullExpressionContext()
+}
+
+type NullExpressionContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyNullExpressionContext() *NullExpressionContext {
+ var p = new(NullExpressionContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_nullExpression
+ return p
+}
+
+func InitEmptyNullExpressionContext(p *NullExpressionContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_nullExpression
+}
+
+func (*NullExpressionContext) IsNullExpressionContext() {}
+
+func NewNullExpressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *NullExpressionContext {
+ var p = new(NullExpressionContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_nullExpression
+
+ return p
+}
+
+func (s *NullExpressionContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *NullExpressionContext) IS() antlr.TerminalNode {
+ return s.GetToken(CypherParserIS, 0)
+}
+
+func (s *NullExpressionContext) NULL_W() antlr.TerminalNode {
+ return s.GetToken(CypherParserNULL_W, 0)
+}
+
+func (s *NullExpressionContext) NOT() antlr.TerminalNode {
+ return s.GetToken(CypherParserNOT, 0)
+}
+
+func (s *NullExpressionContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *NullExpressionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *NullExpressionContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterNullExpression(s)
+ }
+}
+
+func (s *NullExpressionContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitNullExpression(s)
+ }
+}
+
+func (p *CypherParser) NullExpression() (localctx INullExpressionContext) {
+ localctx = NewNullExpressionContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 114, CypherParserRULE_nullExpression)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(779)
+ p.Match(CypherParserIS)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(781)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserNOT {
+ {
+ p.SetState(780)
+ p.Match(CypherParserNOT)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ }
+ {
+ p.SetState(783)
+ p.Match(CypherParserNULL_W)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IPropertyOrLabelExpressionContext is an interface to support dynamic dispatch.
+type IPropertyOrLabelExpressionContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ PropertyExpression() IPropertyExpressionContext
+ NodeLabels() INodeLabelsContext
+
+ // IsPropertyOrLabelExpressionContext differentiates from other interfaces.
+ IsPropertyOrLabelExpressionContext()
+}
+
+type PropertyOrLabelExpressionContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyPropertyOrLabelExpressionContext() *PropertyOrLabelExpressionContext {
+ var p = new(PropertyOrLabelExpressionContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_propertyOrLabelExpression
+ return p
+}
+
+func InitEmptyPropertyOrLabelExpressionContext(p *PropertyOrLabelExpressionContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_propertyOrLabelExpression
+}
+
+func (*PropertyOrLabelExpressionContext) IsPropertyOrLabelExpressionContext() {}
+
+func NewPropertyOrLabelExpressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *PropertyOrLabelExpressionContext {
+ var p = new(PropertyOrLabelExpressionContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_propertyOrLabelExpression
+
+ return p
+}
+
+func (s *PropertyOrLabelExpressionContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *PropertyOrLabelExpressionContext) PropertyExpression() IPropertyExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IPropertyExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IPropertyExpressionContext)
+}
+
+func (s *PropertyOrLabelExpressionContext) NodeLabels() INodeLabelsContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(INodeLabelsContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(INodeLabelsContext)
+}
+
+func (s *PropertyOrLabelExpressionContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *PropertyOrLabelExpressionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *PropertyOrLabelExpressionContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterPropertyOrLabelExpression(s)
+ }
+}
+
+func (s *PropertyOrLabelExpressionContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitPropertyOrLabelExpression(s)
+ }
+}
+
+func (p *CypherParser) PropertyOrLabelExpression() (localctx IPropertyOrLabelExpressionContext) {
+ localctx = NewPropertyOrLabelExpressionContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 116, CypherParserRULE_propertyOrLabelExpression)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(785)
+ p.PropertyExpression()
+ }
+ p.SetState(787)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserCOLON {
+ {
+ p.SetState(786)
+ p.NodeLabels()
+ }
+
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IPropertyExpressionContext is an interface to support dynamic dispatch.
+type IPropertyExpressionContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ Atom() IAtomContext
+ AllDOT() []antlr.TerminalNode
+ DOT(i int) antlr.TerminalNode
+ AllName() []INameContext
+ Name(i int) INameContext
+
+ // IsPropertyExpressionContext differentiates from other interfaces.
+ IsPropertyExpressionContext()
+}
+
+type PropertyExpressionContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyPropertyExpressionContext() *PropertyExpressionContext {
+ var p = new(PropertyExpressionContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_propertyExpression
+ return p
+}
+
+func InitEmptyPropertyExpressionContext(p *PropertyExpressionContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_propertyExpression
+}
+
+func (*PropertyExpressionContext) IsPropertyExpressionContext() {}
+
+func NewPropertyExpressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *PropertyExpressionContext {
+ var p = new(PropertyExpressionContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_propertyExpression
+
+ return p
+}
+
+func (s *PropertyExpressionContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *PropertyExpressionContext) Atom() IAtomContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IAtomContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IAtomContext)
+}
+
+func (s *PropertyExpressionContext) AllDOT() []antlr.TerminalNode {
+ return s.GetTokens(CypherParserDOT)
+}
+
+func (s *PropertyExpressionContext) DOT(i int) antlr.TerminalNode {
+ return s.GetToken(CypherParserDOT, i)
+}
+
+func (s *PropertyExpressionContext) AllName() []INameContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(INameContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]INameContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(INameContext); ok {
+ tst[i] = t.(INameContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *PropertyExpressionContext) Name(i int) INameContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(INameContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(INameContext)
+}
+
+func (s *PropertyExpressionContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *PropertyExpressionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *PropertyExpressionContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterPropertyExpression(s)
+ }
+}
+
+func (s *PropertyExpressionContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitPropertyExpression(s)
+ }
+}
+
+func (p *CypherParser) PropertyExpression() (localctx IPropertyExpressionContext) {
+ localctx = NewPropertyExpressionContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 118, CypherParserRULE_propertyExpression)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(789)
+ p.Atom()
+ }
+ p.SetState(794)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for _la == CypherParserDOT {
+ {
+ p.SetState(790)
+ p.Match(CypherParserDOT)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(791)
+ p.Name()
+ }
+
+ p.SetState(796)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IPatternPartContext is an interface to support dynamic dispatch.
+type IPatternPartContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ PatternElem() IPatternElemContext
+ Symbol() ISymbolContext
+ ASSIGN() antlr.TerminalNode
+ PathFunction() IPathFunctionContext
+
+ // IsPatternPartContext differentiates from other interfaces.
+ IsPatternPartContext()
+}
+
+type PatternPartContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyPatternPartContext() *PatternPartContext {
+ var p = new(PatternPartContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_patternPart
+ return p
+}
+
+func InitEmptyPatternPartContext(p *PatternPartContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_patternPart
+}
+
+func (*PatternPartContext) IsPatternPartContext() {}
+
+func NewPatternPartContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *PatternPartContext {
+ var p = new(PatternPartContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_patternPart
+
+ return p
+}
+
+func (s *PatternPartContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *PatternPartContext) PatternElem() IPatternElemContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IPatternElemContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IPatternElemContext)
+}
+
+func (s *PatternPartContext) Symbol() ISymbolContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ISymbolContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ISymbolContext)
+}
+
+func (s *PatternPartContext) ASSIGN() antlr.TerminalNode {
+ return s.GetToken(CypherParserASSIGN, 0)
+}
+
+func (s *PatternPartContext) PathFunction() IPathFunctionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IPathFunctionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IPathFunctionContext)
+}
+
+func (s *PatternPartContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *PatternPartContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *PatternPartContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterPatternPart(s)
+ }
+}
+
+func (s *PatternPartContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitPatternPart(s)
+ }
+}
+
+func (p *CypherParser) PatternPart() (localctx IPatternPartContext) {
+ localctx = NewPatternPartContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 120, CypherParserRULE_patternPart)
+ var _la int
+
+ p.SetState(809)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 108, p.GetParserRuleContext()) {
+ case 1:
+ p.EnterOuterAlt(localctx, 1)
+ p.SetState(800)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if ((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&1470645178514538496) != 0) || ((int64((_la-77)) & ^0x3f) == 0 && ((int64(1)<<(_la-77))&27487515910095) != 0) {
+ {
+ p.SetState(797)
+ p.Symbol()
+ }
+ {
+ p.SetState(798)
+ p.Match(CypherParserASSIGN)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ }
+ {
+ p.SetState(802)
+ p.PatternElem()
+ }
+
+ case 2:
+ p.EnterOuterAlt(localctx, 2)
+ p.SetState(806)
+ p.GetErrorHandler().Sync(p)
+
+ if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 107, p.GetParserRuleContext()) == 1 {
+ {
+ p.SetState(803)
+ p.Symbol()
+ }
+ {
+ p.SetState(804)
+ p.Match(CypherParserASSIGN)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ } else if p.HasError() { // JIM
+ goto errorExit
+ }
+ {
+ p.SetState(808)
+ p.PathFunction()
+ }
+
+ case antlr.ATNInvalidAltNumber:
+ goto errorExit
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IPathFunctionContext is an interface to support dynamic dispatch.
+type IPathFunctionContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ LPAREN() antlr.TerminalNode
+ PatternElem() IPatternElemContext
+ RPAREN() antlr.TerminalNode
+ SHORTESTPATH() antlr.TerminalNode
+ ALLSHORTESTPATHS() antlr.TerminalNode
+
+ // IsPathFunctionContext differentiates from other interfaces.
+ IsPathFunctionContext()
+}
+
+type PathFunctionContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyPathFunctionContext() *PathFunctionContext {
+ var p = new(PathFunctionContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_pathFunction
+ return p
+}
+
+func InitEmptyPathFunctionContext(p *PathFunctionContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_pathFunction
+}
+
+func (*PathFunctionContext) IsPathFunctionContext() {}
+
+func NewPathFunctionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *PathFunctionContext {
+ var p = new(PathFunctionContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_pathFunction
+
+ return p
+}
+
+func (s *PathFunctionContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *PathFunctionContext) LPAREN() antlr.TerminalNode {
+ return s.GetToken(CypherParserLPAREN, 0)
+}
+
+func (s *PathFunctionContext) PatternElem() IPatternElemContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IPatternElemContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IPatternElemContext)
+}
+
+func (s *PathFunctionContext) RPAREN() antlr.TerminalNode {
+ return s.GetToken(CypherParserRPAREN, 0)
+}
+
+func (s *PathFunctionContext) SHORTESTPATH() antlr.TerminalNode {
+ return s.GetToken(CypherParserSHORTESTPATH, 0)
+}
+
+func (s *PathFunctionContext) ALLSHORTESTPATHS() antlr.TerminalNode {
+ return s.GetToken(CypherParserALLSHORTESTPATHS, 0)
+}
+
+func (s *PathFunctionContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *PathFunctionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *PathFunctionContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterPathFunction(s)
+ }
+}
+
+func (s *PathFunctionContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitPathFunction(s)
+ }
+}
+
+func (p *CypherParser) PathFunction() (localctx IPathFunctionContext) {
+ localctx = NewPathFunctionContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 122, CypherParserRULE_pathFunction)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(811)
+ _la = p.GetTokenStream().LA(1)
+
+ if !(_la == CypherParserSHORTESTPATH || _la == CypherParserALLSHORTESTPATHS) {
+ p.GetErrorHandler().RecoverInline(p)
+ } else {
+ p.GetErrorHandler().ReportMatch(p)
+ p.Consume()
+ }
+ }
+ {
+ p.SetState(812)
+ p.Match(CypherParserLPAREN)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(813)
+ p.PatternElem()
+ }
+ {
+ p.SetState(814)
+ p.Match(CypherParserRPAREN)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IPatternElemContext is an interface to support dynamic dispatch.
+type IPatternElemContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ NodePattern() INodePatternContext
+ AllPatternElemChain() []IPatternElemChainContext
+ PatternElemChain(i int) IPatternElemChainContext
+ LPAREN() antlr.TerminalNode
+ PatternElem() IPatternElemContext
+ RPAREN() antlr.TerminalNode
+
+ // IsPatternElemContext differentiates from other interfaces.
+ IsPatternElemContext()
+}
+
+type PatternElemContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyPatternElemContext() *PatternElemContext {
+ var p = new(PatternElemContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_patternElem
+ return p
+}
+
+func InitEmptyPatternElemContext(p *PatternElemContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_patternElem
+}
+
+func (*PatternElemContext) IsPatternElemContext() {}
+
+func NewPatternElemContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *PatternElemContext {
+ var p = new(PatternElemContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_patternElem
+
+ return p
+}
+
+func (s *PatternElemContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *PatternElemContext) NodePattern() INodePatternContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(INodePatternContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(INodePatternContext)
+}
+
+func (s *PatternElemContext) AllPatternElemChain() []IPatternElemChainContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IPatternElemChainContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IPatternElemChainContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IPatternElemChainContext); ok {
+ tst[i] = t.(IPatternElemChainContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *PatternElemContext) PatternElemChain(i int) IPatternElemChainContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IPatternElemChainContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IPatternElemChainContext)
+}
+
+func (s *PatternElemContext) LPAREN() antlr.TerminalNode {
+ return s.GetToken(CypherParserLPAREN, 0)
+}
+
+func (s *PatternElemContext) PatternElem() IPatternElemContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IPatternElemContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IPatternElemContext)
+}
+
+func (s *PatternElemContext) RPAREN() antlr.TerminalNode {
+ return s.GetToken(CypherParserRPAREN, 0)
+}
+
+func (s *PatternElemContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *PatternElemContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *PatternElemContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterPatternElem(s)
+ }
+}
+
+func (s *PatternElemContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitPatternElem(s)
+ }
+}
+
+func (p *CypherParser) PatternElem() (localctx IPatternElemContext) {
+ localctx = NewPatternElemContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 124, CypherParserRULE_patternElem)
+ var _la int
+
+ p.SetState(827)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 110, p.GetParserRuleContext()) {
+ case 1:
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(816)
+ p.NodePattern()
+ }
+ p.SetState(820)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for _la == CypherParserLT || _la == CypherParserSUB {
+ {
+ p.SetState(817)
+ p.PatternElemChain()
+ }
+
+ p.SetState(822)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+
+ case 2:
+ p.EnterOuterAlt(localctx, 2)
+ {
+ p.SetState(823)
+ p.Match(CypherParserLPAREN)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(824)
+ p.PatternElem()
+ }
+ {
+ p.SetState(825)
+ p.Match(CypherParserRPAREN)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ case antlr.ATNInvalidAltNumber:
+ goto errorExit
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IPatternElemChainContext is an interface to support dynamic dispatch.
+type IPatternElemChainContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ RelationshipPattern() IRelationshipPatternContext
+ NodePattern() INodePatternContext
+
+ // IsPatternElemChainContext differentiates from other interfaces.
+ IsPatternElemChainContext()
+}
+
+type PatternElemChainContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyPatternElemChainContext() *PatternElemChainContext {
+ var p = new(PatternElemChainContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_patternElemChain
+ return p
+}
+
+func InitEmptyPatternElemChainContext(p *PatternElemChainContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_patternElemChain
+}
+
+func (*PatternElemChainContext) IsPatternElemChainContext() {}
+
+func NewPatternElemChainContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *PatternElemChainContext {
+ var p = new(PatternElemChainContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_patternElemChain
+
+ return p
+}
+
+func (s *PatternElemChainContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *PatternElemChainContext) RelationshipPattern() IRelationshipPatternContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IRelationshipPatternContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IRelationshipPatternContext)
+}
+
+func (s *PatternElemChainContext) NodePattern() INodePatternContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(INodePatternContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(INodePatternContext)
+}
+
+func (s *PatternElemChainContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *PatternElemChainContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *PatternElemChainContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterPatternElemChain(s)
+ }
+}
+
+func (s *PatternElemChainContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitPatternElemChain(s)
+ }
+}
+
+func (p *CypherParser) PatternElemChain() (localctx IPatternElemChainContext) {
+ localctx = NewPatternElemChainContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 126, CypherParserRULE_patternElemChain)
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(829)
+ p.RelationshipPattern()
+ }
+ {
+ p.SetState(830)
+ p.NodePattern()
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IPropertiesContext is an interface to support dynamic dispatch.
+type IPropertiesContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ MapLit() IMapLitContext
+ Parameter() IParameterContext
+
+ // IsPropertiesContext differentiates from other interfaces.
+ IsPropertiesContext()
+}
+
+type PropertiesContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyPropertiesContext() *PropertiesContext {
+ var p = new(PropertiesContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_properties
+ return p
+}
+
+func InitEmptyPropertiesContext(p *PropertiesContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_properties
+}
+
+func (*PropertiesContext) IsPropertiesContext() {}
+
+func NewPropertiesContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *PropertiesContext {
+ var p = new(PropertiesContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_properties
+
+ return p
+}
+
+func (s *PropertiesContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *PropertiesContext) MapLit() IMapLitContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IMapLitContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IMapLitContext)
+}
+
+func (s *PropertiesContext) Parameter() IParameterContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IParameterContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IParameterContext)
+}
+
+func (s *PropertiesContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *PropertiesContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *PropertiesContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterProperties(s)
+ }
+}
+
+func (s *PropertiesContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitProperties(s)
+ }
+}
+
+func (p *CypherParser) Properties() (localctx IPropertiesContext) {
+ localctx = NewPropertiesContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 128, CypherParserRULE_properties)
+ p.SetState(834)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetTokenStream().LA(1) {
+ case CypherParserLBRACE:
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(832)
+ p.MapLit()
+ }
+
+ case CypherParserDOLLAR:
+ p.EnterOuterAlt(localctx, 2)
+ {
+ p.SetState(833)
+ p.Parameter()
+ }
+
+ default:
+ p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil))
+ goto errorExit
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// INodePatternContext is an interface to support dynamic dispatch.
+type INodePatternContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ LPAREN() antlr.TerminalNode
+ RPAREN() antlr.TerminalNode
+ Symbol() ISymbolContext
+ NodeLabels() INodeLabelsContext
+ Properties() IPropertiesContext
+
+ // IsNodePatternContext differentiates from other interfaces.
+ IsNodePatternContext()
+}
+
+type NodePatternContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyNodePatternContext() *NodePatternContext {
+ var p = new(NodePatternContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_nodePattern
+ return p
+}
+
+func InitEmptyNodePatternContext(p *NodePatternContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_nodePattern
+}
+
+func (*NodePatternContext) IsNodePatternContext() {}
+
+func NewNodePatternContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *NodePatternContext {
+ var p = new(NodePatternContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_nodePattern
+
+ return p
+}
+
+func (s *NodePatternContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *NodePatternContext) LPAREN() antlr.TerminalNode {
+ return s.GetToken(CypherParserLPAREN, 0)
+}
+
+func (s *NodePatternContext) RPAREN() antlr.TerminalNode {
+ return s.GetToken(CypherParserRPAREN, 0)
+}
+
+func (s *NodePatternContext) Symbol() ISymbolContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ISymbolContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ISymbolContext)
+}
+
+func (s *NodePatternContext) NodeLabels() INodeLabelsContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(INodeLabelsContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(INodeLabelsContext)
+}
+
+func (s *NodePatternContext) Properties() IPropertiesContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IPropertiesContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IPropertiesContext)
+}
+
+func (s *NodePatternContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *NodePatternContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *NodePatternContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterNodePattern(s)
+ }
+}
+
+func (s *NodePatternContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitNodePattern(s)
+ }
+}
+
+func (p *CypherParser) NodePattern() (localctx INodePatternContext) {
+ localctx = NewNodePatternContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 130, CypherParserRULE_nodePattern)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(836)
+ p.Match(CypherParserLPAREN)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(838)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if ((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&1470645178514538496) != 0) || ((int64((_la-77)) & ^0x3f) == 0 && ((int64(1)<<(_la-77))&27487515910095) != 0) {
+ {
+ p.SetState(837)
+ p.Symbol()
+ }
+
+ }
+ p.SetState(841)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserCOLON {
+ {
+ p.SetState(840)
+ p.NodeLabels()
+ }
+
+ }
+ p.SetState(844)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserLBRACE || _la == CypherParserDOLLAR {
+ {
+ p.SetState(843)
+ p.Properties()
+ }
+
+ }
+ {
+ p.SetState(846)
+ p.Match(CypherParserRPAREN)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IAtomContext is an interface to support dynamic dispatch.
+type IAtomContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ Literal() ILiteralContext
+ Parameter() IParameterContext
+ CaseExpression() ICaseExpressionContext
+ CountAll() ICountAllContext
+ ListComprehension() IListComprehensionContext
+ PatternComprehension() IPatternComprehensionContext
+ FilterWith() IFilterWithContext
+ RelationshipsChainPattern() IRelationshipsChainPatternContext
+ ParenthesizedExpression() IParenthesizedExpressionContext
+ FunctionInvocation() IFunctionInvocationContext
+ Symbol() ISymbolContext
+ SubqueryExist() ISubqueryExistContext
+
+ // IsAtomContext differentiates from other interfaces.
+ IsAtomContext()
+}
+
+type AtomContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyAtomContext() *AtomContext {
+ var p = new(AtomContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_atom
+ return p
+}
+
+func InitEmptyAtomContext(p *AtomContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_atom
+}
+
+func (*AtomContext) IsAtomContext() {}
+
+func NewAtomContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *AtomContext {
+ var p = new(AtomContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_atom
+
+ return p
+}
+
+func (s *AtomContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *AtomContext) Literal() ILiteralContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ILiteralContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ILiteralContext)
+}
+
+func (s *AtomContext) Parameter() IParameterContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IParameterContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IParameterContext)
+}
+
+func (s *AtomContext) CaseExpression() ICaseExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ICaseExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ICaseExpressionContext)
+}
+
+func (s *AtomContext) CountAll() ICountAllContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ICountAllContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ICountAllContext)
+}
+
+func (s *AtomContext) ListComprehension() IListComprehensionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IListComprehensionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IListComprehensionContext)
+}
+
+func (s *AtomContext) PatternComprehension() IPatternComprehensionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IPatternComprehensionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IPatternComprehensionContext)
+}
+
+func (s *AtomContext) FilterWith() IFilterWithContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IFilterWithContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IFilterWithContext)
+}
+
+func (s *AtomContext) RelationshipsChainPattern() IRelationshipsChainPatternContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IRelationshipsChainPatternContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IRelationshipsChainPatternContext)
+}
+
+func (s *AtomContext) ParenthesizedExpression() IParenthesizedExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IParenthesizedExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IParenthesizedExpressionContext)
+}
+
+func (s *AtomContext) FunctionInvocation() IFunctionInvocationContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IFunctionInvocationContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IFunctionInvocationContext)
+}
+
+func (s *AtomContext) Symbol() ISymbolContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ISymbolContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ISymbolContext)
+}
+
+func (s *AtomContext) SubqueryExist() ISubqueryExistContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ISubqueryExistContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ISubqueryExistContext)
+}
+
+func (s *AtomContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *AtomContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *AtomContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterAtom(s)
+ }
+}
+
+func (s *AtomContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitAtom(s)
+ }
+}
+
+func (p *CypherParser) Atom() (localctx IAtomContext) {
+ localctx = NewAtomContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 132, CypherParserRULE_atom)
+ p.SetState(860)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 115, p.GetParserRuleContext()) {
+ case 1:
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(848)
+ p.Literal()
+ }
+
+ case 2:
+ p.EnterOuterAlt(localctx, 2)
+ {
+ p.SetState(849)
+ p.Parameter()
+ }
+
+ case 3:
+ p.EnterOuterAlt(localctx, 3)
+ {
+ p.SetState(850)
+ p.CaseExpression()
+ }
+
+ case 4:
+ p.EnterOuterAlt(localctx, 4)
+ {
+ p.SetState(851)
+ p.CountAll()
+ }
+
+ case 5:
+ p.EnterOuterAlt(localctx, 5)
+ {
+ p.SetState(852)
+ p.ListComprehension()
+ }
+
+ case 6:
+ p.EnterOuterAlt(localctx, 6)
+ {
+ p.SetState(853)
+ p.PatternComprehension()
+ }
+
+ case 7:
+ p.EnterOuterAlt(localctx, 7)
+ {
+ p.SetState(854)
+ p.FilterWith()
+ }
+
+ case 8:
+ p.EnterOuterAlt(localctx, 8)
+ {
+ p.SetState(855)
+ p.RelationshipsChainPattern()
+ }
+
+ case 9:
+ p.EnterOuterAlt(localctx, 9)
+ {
+ p.SetState(856)
+ p.ParenthesizedExpression()
+ }
+
+ case 10:
+ p.EnterOuterAlt(localctx, 10)
+ {
+ p.SetState(857)
+ p.FunctionInvocation()
+ }
+
+ case 11:
+ p.EnterOuterAlt(localctx, 11)
+ {
+ p.SetState(858)
+ p.Symbol()
+ }
+
+ case 12:
+ p.EnterOuterAlt(localctx, 12)
+ {
+ p.SetState(859)
+ p.SubqueryExist()
+ }
+
+ case antlr.ATNInvalidAltNumber:
+ goto errorExit
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// ILhsContext is an interface to support dynamic dispatch.
+type ILhsContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ Symbol() ISymbolContext
+ ASSIGN() antlr.TerminalNode
+
+ // IsLhsContext differentiates from other interfaces.
+ IsLhsContext()
+}
+
+type LhsContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyLhsContext() *LhsContext {
+ var p = new(LhsContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_lhs
+ return p
+}
+
+func InitEmptyLhsContext(p *LhsContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_lhs
+}
+
+func (*LhsContext) IsLhsContext() {}
+
+func NewLhsContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *LhsContext {
+ var p = new(LhsContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_lhs
+
+ return p
+}
+
+func (s *LhsContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *LhsContext) Symbol() ISymbolContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ISymbolContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ISymbolContext)
+}
+
+func (s *LhsContext) ASSIGN() antlr.TerminalNode {
+ return s.GetToken(CypherParserASSIGN, 0)
+}
+
+func (s *LhsContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *LhsContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *LhsContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterLhs(s)
+ }
+}
+
+func (s *LhsContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitLhs(s)
+ }
+}
+
+func (p *CypherParser) Lhs() (localctx ILhsContext) {
+ localctx = NewLhsContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 134, CypherParserRULE_lhs)
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(862)
+ p.Symbol()
+ }
+ {
+ p.SetState(863)
+ p.Match(CypherParserASSIGN)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IRelationshipPatternContext is an interface to support dynamic dispatch.
+type IRelationshipPatternContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ LT() antlr.TerminalNode
+ AllSUB() []antlr.TerminalNode
+ SUB(i int) antlr.TerminalNode
+ RelationDetail() IRelationDetailContext
+ GT() antlr.TerminalNode
+
+ // IsRelationshipPatternContext differentiates from other interfaces.
+ IsRelationshipPatternContext()
+}
+
+type RelationshipPatternContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyRelationshipPatternContext() *RelationshipPatternContext {
+ var p = new(RelationshipPatternContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_relationshipPattern
+ return p
+}
+
+func InitEmptyRelationshipPatternContext(p *RelationshipPatternContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_relationshipPattern
+}
+
+func (*RelationshipPatternContext) IsRelationshipPatternContext() {}
+
+func NewRelationshipPatternContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *RelationshipPatternContext {
+ var p = new(RelationshipPatternContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_relationshipPattern
+
+ return p
+}
+
+func (s *RelationshipPatternContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *RelationshipPatternContext) LT() antlr.TerminalNode {
+ return s.GetToken(CypherParserLT, 0)
+}
+
+func (s *RelationshipPatternContext) AllSUB() []antlr.TerminalNode {
+ return s.GetTokens(CypherParserSUB)
+}
+
+func (s *RelationshipPatternContext) SUB(i int) antlr.TerminalNode {
+ return s.GetToken(CypherParserSUB, i)
+}
+
+func (s *RelationshipPatternContext) RelationDetail() IRelationDetailContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IRelationDetailContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IRelationDetailContext)
+}
+
+func (s *RelationshipPatternContext) GT() antlr.TerminalNode {
+ return s.GetToken(CypherParserGT, 0)
+}
+
+func (s *RelationshipPatternContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *RelationshipPatternContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *RelationshipPatternContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterRelationshipPattern(s)
+ }
+}
+
+func (s *RelationshipPatternContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitRelationshipPattern(s)
+ }
+}
+
+func (p *CypherParser) RelationshipPattern() (localctx IRelationshipPatternContext) {
+ localctx = NewRelationshipPatternContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 136, CypherParserRULE_relationshipPattern)
+ var _la int
+
+ p.SetState(882)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetTokenStream().LA(1) {
+ case CypherParserLT:
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(865)
+ p.Match(CypherParserLT)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(866)
+ p.Match(CypherParserSUB)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(868)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserLBRACK {
+ {
+ p.SetState(867)
+ p.RelationDetail()
+ }
+
+ }
+ {
+ p.SetState(870)
+ p.Match(CypherParserSUB)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(872)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserGT {
+ {
+ p.SetState(871)
+ p.Match(CypherParserGT)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ }
+
+ case CypherParserSUB:
+ p.EnterOuterAlt(localctx, 2)
+ {
+ p.SetState(874)
+ p.Match(CypherParserSUB)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(876)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserLBRACK {
+ {
+ p.SetState(875)
+ p.RelationDetail()
+ }
+
+ }
+ {
+ p.SetState(878)
+ p.Match(CypherParserSUB)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(880)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserGT {
+ {
+ p.SetState(879)
+ p.Match(CypherParserGT)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ }
+
+ default:
+ p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil))
+ goto errorExit
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IRelationDetailContext is an interface to support dynamic dispatch.
+type IRelationDetailContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ LBRACK() antlr.TerminalNode
+ RBRACK() antlr.TerminalNode
+ Symbol() ISymbolContext
+ RelationshipTypes() IRelationshipTypesContext
+ RangeLit() IRangeLitContext
+ Properties() IPropertiesContext
+
+ // IsRelationDetailContext differentiates from other interfaces.
+ IsRelationDetailContext()
+}
+
+type RelationDetailContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyRelationDetailContext() *RelationDetailContext {
+ var p = new(RelationDetailContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_relationDetail
+ return p
+}
+
+func InitEmptyRelationDetailContext(p *RelationDetailContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_relationDetail
+}
+
+func (*RelationDetailContext) IsRelationDetailContext() {}
+
+func NewRelationDetailContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *RelationDetailContext {
+ var p = new(RelationDetailContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_relationDetail
+
+ return p
+}
+
+func (s *RelationDetailContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *RelationDetailContext) LBRACK() antlr.TerminalNode {
+ return s.GetToken(CypherParserLBRACK, 0)
+}
+
+func (s *RelationDetailContext) RBRACK() antlr.TerminalNode {
+ return s.GetToken(CypherParserRBRACK, 0)
+}
+
+func (s *RelationDetailContext) Symbol() ISymbolContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ISymbolContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ISymbolContext)
+}
+
+func (s *RelationDetailContext) RelationshipTypes() IRelationshipTypesContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IRelationshipTypesContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IRelationshipTypesContext)
+}
+
+func (s *RelationDetailContext) RangeLit() IRangeLitContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IRangeLitContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IRangeLitContext)
+}
+
+func (s *RelationDetailContext) Properties() IPropertiesContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IPropertiesContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IPropertiesContext)
+}
+
+func (s *RelationDetailContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *RelationDetailContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *RelationDetailContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterRelationDetail(s)
+ }
+}
+
+func (s *RelationDetailContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitRelationDetail(s)
+ }
+}
+
+func (p *CypherParser) RelationDetail() (localctx IRelationDetailContext) {
+ localctx = NewRelationDetailContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 138, CypherParserRULE_relationDetail)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(884)
+ p.Match(CypherParserLBRACK)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(886)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if ((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&1470645178514538496) != 0) || ((int64((_la-77)) & ^0x3f) == 0 && ((int64(1)<<(_la-77))&27487515910095) != 0) {
+ {
+ p.SetState(885)
+ p.Symbol()
+ }
+
+ }
+ p.SetState(889)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserCOLON {
+ {
+ p.SetState(888)
+ p.RelationshipTypes()
+ }
+
+ }
+ p.SetState(892)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserMULT {
+ {
+ p.SetState(891)
+ p.RangeLit()
+ }
+
+ }
+ p.SetState(895)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserLBRACE || _la == CypherParserDOLLAR {
+ {
+ p.SetState(894)
+ p.Properties()
+ }
+
+ }
+ {
+ p.SetState(897)
+ p.Match(CypherParserRBRACK)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IRelationshipTypesContext is an interface to support dynamic dispatch.
+type IRelationshipTypesContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ AllCOLON() []antlr.TerminalNode
+ COLON(i int) antlr.TerminalNode
+ AllName() []INameContext
+ Name(i int) INameContext
+ AllSTICK() []antlr.TerminalNode
+ STICK(i int) antlr.TerminalNode
+
+ // IsRelationshipTypesContext differentiates from other interfaces.
+ IsRelationshipTypesContext()
+}
+
+type RelationshipTypesContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyRelationshipTypesContext() *RelationshipTypesContext {
+ var p = new(RelationshipTypesContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_relationshipTypes
+ return p
+}
+
+func InitEmptyRelationshipTypesContext(p *RelationshipTypesContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_relationshipTypes
+}
+
+func (*RelationshipTypesContext) IsRelationshipTypesContext() {}
+
+func NewRelationshipTypesContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *RelationshipTypesContext {
+ var p = new(RelationshipTypesContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_relationshipTypes
+
+ return p
+}
+
+func (s *RelationshipTypesContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *RelationshipTypesContext) AllCOLON() []antlr.TerminalNode {
+ return s.GetTokens(CypherParserCOLON)
+}
+
+func (s *RelationshipTypesContext) COLON(i int) antlr.TerminalNode {
+ return s.GetToken(CypherParserCOLON, i)
+}
+
+func (s *RelationshipTypesContext) AllName() []INameContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(INameContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]INameContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(INameContext); ok {
+ tst[i] = t.(INameContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *RelationshipTypesContext) Name(i int) INameContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(INameContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(INameContext)
+}
+
+func (s *RelationshipTypesContext) AllSTICK() []antlr.TerminalNode {
+ return s.GetTokens(CypherParserSTICK)
+}
+
+func (s *RelationshipTypesContext) STICK(i int) antlr.TerminalNode {
+ return s.GetToken(CypherParserSTICK, i)
+}
+
+func (s *RelationshipTypesContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *RelationshipTypesContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *RelationshipTypesContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterRelationshipTypes(s)
+ }
+}
+
+func (s *RelationshipTypesContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitRelationshipTypes(s)
+ }
+}
+
+func (p *CypherParser) RelationshipTypes() (localctx IRelationshipTypesContext) {
+ localctx = NewRelationshipTypesContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 140, CypherParserRULE_relationshipTypes)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(899)
+ p.Match(CypherParserCOLON)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(900)
+ p.Name()
+ }
+ p.SetState(908)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for _la == CypherParserSTICK {
+ {
+ p.SetState(901)
+ p.Match(CypherParserSTICK)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(903)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserCOLON {
+ {
+ p.SetState(902)
+ p.Match(CypherParserCOLON)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ }
+ {
+ p.SetState(905)
+ p.Name()
+ }
+
+ p.SetState(910)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IUnionStContext is an interface to support dynamic dispatch.
+type IUnionStContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ UNION() antlr.TerminalNode
+ SingleQuery() ISingleQueryContext
+ ALL() antlr.TerminalNode
+
+ // IsUnionStContext differentiates from other interfaces.
+ IsUnionStContext()
+}
+
+type UnionStContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyUnionStContext() *UnionStContext {
+ var p = new(UnionStContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_unionSt
+ return p
+}
+
+func InitEmptyUnionStContext(p *UnionStContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_unionSt
+}
+
+func (*UnionStContext) IsUnionStContext() {}
+
+func NewUnionStContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *UnionStContext {
+ var p = new(UnionStContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_unionSt
+
+ return p
+}
+
+func (s *UnionStContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *UnionStContext) UNION() antlr.TerminalNode {
+ return s.GetToken(CypherParserUNION, 0)
+}
+
+func (s *UnionStContext) SingleQuery() ISingleQueryContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ISingleQueryContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ISingleQueryContext)
+}
+
+func (s *UnionStContext) ALL() antlr.TerminalNode {
+ return s.GetToken(CypherParserALL, 0)
+}
+
+func (s *UnionStContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *UnionStContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *UnionStContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterUnionSt(s)
+ }
+}
+
+func (s *UnionStContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitUnionSt(s)
+ }
+}
+
+func (p *CypherParser) UnionSt() (localctx IUnionStContext) {
+ localctx = NewUnionStContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 142, CypherParserRULE_unionSt)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(911)
+ p.Match(CypherParserUNION)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(913)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserALL {
+ {
+ p.SetState(912)
+ p.Match(CypherParserALL)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ }
+ {
+ p.SetState(915)
+ p.SingleQuery()
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// ISubqueryExistContext is an interface to support dynamic dispatch.
+type ISubqueryExistContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ EXISTS() antlr.TerminalNode
+ LBRACE() antlr.TerminalNode
+ RBRACE() antlr.TerminalNode
+ RegularQuery() IRegularQueryContext
+ PatternWhere() IPatternWhereContext
+
+ // IsSubqueryExistContext differentiates from other interfaces.
+ IsSubqueryExistContext()
+}
+
+type SubqueryExistContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptySubqueryExistContext() *SubqueryExistContext {
+ var p = new(SubqueryExistContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_subqueryExist
+ return p
+}
+
+func InitEmptySubqueryExistContext(p *SubqueryExistContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_subqueryExist
+}
+
+func (*SubqueryExistContext) IsSubqueryExistContext() {}
+
+func NewSubqueryExistContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *SubqueryExistContext {
+ var p = new(SubqueryExistContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_subqueryExist
+
+ return p
+}
+
+func (s *SubqueryExistContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *SubqueryExistContext) EXISTS() antlr.TerminalNode {
+ return s.GetToken(CypherParserEXISTS, 0)
+}
+
+func (s *SubqueryExistContext) LBRACE() antlr.TerminalNode {
+ return s.GetToken(CypherParserLBRACE, 0)
+}
+
+func (s *SubqueryExistContext) RBRACE() antlr.TerminalNode {
+ return s.GetToken(CypherParserRBRACE, 0)
+}
+
+func (s *SubqueryExistContext) RegularQuery() IRegularQueryContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IRegularQueryContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IRegularQueryContext)
+}
+
+func (s *SubqueryExistContext) PatternWhere() IPatternWhereContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IPatternWhereContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IPatternWhereContext)
+}
+
+func (s *SubqueryExistContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *SubqueryExistContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *SubqueryExistContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterSubqueryExist(s)
+ }
+}
+
+func (s *SubqueryExistContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitSubqueryExist(s)
+ }
+}
+
+func (p *CypherParser) SubqueryExist() (localctx ISubqueryExistContext) {
+ localctx = NewSubqueryExistContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 144, CypherParserRULE_subqueryExist)
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(917)
+ p.Match(CypherParserEXISTS)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(918)
+ p.Match(CypherParserLBRACE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(921)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 128, p.GetParserRuleContext()) {
+ case 1:
+ {
+ p.SetState(919)
+ p.RegularQuery()
+ }
+
+ case 2:
+ {
+ p.SetState(920)
+ p.PatternWhere()
+ }
+
+ case antlr.ATNInvalidAltNumber:
+ goto errorExit
+ }
+ {
+ p.SetState(923)
+ p.Match(CypherParserRBRACE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IInvocationNameContext is an interface to support dynamic dispatch.
+type IInvocationNameContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ AllSymbol() []ISymbolContext
+ Symbol(i int) ISymbolContext
+ AllDOT() []antlr.TerminalNode
+ DOT(i int) antlr.TerminalNode
+
+ // IsInvocationNameContext differentiates from other interfaces.
+ IsInvocationNameContext()
+}
+
+type InvocationNameContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyInvocationNameContext() *InvocationNameContext {
+ var p = new(InvocationNameContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_invocationName
+ return p
+}
+
+func InitEmptyInvocationNameContext(p *InvocationNameContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_invocationName
+}
+
+func (*InvocationNameContext) IsInvocationNameContext() {}
+
+func NewInvocationNameContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *InvocationNameContext {
+ var p = new(InvocationNameContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_invocationName
+
+ return p
+}
+
+func (s *InvocationNameContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *InvocationNameContext) AllSymbol() []ISymbolContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(ISymbolContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]ISymbolContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(ISymbolContext); ok {
+ tst[i] = t.(ISymbolContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *InvocationNameContext) Symbol(i int) ISymbolContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ISymbolContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ISymbolContext)
+}
+
+func (s *InvocationNameContext) AllDOT() []antlr.TerminalNode {
+ return s.GetTokens(CypherParserDOT)
+}
+
+func (s *InvocationNameContext) DOT(i int) antlr.TerminalNode {
+ return s.GetToken(CypherParserDOT, i)
+}
+
+func (s *InvocationNameContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *InvocationNameContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *InvocationNameContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterInvocationName(s)
+ }
+}
+
+func (s *InvocationNameContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitInvocationName(s)
+ }
+}
+
+func (p *CypherParser) InvocationName() (localctx IInvocationNameContext) {
+ localctx = NewInvocationNameContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 146, CypherParserRULE_invocationName)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(925)
+ p.Symbol()
+ }
+ p.SetState(930)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for _la == CypherParserDOT {
+ {
+ p.SetState(926)
+ p.Match(CypherParserDOT)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(927)
+ p.Symbol()
+ }
+
+ p.SetState(932)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IFunctionInvocationContext is an interface to support dynamic dispatch.
+type IFunctionInvocationContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ InvocationName() IInvocationNameContext
+ LPAREN() antlr.TerminalNode
+ RPAREN() antlr.TerminalNode
+ DISTINCT() antlr.TerminalNode
+ ExpressionChain() IExpressionChainContext
+
+ // IsFunctionInvocationContext differentiates from other interfaces.
+ IsFunctionInvocationContext()
+}
+
+type FunctionInvocationContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyFunctionInvocationContext() *FunctionInvocationContext {
+ var p = new(FunctionInvocationContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_functionInvocation
+ return p
+}
+
+func InitEmptyFunctionInvocationContext(p *FunctionInvocationContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_functionInvocation
+}
+
+func (*FunctionInvocationContext) IsFunctionInvocationContext() {}
+
+func NewFunctionInvocationContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *FunctionInvocationContext {
+ var p = new(FunctionInvocationContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_functionInvocation
+
+ return p
+}
+
+func (s *FunctionInvocationContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *FunctionInvocationContext) InvocationName() IInvocationNameContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IInvocationNameContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IInvocationNameContext)
+}
+
+func (s *FunctionInvocationContext) LPAREN() antlr.TerminalNode {
+ return s.GetToken(CypherParserLPAREN, 0)
+}
+
+func (s *FunctionInvocationContext) RPAREN() antlr.TerminalNode {
+ return s.GetToken(CypherParserRPAREN, 0)
+}
+
+func (s *FunctionInvocationContext) DISTINCT() antlr.TerminalNode {
+ return s.GetToken(CypherParserDISTINCT, 0)
+}
+
+func (s *FunctionInvocationContext) ExpressionChain() IExpressionChainContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IExpressionChainContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IExpressionChainContext)
+}
+
+func (s *FunctionInvocationContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *FunctionInvocationContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *FunctionInvocationContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterFunctionInvocation(s)
+ }
+}
+
+func (s *FunctionInvocationContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitFunctionInvocation(s)
+ }
+}
+
+func (p *CypherParser) FunctionInvocation() (localctx IFunctionInvocationContext) {
+ localctx = NewFunctionInvocationContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 148, CypherParserRULE_functionInvocation)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(933)
+ p.InvocationName()
+ }
+ {
+ p.SetState(934)
+ p.Match(CypherParserLPAREN)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(936)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserDISTINCT {
+ {
+ p.SetState(935)
+ p.Match(CypherParserDISTINCT)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ }
+ p.SetState(939)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if ((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&1470645178784718848) != 0) || ((int64((_la-73)) & ^0x3f) == 0 && ((int64(1)<<(_la-73))&2251795417136369) != 0) {
+ {
+ p.SetState(938)
+ p.ExpressionChain()
+ }
+
+ }
+ {
+ p.SetState(941)
+ p.Match(CypherParserRPAREN)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IParenthesizedExpressionContext is an interface to support dynamic dispatch.
+type IParenthesizedExpressionContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ LPAREN() antlr.TerminalNode
+ Expression() IExpressionContext
+ RPAREN() antlr.TerminalNode
+
+ // IsParenthesizedExpressionContext differentiates from other interfaces.
+ IsParenthesizedExpressionContext()
+}
+
+type ParenthesizedExpressionContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyParenthesizedExpressionContext() *ParenthesizedExpressionContext {
+ var p = new(ParenthesizedExpressionContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_parenthesizedExpression
+ return p
+}
+
+func InitEmptyParenthesizedExpressionContext(p *ParenthesizedExpressionContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_parenthesizedExpression
+}
+
+func (*ParenthesizedExpressionContext) IsParenthesizedExpressionContext() {}
+
+func NewParenthesizedExpressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ParenthesizedExpressionContext {
+ var p = new(ParenthesizedExpressionContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_parenthesizedExpression
+
+ return p
+}
+
+func (s *ParenthesizedExpressionContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *ParenthesizedExpressionContext) LPAREN() antlr.TerminalNode {
+ return s.GetToken(CypherParserLPAREN, 0)
+}
+
+func (s *ParenthesizedExpressionContext) Expression() IExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IExpressionContext)
+}
+
+func (s *ParenthesizedExpressionContext) RPAREN() antlr.TerminalNode {
+ return s.GetToken(CypherParserRPAREN, 0)
+}
+
+func (s *ParenthesizedExpressionContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *ParenthesizedExpressionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *ParenthesizedExpressionContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterParenthesizedExpression(s)
+ }
+}
+
+func (s *ParenthesizedExpressionContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitParenthesizedExpression(s)
+ }
+}
+
+func (p *CypherParser) ParenthesizedExpression() (localctx IParenthesizedExpressionContext) {
+ localctx = NewParenthesizedExpressionContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 150, CypherParserRULE_parenthesizedExpression)
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(943)
+ p.Match(CypherParserLPAREN)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(944)
+ p.Expression()
+ }
+ {
+ p.SetState(945)
+ p.Match(CypherParserRPAREN)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IFilterWithContext is an interface to support dynamic dispatch.
+type IFilterWithContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ LPAREN() antlr.TerminalNode
+ FilterExpression() IFilterExpressionContext
+ RPAREN() antlr.TerminalNode
+ ALL() antlr.TerminalNode
+ ANY() antlr.TerminalNode
+ NONE() antlr.TerminalNode
+ SINGLE() antlr.TerminalNode
+
+ // IsFilterWithContext differentiates from other interfaces.
+ IsFilterWithContext()
+}
+
+type FilterWithContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyFilterWithContext() *FilterWithContext {
+ var p = new(FilterWithContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_filterWith
+ return p
+}
+
+func InitEmptyFilterWithContext(p *FilterWithContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_filterWith
+}
+
+func (*FilterWithContext) IsFilterWithContext() {}
+
+func NewFilterWithContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *FilterWithContext {
+ var p = new(FilterWithContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_filterWith
+
+ return p
+}
+
+func (s *FilterWithContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *FilterWithContext) LPAREN() antlr.TerminalNode {
+ return s.GetToken(CypherParserLPAREN, 0)
+}
+
+func (s *FilterWithContext) FilterExpression() IFilterExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IFilterExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IFilterExpressionContext)
+}
+
+func (s *FilterWithContext) RPAREN() antlr.TerminalNode {
+ return s.GetToken(CypherParserRPAREN, 0)
+}
+
+func (s *FilterWithContext) ALL() antlr.TerminalNode {
+ return s.GetToken(CypherParserALL, 0)
+}
+
+func (s *FilterWithContext) ANY() antlr.TerminalNode {
+ return s.GetToken(CypherParserANY, 0)
+}
+
+func (s *FilterWithContext) NONE() antlr.TerminalNode {
+ return s.GetToken(CypherParserNONE, 0)
+}
+
+func (s *FilterWithContext) SINGLE() antlr.TerminalNode {
+ return s.GetToken(CypherParserSINGLE, 0)
+}
+
+func (s *FilterWithContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *FilterWithContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *FilterWithContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterFilterWith(s)
+ }
+}
+
+func (s *FilterWithContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitFilterWith(s)
+ }
+}
+
+func (p *CypherParser) FilterWith() (localctx IFilterWithContext) {
+ localctx = NewFilterWithContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 152, CypherParserRULE_filterWith)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(947)
+ _la = p.GetTokenStream().LA(1)
+
+ if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&8246337208320) != 0) {
+ p.GetErrorHandler().RecoverInline(p)
+ } else {
+ p.GetErrorHandler().ReportMatch(p)
+ p.Consume()
+ }
+ }
+ {
+ p.SetState(948)
+ p.Match(CypherParserLPAREN)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(949)
+ p.FilterExpression()
+ }
+ {
+ p.SetState(950)
+ p.Match(CypherParserRPAREN)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IPatternComprehensionContext is an interface to support dynamic dispatch.
+type IPatternComprehensionContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ LBRACK() antlr.TerminalNode
+ RelationshipsChainPattern() IRelationshipsChainPatternContext
+ STICK() antlr.TerminalNode
+ Expression() IExpressionContext
+ RBRACK() antlr.TerminalNode
+ Lhs() ILhsContext
+ Where() IWhereContext
+
+ // IsPatternComprehensionContext differentiates from other interfaces.
+ IsPatternComprehensionContext()
+}
+
+type PatternComprehensionContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyPatternComprehensionContext() *PatternComprehensionContext {
+ var p = new(PatternComprehensionContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_patternComprehension
+ return p
+}
+
+func InitEmptyPatternComprehensionContext(p *PatternComprehensionContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_patternComprehension
+}
+
+func (*PatternComprehensionContext) IsPatternComprehensionContext() {}
+
+func NewPatternComprehensionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *PatternComprehensionContext {
+ var p = new(PatternComprehensionContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_patternComprehension
+
+ return p
+}
+
+func (s *PatternComprehensionContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *PatternComprehensionContext) LBRACK() antlr.TerminalNode {
+ return s.GetToken(CypherParserLBRACK, 0)
+}
+
+func (s *PatternComprehensionContext) RelationshipsChainPattern() IRelationshipsChainPatternContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IRelationshipsChainPatternContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IRelationshipsChainPatternContext)
+}
+
+func (s *PatternComprehensionContext) STICK() antlr.TerminalNode {
+ return s.GetToken(CypherParserSTICK, 0)
+}
+
+func (s *PatternComprehensionContext) Expression() IExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IExpressionContext)
+}
+
+func (s *PatternComprehensionContext) RBRACK() antlr.TerminalNode {
+ return s.GetToken(CypherParserRBRACK, 0)
+}
+
+func (s *PatternComprehensionContext) Lhs() ILhsContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ILhsContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ILhsContext)
+}
+
+func (s *PatternComprehensionContext) Where() IWhereContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IWhereContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IWhereContext)
+}
+
+func (s *PatternComprehensionContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *PatternComprehensionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *PatternComprehensionContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterPatternComprehension(s)
+ }
+}
+
+func (s *PatternComprehensionContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitPatternComprehension(s)
+ }
+}
+
+func (p *CypherParser) PatternComprehension() (localctx IPatternComprehensionContext) {
+ localctx = NewPatternComprehensionContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 154, CypherParserRULE_patternComprehension)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(952)
+ p.Match(CypherParserLBRACK)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(954)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if ((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&1470645178514538496) != 0) || ((int64((_la-77)) & ^0x3f) == 0 && ((int64(1)<<(_la-77))&27487515910095) != 0) {
+ {
+ p.SetState(953)
+ p.Lhs()
+ }
+
+ }
+ {
+ p.SetState(956)
+ p.RelationshipsChainPattern()
+ }
+ p.SetState(958)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserWHERE {
+ {
+ p.SetState(957)
+ p.Where()
+ }
+
+ }
+ {
+ p.SetState(960)
+ p.Match(CypherParserSTICK)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(961)
+ p.Expression()
+ }
+ {
+ p.SetState(962)
+ p.Match(CypherParserRBRACK)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IRelationshipsChainPatternContext is an interface to support dynamic dispatch.
+type IRelationshipsChainPatternContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ NodePattern() INodePatternContext
+ AllPatternElemChain() []IPatternElemChainContext
+ PatternElemChain(i int) IPatternElemChainContext
+
+ // IsRelationshipsChainPatternContext differentiates from other interfaces.
+ IsRelationshipsChainPatternContext()
+}
+
+type RelationshipsChainPatternContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyRelationshipsChainPatternContext() *RelationshipsChainPatternContext {
+ var p = new(RelationshipsChainPatternContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_relationshipsChainPattern
+ return p
+}
+
+func InitEmptyRelationshipsChainPatternContext(p *RelationshipsChainPatternContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_relationshipsChainPattern
+}
+
+func (*RelationshipsChainPatternContext) IsRelationshipsChainPatternContext() {}
+
+func NewRelationshipsChainPatternContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *RelationshipsChainPatternContext {
+ var p = new(RelationshipsChainPatternContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_relationshipsChainPattern
+
+ return p
+}
+
+func (s *RelationshipsChainPatternContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *RelationshipsChainPatternContext) NodePattern() INodePatternContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(INodePatternContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(INodePatternContext)
+}
+
+func (s *RelationshipsChainPatternContext) AllPatternElemChain() []IPatternElemChainContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IPatternElemChainContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IPatternElemChainContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IPatternElemChainContext); ok {
+ tst[i] = t.(IPatternElemChainContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *RelationshipsChainPatternContext) PatternElemChain(i int) IPatternElemChainContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IPatternElemChainContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IPatternElemChainContext)
+}
+
+func (s *RelationshipsChainPatternContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *RelationshipsChainPatternContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *RelationshipsChainPatternContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterRelationshipsChainPattern(s)
+ }
+}
+
+func (s *RelationshipsChainPatternContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitRelationshipsChainPattern(s)
+ }
+}
+
+func (p *CypherParser) RelationshipsChainPattern() (localctx IRelationshipsChainPatternContext) {
+ localctx = NewRelationshipsChainPatternContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 156, CypherParserRULE_relationshipsChainPattern)
+ var _alt int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(964)
+ p.NodePattern()
+ }
+ p.SetState(966)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _alt = 1
+ for ok := true; ok; ok = _alt != 2 && _alt != antlr.ATNInvalidAltNumber {
+ switch _alt {
+ case 1:
+ {
+ p.SetState(965)
+ p.PatternElemChain()
+ }
+
+ default:
+ p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil))
+ goto errorExit
+ }
+
+ p.SetState(968)
+ p.GetErrorHandler().Sync(p)
+ _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 134, p.GetParserRuleContext())
+ if p.HasError() {
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IListComprehensionContext is an interface to support dynamic dispatch.
+type IListComprehensionContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ LBRACK() antlr.TerminalNode
+ FilterExpression() IFilterExpressionContext
+ RBRACK() antlr.TerminalNode
+ STICK() antlr.TerminalNode
+ Expression() IExpressionContext
+
+ // IsListComprehensionContext differentiates from other interfaces.
+ IsListComprehensionContext()
+}
+
+type ListComprehensionContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyListComprehensionContext() *ListComprehensionContext {
+ var p = new(ListComprehensionContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_listComprehension
+ return p
+}
+
+func InitEmptyListComprehensionContext(p *ListComprehensionContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_listComprehension
+}
+
+func (*ListComprehensionContext) IsListComprehensionContext() {}
+
+func NewListComprehensionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ListComprehensionContext {
+ var p = new(ListComprehensionContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_listComprehension
+
+ return p
+}
+
+func (s *ListComprehensionContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *ListComprehensionContext) LBRACK() antlr.TerminalNode {
+ return s.GetToken(CypherParserLBRACK, 0)
+}
+
+func (s *ListComprehensionContext) FilterExpression() IFilterExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IFilterExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IFilterExpressionContext)
+}
+
+func (s *ListComprehensionContext) RBRACK() antlr.TerminalNode {
+ return s.GetToken(CypherParserRBRACK, 0)
+}
+
+func (s *ListComprehensionContext) STICK() antlr.TerminalNode {
+ return s.GetToken(CypherParserSTICK, 0)
+}
+
+func (s *ListComprehensionContext) Expression() IExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IExpressionContext)
+}
+
+func (s *ListComprehensionContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *ListComprehensionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *ListComprehensionContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterListComprehension(s)
+ }
+}
+
+func (s *ListComprehensionContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitListComprehension(s)
+ }
+}
+
+func (p *CypherParser) ListComprehension() (localctx IListComprehensionContext) {
+ localctx = NewListComprehensionContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 158, CypherParserRULE_listComprehension)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(970)
+ p.Match(CypherParserLBRACK)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(971)
+ p.FilterExpression()
+ }
+ p.SetState(974)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserSTICK {
+ {
+ p.SetState(972)
+ p.Match(CypherParserSTICK)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(973)
+ p.Expression()
+ }
+
+ }
+ {
+ p.SetState(976)
+ p.Match(CypherParserRBRACK)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IFilterExpressionContext is an interface to support dynamic dispatch.
+type IFilterExpressionContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ Symbol() ISymbolContext
+ IN() antlr.TerminalNode
+ Expression() IExpressionContext
+ Where() IWhereContext
+
+ // IsFilterExpressionContext differentiates from other interfaces.
+ IsFilterExpressionContext()
+}
+
+type FilterExpressionContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyFilterExpressionContext() *FilterExpressionContext {
+ var p = new(FilterExpressionContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_filterExpression
+ return p
+}
+
+func InitEmptyFilterExpressionContext(p *FilterExpressionContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_filterExpression
+}
+
+func (*FilterExpressionContext) IsFilterExpressionContext() {}
+
+func NewFilterExpressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *FilterExpressionContext {
+ var p = new(FilterExpressionContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_filterExpression
+
+ return p
+}
+
+func (s *FilterExpressionContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *FilterExpressionContext) Symbol() ISymbolContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ISymbolContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ISymbolContext)
+}
+
+func (s *FilterExpressionContext) IN() antlr.TerminalNode {
+ return s.GetToken(CypherParserIN, 0)
+}
+
+func (s *FilterExpressionContext) Expression() IExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IExpressionContext)
+}
+
+func (s *FilterExpressionContext) Where() IWhereContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IWhereContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IWhereContext)
+}
+
+func (s *FilterExpressionContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *FilterExpressionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *FilterExpressionContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterFilterExpression(s)
+ }
+}
+
+func (s *FilterExpressionContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitFilterExpression(s)
+ }
+}
+
+func (p *CypherParser) FilterExpression() (localctx IFilterExpressionContext) {
+ localctx = NewFilterExpressionContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 160, CypherParserRULE_filterExpression)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(978)
+ p.Symbol()
+ }
+ {
+ p.SetState(979)
+ p.Match(CypherParserIN)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(980)
+ p.Expression()
+ }
+ p.SetState(982)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserWHERE {
+ {
+ p.SetState(981)
+ p.Where()
+ }
+
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// ICountAllContext is an interface to support dynamic dispatch.
+type ICountAllContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ COUNT() antlr.TerminalNode
+ LPAREN() antlr.TerminalNode
+ MULT() antlr.TerminalNode
+ RPAREN() antlr.TerminalNode
+
+ // IsCountAllContext differentiates from other interfaces.
+ IsCountAllContext()
+}
+
+type CountAllContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyCountAllContext() *CountAllContext {
+ var p = new(CountAllContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_countAll
+ return p
+}
+
+func InitEmptyCountAllContext(p *CountAllContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_countAll
+}
+
+func (*CountAllContext) IsCountAllContext() {}
+
+func NewCountAllContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *CountAllContext {
+ var p = new(CountAllContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_countAll
+
+ return p
+}
+
+func (s *CountAllContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *CountAllContext) COUNT() antlr.TerminalNode {
+ return s.GetToken(CypherParserCOUNT, 0)
+}
+
+func (s *CountAllContext) LPAREN() antlr.TerminalNode {
+ return s.GetToken(CypherParserLPAREN, 0)
+}
+
+func (s *CountAllContext) MULT() antlr.TerminalNode {
+ return s.GetToken(CypherParserMULT, 0)
+}
+
+func (s *CountAllContext) RPAREN() antlr.TerminalNode {
+ return s.GetToken(CypherParserRPAREN, 0)
+}
+
+func (s *CountAllContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *CountAllContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *CountAllContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterCountAll(s)
+ }
+}
+
+func (s *CountAllContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitCountAll(s)
+ }
+}
+
+func (p *CypherParser) CountAll() (localctx ICountAllContext) {
+ localctx = NewCountAllContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 162, CypherParserRULE_countAll)
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(984)
+ p.Match(CypherParserCOUNT)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(985)
+ p.Match(CypherParserLPAREN)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(986)
+ p.Match(CypherParserMULT)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(987)
+ p.Match(CypherParserRPAREN)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IExpressionChainContext is an interface to support dynamic dispatch.
+type IExpressionChainContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ AllExpression() []IExpressionContext
+ Expression(i int) IExpressionContext
+ AllCOMMA() []antlr.TerminalNode
+ COMMA(i int) antlr.TerminalNode
+
+ // IsExpressionChainContext differentiates from other interfaces.
+ IsExpressionChainContext()
+}
+
+type ExpressionChainContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyExpressionChainContext() *ExpressionChainContext {
+ var p = new(ExpressionChainContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_expressionChain
+ return p
+}
+
+func InitEmptyExpressionChainContext(p *ExpressionChainContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_expressionChain
+}
+
+func (*ExpressionChainContext) IsExpressionChainContext() {}
+
+func NewExpressionChainContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ExpressionChainContext {
+ var p = new(ExpressionChainContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_expressionChain
+
+ return p
+}
+
+func (s *ExpressionChainContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *ExpressionChainContext) AllExpression() []IExpressionContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IExpressionContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IExpressionContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IExpressionContext); ok {
+ tst[i] = t.(IExpressionContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *ExpressionChainContext) Expression(i int) IExpressionContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IExpressionContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IExpressionContext)
+}
+
+func (s *ExpressionChainContext) AllCOMMA() []antlr.TerminalNode {
+ return s.GetTokens(CypherParserCOMMA)
+}
+
+func (s *ExpressionChainContext) COMMA(i int) antlr.TerminalNode {
+ return s.GetToken(CypherParserCOMMA, i)
+}
+
+func (s *ExpressionChainContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *ExpressionChainContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *ExpressionChainContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterExpressionChain(s)
+ }
+}
+
+func (s *ExpressionChainContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitExpressionChain(s)
+ }
+}
+
+func (p *CypherParser) ExpressionChain() (localctx IExpressionChainContext) {
+ localctx = NewExpressionChainContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 164, CypherParserRULE_expressionChain)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(989)
+ p.Expression()
+ }
+ p.SetState(994)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for _la == CypherParserCOMMA {
+ {
+ p.SetState(990)
+ p.Match(CypherParserCOMMA)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(991)
+ p.Expression()
+ }
+
+ p.SetState(996)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// ICaseExpressionContext is an interface to support dynamic dispatch.
+type ICaseExpressionContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ CASE() antlr.TerminalNode
+ END() antlr.TerminalNode
+ AllExpression() []IExpressionContext
+ Expression(i int) IExpressionContext
+ AllWHEN() []antlr.TerminalNode
+ WHEN(i int) antlr.TerminalNode
+ AllTHEN() []antlr.TerminalNode
+ THEN(i int) antlr.TerminalNode
+ ELSE() antlr.TerminalNode
+
+ // IsCaseExpressionContext differentiates from other interfaces.
+ IsCaseExpressionContext()
+}
+
+type CaseExpressionContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyCaseExpressionContext() *CaseExpressionContext {
+ var p = new(CaseExpressionContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_caseExpression
+ return p
+}
+
+func InitEmptyCaseExpressionContext(p *CaseExpressionContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_caseExpression
+}
+
+func (*CaseExpressionContext) IsCaseExpressionContext() {}
+
+func NewCaseExpressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *CaseExpressionContext {
+ var p = new(CaseExpressionContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_caseExpression
+
+ return p
+}
+
+func (s *CaseExpressionContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *CaseExpressionContext) CASE() antlr.TerminalNode {
+ return s.GetToken(CypherParserCASE, 0)
+}
+
+func (s *CaseExpressionContext) END() antlr.TerminalNode {
+ return s.GetToken(CypherParserEND, 0)
+}
+
+func (s *CaseExpressionContext) AllExpression() []IExpressionContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IExpressionContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IExpressionContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IExpressionContext); ok {
+ tst[i] = t.(IExpressionContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *CaseExpressionContext) Expression(i int) IExpressionContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IExpressionContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IExpressionContext)
+}
+
+func (s *CaseExpressionContext) AllWHEN() []antlr.TerminalNode {
+ return s.GetTokens(CypherParserWHEN)
+}
+
+func (s *CaseExpressionContext) WHEN(i int) antlr.TerminalNode {
+ return s.GetToken(CypherParserWHEN, i)
+}
+
+func (s *CaseExpressionContext) AllTHEN() []antlr.TerminalNode {
+ return s.GetTokens(CypherParserTHEN)
+}
+
+func (s *CaseExpressionContext) THEN(i int) antlr.TerminalNode {
+ return s.GetToken(CypherParserTHEN, i)
+}
+
+func (s *CaseExpressionContext) ELSE() antlr.TerminalNode {
+ return s.GetToken(CypherParserELSE, 0)
+}
+
+func (s *CaseExpressionContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *CaseExpressionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *CaseExpressionContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterCaseExpression(s)
+ }
+}
+
+func (s *CaseExpressionContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitCaseExpression(s)
+ }
+}
+
+func (p *CypherParser) CaseExpression() (localctx ICaseExpressionContext) {
+ localctx = NewCaseExpressionContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 166, CypherParserRULE_caseExpression)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(997)
+ p.Match(CypherParserCASE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(999)
+ p.GetErrorHandler().Sync(p)
+
+ if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 138, p.GetParserRuleContext()) == 1 {
+ {
+ p.SetState(998)
+ p.Expression()
+ }
+
+ } else if p.HasError() { // JIM
+ goto errorExit
+ }
+ p.SetState(1006)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for ok := true; ok; ok = _la == CypherParserWHEN {
+ {
+ p.SetState(1001)
+ p.Match(CypherParserWHEN)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(1002)
+ p.Expression()
+ }
+ {
+ p.SetState(1003)
+ p.Match(CypherParserTHEN)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(1004)
+ p.Expression()
+ }
+
+ p.SetState(1008)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+ p.SetState(1012)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserELSE {
+ {
+ p.SetState(1010)
+ p.Match(CypherParserELSE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(1011)
+ p.Expression()
+ }
+
+ }
+ {
+ p.SetState(1014)
+ p.Match(CypherParserEND)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IParameterContext is an interface to support dynamic dispatch.
+type IParameterContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ DOLLAR() antlr.TerminalNode
+ Symbol() ISymbolContext
+ NumLit() INumLitContext
+
+ // IsParameterContext differentiates from other interfaces.
+ IsParameterContext()
+}
+
+type ParameterContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyParameterContext() *ParameterContext {
+ var p = new(ParameterContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_parameter
+ return p
+}
+
+func InitEmptyParameterContext(p *ParameterContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_parameter
+}
+
+func (*ParameterContext) IsParameterContext() {}
+
+func NewParameterContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ParameterContext {
+ var p = new(ParameterContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_parameter
+
+ return p
+}
+
+func (s *ParameterContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *ParameterContext) DOLLAR() antlr.TerminalNode {
+ return s.GetToken(CypherParserDOLLAR, 0)
+}
+
+func (s *ParameterContext) Symbol() ISymbolContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ISymbolContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ISymbolContext)
+}
+
+func (s *ParameterContext) NumLit() INumLitContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(INumLitContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(INumLitContext)
+}
+
+func (s *ParameterContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *ParameterContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *ParameterContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterParameter(s)
+ }
+}
+
+func (s *ParameterContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitParameter(s)
+ }
+}
+
+func (p *CypherParser) Parameter() (localctx IParameterContext) {
+ localctx = NewParameterContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 168, CypherParserRULE_parameter)
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(1016)
+ p.Match(CypherParserDOLLAR)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(1019)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetTokenStream().LA(1) {
+ case CypherParserFILTER, CypherParserEXTRACT, CypherParserCOUNT, CypherParserSUM, CypherParserAVG, CypherParserMIN, CypherParserMAX, CypherParserCOLLECT, CypherParserANY, CypherParserNONE, CypherParserSINGLE, CypherParserALL, CypherParserCREATE, CypherParserDELETE, CypherParserEXISTS, CypherParserMATCH, CypherParserMERGE, CypherParserREMOVE, CypherParserSET, CypherParserFALSE, CypherParserTRUE, CypherParserNULL_W, CypherParserCONSTRAINT, CypherParserREQUIRE, CypherParserUNIQUE, CypherParserCASE, CypherParserWHEN, CypherParserTHEN, CypherParserELSE, CypherParserEND, CypherParserADD, CypherParserDROP, CypherParserINDEX, CypherParserINDEXES, CypherParserVECTOR, CypherParserSHOW, CypherParserCONSTRAINTS, CypherParserPROCEDURES, CypherParserFUNCTIONS, CypherParserDATABASE, CypherParserFULLTEXT, CypherParserOPTIONS, CypherParserEACH, CypherParserIF, CypherParserTRANSACTIONS, CypherParserROWS, CypherParserASSERT, CypherParserKEY, CypherParserNODE, CypherParserSHORTESTPATH, CypherParserALLSHORTESTPATHS, CypherParserID, CypherParserESC_LITERAL:
+ {
+ p.SetState(1017)
+ p.Symbol()
+ }
+
+ case CypherParserFLOAT, CypherParserINTEGER, CypherParserDIGIT:
+ {
+ p.SetState(1018)
+ p.NumLit()
+ }
+
+ default:
+ p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil))
+ goto errorExit
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// ILiteralContext is an interface to support dynamic dispatch.
+type ILiteralContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ BoolLit() IBoolLitContext
+ NumLit() INumLitContext
+ NULL_W() antlr.TerminalNode
+ StringLit() IStringLitContext
+ CharLit() ICharLitContext
+ ListLit() IListLitContext
+ MapLit() IMapLitContext
+
+ // IsLiteralContext differentiates from other interfaces.
+ IsLiteralContext()
+}
+
+type LiteralContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyLiteralContext() *LiteralContext {
+ var p = new(LiteralContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_literal
+ return p
+}
+
+func InitEmptyLiteralContext(p *LiteralContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_literal
+}
+
+func (*LiteralContext) IsLiteralContext() {}
+
+func NewLiteralContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *LiteralContext {
+ var p = new(LiteralContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_literal
+
+ return p
+}
+
+func (s *LiteralContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *LiteralContext) BoolLit() IBoolLitContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IBoolLitContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IBoolLitContext)
+}
+
+func (s *LiteralContext) NumLit() INumLitContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(INumLitContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(INumLitContext)
+}
+
+func (s *LiteralContext) NULL_W() antlr.TerminalNode {
+ return s.GetToken(CypherParserNULL_W, 0)
+}
+
+func (s *LiteralContext) StringLit() IStringLitContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IStringLitContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IStringLitContext)
+}
+
+func (s *LiteralContext) CharLit() ICharLitContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ICharLitContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ICharLitContext)
+}
+
+func (s *LiteralContext) ListLit() IListLitContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IListLitContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IListLitContext)
+}
+
+func (s *LiteralContext) MapLit() IMapLitContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IMapLitContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IMapLitContext)
+}
+
+func (s *LiteralContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *LiteralContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *LiteralContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterLiteral(s)
+ }
+}
+
+func (s *LiteralContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitLiteral(s)
+ }
+}
+
+func (p *CypherParser) Literal() (localctx ILiteralContext) {
+ localctx = NewLiteralContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 170, CypherParserRULE_literal)
+ p.SetState(1028)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetTokenStream().LA(1) {
+ case CypherParserFALSE, CypherParserTRUE:
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(1021)
+ p.BoolLit()
+ }
+
+ case CypherParserFLOAT, CypherParserINTEGER, CypherParserDIGIT:
+ p.EnterOuterAlt(localctx, 2)
+ {
+ p.SetState(1022)
+ p.NumLit()
+ }
+
+ case CypherParserNULL_W:
+ p.EnterOuterAlt(localctx, 3)
+ {
+ p.SetState(1023)
+ p.Match(CypherParserNULL_W)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ case CypherParserSTRING_LITERAL:
+ p.EnterOuterAlt(localctx, 4)
+ {
+ p.SetState(1024)
+ p.StringLit()
+ }
+
+ case CypherParserCHAR_LITERAL:
+ p.EnterOuterAlt(localctx, 5)
+ {
+ p.SetState(1025)
+ p.CharLit()
+ }
+
+ case CypherParserLBRACK:
+ p.EnterOuterAlt(localctx, 6)
+ {
+ p.SetState(1026)
+ p.ListLit()
+ }
+
+ case CypherParserLBRACE:
+ p.EnterOuterAlt(localctx, 7)
+ {
+ p.SetState(1027)
+ p.MapLit()
+ }
+
+ default:
+ p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil))
+ goto errorExit
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IRangeLitContext is an interface to support dynamic dispatch.
+type IRangeLitContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ MULT() antlr.TerminalNode
+ AllIntegerLit() []IIntegerLitContext
+ IntegerLit(i int) IIntegerLitContext
+ RANGE() antlr.TerminalNode
+
+ // IsRangeLitContext differentiates from other interfaces.
+ IsRangeLitContext()
+}
+
+type RangeLitContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyRangeLitContext() *RangeLitContext {
+ var p = new(RangeLitContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_rangeLit
+ return p
+}
+
+func InitEmptyRangeLitContext(p *RangeLitContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_rangeLit
+}
+
+func (*RangeLitContext) IsRangeLitContext() {}
+
+func NewRangeLitContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *RangeLitContext {
+ var p = new(RangeLitContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_rangeLit
+
+ return p
+}
+
+func (s *RangeLitContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *RangeLitContext) MULT() antlr.TerminalNode {
+ return s.GetToken(CypherParserMULT, 0)
+}
+
+func (s *RangeLitContext) AllIntegerLit() []IIntegerLitContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IIntegerLitContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IIntegerLitContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IIntegerLitContext); ok {
+ tst[i] = t.(IIntegerLitContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *RangeLitContext) IntegerLit(i int) IIntegerLitContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IIntegerLitContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IIntegerLitContext)
+}
+
+func (s *RangeLitContext) RANGE() antlr.TerminalNode {
+ return s.GetToken(CypherParserRANGE, 0)
+}
+
+func (s *RangeLitContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *RangeLitContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *RangeLitContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterRangeLit(s)
+ }
+}
+
+func (s *RangeLitContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitRangeLit(s)
+ }
+}
+
+func (p *CypherParser) RangeLit() (localctx IRangeLitContext) {
+ localctx = NewRangeLitContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 172, CypherParserRULE_rangeLit)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(1030)
+ p.Match(CypherParserMULT)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(1032)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserINTEGER || _la == CypherParserDIGIT {
+ {
+ p.SetState(1031)
+ p.IntegerLit()
+ }
+
+ }
+ p.SetState(1038)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserRANGE {
+ {
+ p.SetState(1034)
+ p.Match(CypherParserRANGE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(1036)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == CypherParserINTEGER || _la == CypherParserDIGIT {
+ {
+ p.SetState(1035)
+ p.IntegerLit()
+ }
+
+ }
+
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IBoolLitContext is an interface to support dynamic dispatch.
+type IBoolLitContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ TRUE() antlr.TerminalNode
+ FALSE() antlr.TerminalNode
+
+ // IsBoolLitContext differentiates from other interfaces.
+ IsBoolLitContext()
+}
+
+type BoolLitContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyBoolLitContext() *BoolLitContext {
+ var p = new(BoolLitContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_boolLit
+ return p
+}
+
+func InitEmptyBoolLitContext(p *BoolLitContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_boolLit
+}
+
+func (*BoolLitContext) IsBoolLitContext() {}
+
+func NewBoolLitContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *BoolLitContext {
+ var p = new(BoolLitContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_boolLit
+
+ return p
+}
+
+func (s *BoolLitContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *BoolLitContext) TRUE() antlr.TerminalNode {
+ return s.GetToken(CypherParserTRUE, 0)
+}
+
+func (s *BoolLitContext) FALSE() antlr.TerminalNode {
+ return s.GetToken(CypherParserFALSE, 0)
+}
+
+func (s *BoolLitContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *BoolLitContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *BoolLitContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterBoolLit(s)
+ }
+}
+
+func (s *BoolLitContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitBoolLit(s)
+ }
+}
+
+func (p *CypherParser) BoolLit() (localctx IBoolLitContext) {
+ localctx = NewBoolLitContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 174, CypherParserRULE_boolLit)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(1040)
+ _la = p.GetTokenStream().LA(1)
+
+ if !(_la == CypherParserFALSE || _la == CypherParserTRUE) {
+ p.GetErrorHandler().RecoverInline(p)
+ } else {
+ p.GetErrorHandler().ReportMatch(p)
+ p.Consume()
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IIntegerLitContext is an interface to support dynamic dispatch.
+type IIntegerLitContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ INTEGER() antlr.TerminalNode
+ DIGIT() antlr.TerminalNode
+
+ // IsIntegerLitContext differentiates from other interfaces.
+ IsIntegerLitContext()
+}
+
+type IntegerLitContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyIntegerLitContext() *IntegerLitContext {
+ var p = new(IntegerLitContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_integerLit
+ return p
+}
+
+func InitEmptyIntegerLitContext(p *IntegerLitContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_integerLit
+}
+
+func (*IntegerLitContext) IsIntegerLitContext() {}
+
+func NewIntegerLitContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *IntegerLitContext {
+ var p = new(IntegerLitContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_integerLit
+
+ return p
+}
+
+func (s *IntegerLitContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *IntegerLitContext) INTEGER() antlr.TerminalNode {
+ return s.GetToken(CypherParserINTEGER, 0)
+}
+
+func (s *IntegerLitContext) DIGIT() antlr.TerminalNode {
+ return s.GetToken(CypherParserDIGIT, 0)
+}
+
+func (s *IntegerLitContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *IntegerLitContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *IntegerLitContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterIntegerLit(s)
+ }
+}
+
+func (s *IntegerLitContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitIntegerLit(s)
+ }
+}
+
+func (p *CypherParser) IntegerLit() (localctx IIntegerLitContext) {
+ localctx = NewIntegerLitContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 176, CypherParserRULE_integerLit)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(1042)
+ _la = p.GetTokenStream().LA(1)
+
+ if !(_la == CypherParserINTEGER || _la == CypherParserDIGIT) {
+ p.GetErrorHandler().RecoverInline(p)
+ } else {
+ p.GetErrorHandler().ReportMatch(p)
+ p.Consume()
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// INumLitContext is an interface to support dynamic dispatch.
+type INumLitContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ FLOAT() antlr.TerminalNode
+ IntegerLit() IIntegerLitContext
+
+ // IsNumLitContext differentiates from other interfaces.
+ IsNumLitContext()
+}
+
+type NumLitContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyNumLitContext() *NumLitContext {
+ var p = new(NumLitContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_numLit
+ return p
+}
+
+func InitEmptyNumLitContext(p *NumLitContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_numLit
+}
+
+func (*NumLitContext) IsNumLitContext() {}
+
+func NewNumLitContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *NumLitContext {
+ var p = new(NumLitContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_numLit
+
+ return p
+}
+
+func (s *NumLitContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *NumLitContext) FLOAT() antlr.TerminalNode {
+ return s.GetToken(CypherParserFLOAT, 0)
+}
+
+func (s *NumLitContext) IntegerLit() IIntegerLitContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IIntegerLitContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IIntegerLitContext)
+}
+
+func (s *NumLitContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *NumLitContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *NumLitContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterNumLit(s)
+ }
+}
+
+func (s *NumLitContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitNumLit(s)
+ }
+}
+
+func (p *CypherParser) NumLit() (localctx INumLitContext) {
+ localctx = NewNumLitContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 178, CypherParserRULE_numLit)
+ p.SetState(1046)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetTokenStream().LA(1) {
+ case CypherParserFLOAT:
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(1044)
+ p.Match(CypherParserFLOAT)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ case CypherParserINTEGER, CypherParserDIGIT:
+ p.EnterOuterAlt(localctx, 2)
+ {
+ p.SetState(1045)
+ p.IntegerLit()
+ }
+
+ default:
+ p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil))
+ goto errorExit
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IStringLitContext is an interface to support dynamic dispatch.
+type IStringLitContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ STRING_LITERAL() antlr.TerminalNode
+
+ // IsStringLitContext differentiates from other interfaces.
+ IsStringLitContext()
+}
+
+type StringLitContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyStringLitContext() *StringLitContext {
+ var p = new(StringLitContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_stringLit
+ return p
+}
+
+func InitEmptyStringLitContext(p *StringLitContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_stringLit
+}
+
+func (*StringLitContext) IsStringLitContext() {}
+
+func NewStringLitContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *StringLitContext {
+ var p = new(StringLitContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_stringLit
+
+ return p
+}
+
+func (s *StringLitContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *StringLitContext) STRING_LITERAL() antlr.TerminalNode {
+ return s.GetToken(CypherParserSTRING_LITERAL, 0)
+}
+
+func (s *StringLitContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *StringLitContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *StringLitContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterStringLit(s)
+ }
+}
+
+func (s *StringLitContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitStringLit(s)
+ }
+}
+
+func (p *CypherParser) StringLit() (localctx IStringLitContext) {
+ localctx = NewStringLitContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 180, CypherParserRULE_stringLit)
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(1048)
+ p.Match(CypherParserSTRING_LITERAL)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// ICharLitContext is an interface to support dynamic dispatch.
+type ICharLitContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ CHAR_LITERAL() antlr.TerminalNode
+
+ // IsCharLitContext differentiates from other interfaces.
+ IsCharLitContext()
+}
+
+type CharLitContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyCharLitContext() *CharLitContext {
+ var p = new(CharLitContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_charLit
+ return p
+}
+
+func InitEmptyCharLitContext(p *CharLitContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_charLit
+}
+
+func (*CharLitContext) IsCharLitContext() {}
+
+func NewCharLitContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *CharLitContext {
+ var p = new(CharLitContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_charLit
+
+ return p
+}
+
+func (s *CharLitContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *CharLitContext) CHAR_LITERAL() antlr.TerminalNode {
+ return s.GetToken(CypherParserCHAR_LITERAL, 0)
+}
+
+func (s *CharLitContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *CharLitContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *CharLitContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterCharLit(s)
+ }
+}
+
+func (s *CharLitContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitCharLit(s)
+ }
+}
+
+func (p *CypherParser) CharLit() (localctx ICharLitContext) {
+ localctx = NewCharLitContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 182, CypherParserRULE_charLit)
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(1050)
+ p.Match(CypherParserCHAR_LITERAL)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IListLitContext is an interface to support dynamic dispatch.
+type IListLitContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ LBRACK() antlr.TerminalNode
+ RBRACK() antlr.TerminalNode
+ ExpressionChain() IExpressionChainContext
+
+ // IsListLitContext differentiates from other interfaces.
+ IsListLitContext()
+}
+
+type ListLitContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyListLitContext() *ListLitContext {
+ var p = new(ListLitContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_listLit
+ return p
+}
+
+func InitEmptyListLitContext(p *ListLitContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_listLit
+}
+
+func (*ListLitContext) IsListLitContext() {}
+
+func NewListLitContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ListLitContext {
+ var p = new(ListLitContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_listLit
+
+ return p
+}
+
+func (s *ListLitContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *ListLitContext) LBRACK() antlr.TerminalNode {
+ return s.GetToken(CypherParserLBRACK, 0)
+}
+
+func (s *ListLitContext) RBRACK() antlr.TerminalNode {
+ return s.GetToken(CypherParserRBRACK, 0)
+}
+
+func (s *ListLitContext) ExpressionChain() IExpressionChainContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IExpressionChainContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IExpressionChainContext)
+}
+
+func (s *ListLitContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *ListLitContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *ListLitContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterListLit(s)
+ }
+}
+
+func (s *ListLitContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitListLit(s)
+ }
+}
+
+func (p *CypherParser) ListLit() (localctx IListLitContext) {
+ localctx = NewListLitContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 184, CypherParserRULE_listLit)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(1052)
+ p.Match(CypherParserLBRACK)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(1054)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if ((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&1470645178784718848) != 0) || ((int64((_la-73)) & ^0x3f) == 0 && ((int64(1)<<(_la-73))&2251795417136369) != 0) {
+ {
+ p.SetState(1053)
+ p.ExpressionChain()
+ }
+
+ }
+ {
+ p.SetState(1056)
+ p.Match(CypherParserRBRACK)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IMapLitContext is an interface to support dynamic dispatch.
+type IMapLitContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ LBRACE() antlr.TerminalNode
+ RBRACE() antlr.TerminalNode
+ AllMapPair() []IMapPairContext
+ MapPair(i int) IMapPairContext
+ AllCOMMA() []antlr.TerminalNode
+ COMMA(i int) antlr.TerminalNode
+
+ // IsMapLitContext differentiates from other interfaces.
+ IsMapLitContext()
+}
+
+type MapLitContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyMapLitContext() *MapLitContext {
+ var p = new(MapLitContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_mapLit
+ return p
+}
+
+func InitEmptyMapLitContext(p *MapLitContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_mapLit
+}
+
+func (*MapLitContext) IsMapLitContext() {}
+
+func NewMapLitContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *MapLitContext {
+ var p = new(MapLitContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_mapLit
+
+ return p
+}
+
+func (s *MapLitContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *MapLitContext) LBRACE() antlr.TerminalNode {
+ return s.GetToken(CypherParserLBRACE, 0)
+}
+
+func (s *MapLitContext) RBRACE() antlr.TerminalNode {
+ return s.GetToken(CypherParserRBRACE, 0)
+}
+
+func (s *MapLitContext) AllMapPair() []IMapPairContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IMapPairContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IMapPairContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IMapPairContext); ok {
+ tst[i] = t.(IMapPairContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *MapLitContext) MapPair(i int) IMapPairContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IMapPairContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IMapPairContext)
+}
+
+func (s *MapLitContext) AllCOMMA() []antlr.TerminalNode {
+ return s.GetTokens(CypherParserCOMMA)
+}
+
+func (s *MapLitContext) COMMA(i int) antlr.TerminalNode {
+ return s.GetToken(CypherParserCOMMA, i)
+}
+
+func (s *MapLitContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *MapLitContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *MapLitContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterMapLit(s)
+ }
+}
+
+func (s *MapLitContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitMapLit(s)
+ }
+}
+
+func (p *CypherParser) MapLit() (localctx IMapLitContext) {
+ localctx = NewMapLitContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 186, CypherParserRULE_mapLit)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(1058)
+ p.Match(CypherParserLBRACE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(1067)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if ((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&-2147483648) != 0) || ((int64((_la-64)) & ^0x3f) == 0 && ((int64(1)<<(_la-64))&225177730805661695) != 0) {
+ {
+ p.SetState(1059)
+ p.MapPair()
+ }
+ p.SetState(1064)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for _la == CypherParserCOMMA {
+ {
+ p.SetState(1060)
+ p.Match(CypherParserCOMMA)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(1061)
+ p.MapPair()
+ }
+
+ p.SetState(1066)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+
+ }
+ {
+ p.SetState(1069)
+ p.Match(CypherParserRBRACE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IMapPairContext is an interface to support dynamic dispatch.
+type IMapPairContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ Name() INameContext
+ COLON() antlr.TerminalNode
+ Expression() IExpressionContext
+
+ // IsMapPairContext differentiates from other interfaces.
+ IsMapPairContext()
+}
+
+type MapPairContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyMapPairContext() *MapPairContext {
+ var p = new(MapPairContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_mapPair
+ return p
+}
+
+func InitEmptyMapPairContext(p *MapPairContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_mapPair
+}
+
+func (*MapPairContext) IsMapPairContext() {}
+
+func NewMapPairContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *MapPairContext {
+ var p = new(MapPairContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_mapPair
+
+ return p
+}
+
+func (s *MapPairContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *MapPairContext) Name() INameContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(INameContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(INameContext)
+}
+
+func (s *MapPairContext) COLON() antlr.TerminalNode {
+ return s.GetToken(CypherParserCOLON, 0)
+}
+
+func (s *MapPairContext) Expression() IExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IExpressionContext)
+}
+
+func (s *MapPairContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *MapPairContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *MapPairContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterMapPair(s)
+ }
+}
+
+func (s *MapPairContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitMapPair(s)
+ }
+}
+
+func (p *CypherParser) MapPair() (localctx IMapPairContext) {
+ localctx = NewMapPairContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 188, CypherParserRULE_mapPair)
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(1071)
+ p.Name()
+ }
+ {
+ p.SetState(1072)
+ p.Match(CypherParserCOLON)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(1073)
+ p.Expression()
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// INameContext is an interface to support dynamic dispatch.
+type INameContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ Symbol() ISymbolContext
+ ReservedWord() IReservedWordContext
+
+ // IsNameContext differentiates from other interfaces.
+ IsNameContext()
+}
+
+type NameContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyNameContext() *NameContext {
+ var p = new(NameContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_name
+ return p
+}
+
+func InitEmptyNameContext(p *NameContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_name
+}
+
+func (*NameContext) IsNameContext() {}
+
+func NewNameContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *NameContext {
+ var p = new(NameContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_name
+
+ return p
+}
+
+func (s *NameContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *NameContext) Symbol() ISymbolContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ISymbolContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ISymbolContext)
+}
+
+func (s *NameContext) ReservedWord() IReservedWordContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IReservedWordContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IReservedWordContext)
+}
+
+func (s *NameContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *NameContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *NameContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterName(s)
+ }
+}
+
+func (s *NameContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitName(s)
+ }
+}
+
+func (p *CypherParser) Name() (localctx INameContext) {
+ localctx = NewNameContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 190, CypherParserRULE_name)
+ p.SetState(1077)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 150, p.GetParserRuleContext()) {
+ case 1:
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(1075)
+ p.Symbol()
+ }
+
+ case 2:
+ p.EnterOuterAlt(localctx, 2)
+ {
+ p.SetState(1076)
+ p.ReservedWord()
+ }
+
+ case antlr.ATNInvalidAltNumber:
+ goto errorExit
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// ISymbolContext is an interface to support dynamic dispatch.
+type ISymbolContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ ESC_LITERAL() antlr.TerminalNode
+ ID() antlr.TerminalNode
+ COUNT() antlr.TerminalNode
+ SUM() antlr.TerminalNode
+ AVG() antlr.TerminalNode
+ MIN() antlr.TerminalNode
+ MAX() antlr.TerminalNode
+ COLLECT() antlr.TerminalNode
+ FILTER() antlr.TerminalNode
+ EXTRACT() antlr.TerminalNode
+ ANY() antlr.TerminalNode
+ NONE() antlr.TerminalNode
+ SINGLE() antlr.TerminalNode
+ INDEX() antlr.TerminalNode
+ INDEXES() antlr.TerminalNode
+ CONSTRAINT() antlr.TerminalNode
+ CONSTRAINTS() antlr.TerminalNode
+ DROP() antlr.TerminalNode
+ CREATE() antlr.TerminalNode
+ VECTOR() antlr.TerminalNode
+ DELETE() antlr.TerminalNode
+ ADD() antlr.TerminalNode
+ REMOVE() antlr.TerminalNode
+ SET() antlr.TerminalNode
+ MATCH() antlr.TerminalNode
+ MERGE() antlr.TerminalNode
+ FULLTEXT() antlr.TerminalNode
+ PROCEDURES() antlr.TerminalNode
+ FUNCTIONS() antlr.TerminalNode
+ DATABASE() antlr.TerminalNode
+ EXISTS() antlr.TerminalNode
+ SHOW() antlr.TerminalNode
+ OPTIONS() antlr.TerminalNode
+ NODE() antlr.TerminalNode
+ KEY() antlr.TerminalNode
+ ASSERT() antlr.TerminalNode
+ ROWS() antlr.TerminalNode
+ TRANSACTIONS() antlr.TerminalNode
+ END() antlr.TerminalNode
+ CASE() antlr.TerminalNode
+ WHEN() antlr.TerminalNode
+ THEN() antlr.TerminalNode
+ ELSE() antlr.TerminalNode
+ TRUE() antlr.TerminalNode
+ FALSE() antlr.TerminalNode
+ NULL_W() antlr.TerminalNode
+ UNIQUE() antlr.TerminalNode
+ REQUIRE() antlr.TerminalNode
+ IF() antlr.TerminalNode
+ EACH() antlr.TerminalNode
+ ALL() antlr.TerminalNode
+ SHORTESTPATH() antlr.TerminalNode
+ ALLSHORTESTPATHS() antlr.TerminalNode
+
+ // IsSymbolContext differentiates from other interfaces.
+ IsSymbolContext()
+}
+
+type SymbolContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptySymbolContext() *SymbolContext {
+ var p = new(SymbolContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_symbol
+ return p
+}
+
+func InitEmptySymbolContext(p *SymbolContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_symbol
+}
+
+func (*SymbolContext) IsSymbolContext() {}
+
+func NewSymbolContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *SymbolContext {
+ var p = new(SymbolContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_symbol
+
+ return p
+}
+
+func (s *SymbolContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *SymbolContext) ESC_LITERAL() antlr.TerminalNode {
+ return s.GetToken(CypherParserESC_LITERAL, 0)
+}
+
+func (s *SymbolContext) ID() antlr.TerminalNode {
+ return s.GetToken(CypherParserID, 0)
+}
+
+func (s *SymbolContext) COUNT() antlr.TerminalNode {
+ return s.GetToken(CypherParserCOUNT, 0)
+}
+
+func (s *SymbolContext) SUM() antlr.TerminalNode {
+ return s.GetToken(CypherParserSUM, 0)
+}
+
+func (s *SymbolContext) AVG() antlr.TerminalNode {
+ return s.GetToken(CypherParserAVG, 0)
+}
+
+func (s *SymbolContext) MIN() antlr.TerminalNode {
+ return s.GetToken(CypherParserMIN, 0)
+}
+
+func (s *SymbolContext) MAX() antlr.TerminalNode {
+ return s.GetToken(CypherParserMAX, 0)
+}
+
+func (s *SymbolContext) COLLECT() antlr.TerminalNode {
+ return s.GetToken(CypherParserCOLLECT, 0)
+}
+
+func (s *SymbolContext) FILTER() antlr.TerminalNode {
+ return s.GetToken(CypherParserFILTER, 0)
+}
+
+func (s *SymbolContext) EXTRACT() antlr.TerminalNode {
+ return s.GetToken(CypherParserEXTRACT, 0)
+}
+
+func (s *SymbolContext) ANY() antlr.TerminalNode {
+ return s.GetToken(CypherParserANY, 0)
+}
+
+func (s *SymbolContext) NONE() antlr.TerminalNode {
+ return s.GetToken(CypherParserNONE, 0)
+}
+
+func (s *SymbolContext) SINGLE() antlr.TerminalNode {
+ return s.GetToken(CypherParserSINGLE, 0)
+}
+
+func (s *SymbolContext) INDEX() antlr.TerminalNode {
+ return s.GetToken(CypherParserINDEX, 0)
+}
+
+func (s *SymbolContext) INDEXES() antlr.TerminalNode {
+ return s.GetToken(CypherParserINDEXES, 0)
+}
+
+func (s *SymbolContext) CONSTRAINT() antlr.TerminalNode {
+ return s.GetToken(CypherParserCONSTRAINT, 0)
+}
+
+func (s *SymbolContext) CONSTRAINTS() antlr.TerminalNode {
+ return s.GetToken(CypherParserCONSTRAINTS, 0)
+}
+
+func (s *SymbolContext) DROP() antlr.TerminalNode {
+ return s.GetToken(CypherParserDROP, 0)
+}
+
+func (s *SymbolContext) CREATE() antlr.TerminalNode {
+ return s.GetToken(CypherParserCREATE, 0)
+}
+
+func (s *SymbolContext) VECTOR() antlr.TerminalNode {
+ return s.GetToken(CypherParserVECTOR, 0)
+}
+
+func (s *SymbolContext) DELETE() antlr.TerminalNode {
+ return s.GetToken(CypherParserDELETE, 0)
+}
+
+func (s *SymbolContext) ADD() antlr.TerminalNode {
+ return s.GetToken(CypherParserADD, 0)
+}
+
+func (s *SymbolContext) REMOVE() antlr.TerminalNode {
+ return s.GetToken(CypherParserREMOVE, 0)
+}
+
+func (s *SymbolContext) SET() antlr.TerminalNode {
+ return s.GetToken(CypherParserSET, 0)
+}
+
+func (s *SymbolContext) MATCH() antlr.TerminalNode {
+ return s.GetToken(CypherParserMATCH, 0)
+}
+
+func (s *SymbolContext) MERGE() antlr.TerminalNode {
+ return s.GetToken(CypherParserMERGE, 0)
+}
+
+func (s *SymbolContext) FULLTEXT() antlr.TerminalNode {
+ return s.GetToken(CypherParserFULLTEXT, 0)
+}
+
+func (s *SymbolContext) PROCEDURES() antlr.TerminalNode {
+ return s.GetToken(CypherParserPROCEDURES, 0)
+}
+
+func (s *SymbolContext) FUNCTIONS() antlr.TerminalNode {
+ return s.GetToken(CypherParserFUNCTIONS, 0)
+}
+
+func (s *SymbolContext) DATABASE() antlr.TerminalNode {
+ return s.GetToken(CypherParserDATABASE, 0)
+}
+
+func (s *SymbolContext) EXISTS() antlr.TerminalNode {
+ return s.GetToken(CypherParserEXISTS, 0)
+}
+
+func (s *SymbolContext) SHOW() antlr.TerminalNode {
+ return s.GetToken(CypherParserSHOW, 0)
+}
+
+func (s *SymbolContext) OPTIONS() antlr.TerminalNode {
+ return s.GetToken(CypherParserOPTIONS, 0)
+}
+
+func (s *SymbolContext) NODE() antlr.TerminalNode {
+ return s.GetToken(CypherParserNODE, 0)
+}
+
+func (s *SymbolContext) KEY() antlr.TerminalNode {
+ return s.GetToken(CypherParserKEY, 0)
+}
+
+func (s *SymbolContext) ASSERT() antlr.TerminalNode {
+ return s.GetToken(CypherParserASSERT, 0)
+}
+
+func (s *SymbolContext) ROWS() antlr.TerminalNode {
+ return s.GetToken(CypherParserROWS, 0)
+}
+
+func (s *SymbolContext) TRANSACTIONS() antlr.TerminalNode {
+ return s.GetToken(CypherParserTRANSACTIONS, 0)
+}
+
+func (s *SymbolContext) END() antlr.TerminalNode {
+ return s.GetToken(CypherParserEND, 0)
+}
+
+func (s *SymbolContext) CASE() antlr.TerminalNode {
+ return s.GetToken(CypherParserCASE, 0)
+}
+
+func (s *SymbolContext) WHEN() antlr.TerminalNode {
+ return s.GetToken(CypherParserWHEN, 0)
+}
+
+func (s *SymbolContext) THEN() antlr.TerminalNode {
+ return s.GetToken(CypherParserTHEN, 0)
+}
+
+func (s *SymbolContext) ELSE() antlr.TerminalNode {
+ return s.GetToken(CypherParserELSE, 0)
+}
+
+func (s *SymbolContext) TRUE() antlr.TerminalNode {
+ return s.GetToken(CypherParserTRUE, 0)
+}
+
+func (s *SymbolContext) FALSE() antlr.TerminalNode {
+ return s.GetToken(CypherParserFALSE, 0)
+}
+
+func (s *SymbolContext) NULL_W() antlr.TerminalNode {
+ return s.GetToken(CypherParserNULL_W, 0)
+}
+
+func (s *SymbolContext) UNIQUE() antlr.TerminalNode {
+ return s.GetToken(CypherParserUNIQUE, 0)
+}
+
+func (s *SymbolContext) REQUIRE() antlr.TerminalNode {
+ return s.GetToken(CypherParserREQUIRE, 0)
+}
+
+func (s *SymbolContext) IF() antlr.TerminalNode {
+ return s.GetToken(CypherParserIF, 0)
+}
+
+func (s *SymbolContext) EACH() antlr.TerminalNode {
+ return s.GetToken(CypherParserEACH, 0)
+}
+
+func (s *SymbolContext) ALL() antlr.TerminalNode {
+ return s.GetToken(CypherParserALL, 0)
+}
+
+func (s *SymbolContext) SHORTESTPATH() antlr.TerminalNode {
+ return s.GetToken(CypherParserSHORTESTPATH, 0)
+}
+
+func (s *SymbolContext) ALLSHORTESTPATHS() antlr.TerminalNode {
+ return s.GetToken(CypherParserALLSHORTESTPATHS, 0)
+}
+
+func (s *SymbolContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *SymbolContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *SymbolContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterSymbol(s)
+ }
+}
+
+func (s *SymbolContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitSymbol(s)
+ }
+}
+
+func (p *CypherParser) Symbol() (localctx ISymbolContext) {
+ localctx = NewSymbolContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 192, CypherParserRULE_symbol)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(1079)
+ _la = p.GetTokenStream().LA(1)
+
+ if !(((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&1470645178514538496) != 0) || ((int64((_la-77)) & ^0x3f) == 0 && ((int64(1)<<(_la-77))&27487515910095) != 0)) {
+ p.GetErrorHandler().RecoverInline(p)
+ } else {
+ p.GetErrorHandler().ReportMatch(p)
+ p.Consume()
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IReservedWordContext is an interface to support dynamic dispatch.
+type IReservedWordContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ ALL() antlr.TerminalNode
+ ASC() antlr.TerminalNode
+ ASCENDING() antlr.TerminalNode
+ BY() antlr.TerminalNode
+ CREATE() antlr.TerminalNode
+ DELETE() antlr.TerminalNode
+ DESC() antlr.TerminalNode
+ DESCENDING() antlr.TerminalNode
+ DETACH() antlr.TerminalNode
+ EXISTS() antlr.TerminalNode
+ LIMIT() antlr.TerminalNode
+ MATCH() antlr.TerminalNode
+ MERGE() antlr.TerminalNode
+ ON() antlr.TerminalNode
+ OPTIONAL() antlr.TerminalNode
+ ORDER() antlr.TerminalNode
+ REMOVE() antlr.TerminalNode
+ RETURN() antlr.TerminalNode
+ SET() antlr.TerminalNode
+ SKIP_W() antlr.TerminalNode
+ WHERE() antlr.TerminalNode
+ WITH() antlr.TerminalNode
+ UNION() antlr.TerminalNode
+ UNWIND() antlr.TerminalNode
+ AND() antlr.TerminalNode
+ AS() antlr.TerminalNode
+ CONTAINS() antlr.TerminalNode
+ DISTINCT() antlr.TerminalNode
+ ENDS() antlr.TerminalNode
+ IN() antlr.TerminalNode
+ IS() antlr.TerminalNode
+ NOT() antlr.TerminalNode
+ OR() antlr.TerminalNode
+ STARTS() antlr.TerminalNode
+ XOR() antlr.TerminalNode
+ FALSE() antlr.TerminalNode
+ TRUE() antlr.TerminalNode
+ NULL_W() antlr.TerminalNode
+ CONSTRAINT() antlr.TerminalNode
+ DO() antlr.TerminalNode
+ FOR() antlr.TerminalNode
+ REQUIRE() antlr.TerminalNode
+ UNIQUE() antlr.TerminalNode
+ CASE() antlr.TerminalNode
+ WHEN() antlr.TerminalNode
+ THEN() antlr.TerminalNode
+ ELSE() antlr.TerminalNode
+ END() antlr.TerminalNode
+ MANDATORY() antlr.TerminalNode
+ SCALAR() antlr.TerminalNode
+ OF() antlr.TerminalNode
+ ADD() antlr.TerminalNode
+ DROP() antlr.TerminalNode
+
+ // IsReservedWordContext differentiates from other interfaces.
+ IsReservedWordContext()
+}
+
+type ReservedWordContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyReservedWordContext() *ReservedWordContext {
+ var p = new(ReservedWordContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_reservedWord
+ return p
+}
+
+func InitEmptyReservedWordContext(p *ReservedWordContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = CypherParserRULE_reservedWord
+}
+
+func (*ReservedWordContext) IsReservedWordContext() {}
+
+func NewReservedWordContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ReservedWordContext {
+ var p = new(ReservedWordContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = CypherParserRULE_reservedWord
+
+ return p
+}
+
+func (s *ReservedWordContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *ReservedWordContext) ALL() antlr.TerminalNode {
+ return s.GetToken(CypherParserALL, 0)
+}
+
+func (s *ReservedWordContext) ASC() antlr.TerminalNode {
+ return s.GetToken(CypherParserASC, 0)
+}
+
+func (s *ReservedWordContext) ASCENDING() antlr.TerminalNode {
+ return s.GetToken(CypherParserASCENDING, 0)
+}
+
+func (s *ReservedWordContext) BY() antlr.TerminalNode {
+ return s.GetToken(CypherParserBY, 0)
+}
+
+func (s *ReservedWordContext) CREATE() antlr.TerminalNode {
+ return s.GetToken(CypherParserCREATE, 0)
+}
+
+func (s *ReservedWordContext) DELETE() antlr.TerminalNode {
+ return s.GetToken(CypherParserDELETE, 0)
+}
+
+func (s *ReservedWordContext) DESC() antlr.TerminalNode {
+ return s.GetToken(CypherParserDESC, 0)
+}
+
+func (s *ReservedWordContext) DESCENDING() antlr.TerminalNode {
+ return s.GetToken(CypherParserDESCENDING, 0)
+}
+
+func (s *ReservedWordContext) DETACH() antlr.TerminalNode {
+ return s.GetToken(CypherParserDETACH, 0)
+}
+
+func (s *ReservedWordContext) EXISTS() antlr.TerminalNode {
+ return s.GetToken(CypherParserEXISTS, 0)
+}
+
+func (s *ReservedWordContext) LIMIT() antlr.TerminalNode {
+ return s.GetToken(CypherParserLIMIT, 0)
+}
+
+func (s *ReservedWordContext) MATCH() antlr.TerminalNode {
+ return s.GetToken(CypherParserMATCH, 0)
+}
+
+func (s *ReservedWordContext) MERGE() antlr.TerminalNode {
+ return s.GetToken(CypherParserMERGE, 0)
+}
+
+func (s *ReservedWordContext) ON() antlr.TerminalNode {
+ return s.GetToken(CypherParserON, 0)
+}
+
+func (s *ReservedWordContext) OPTIONAL() antlr.TerminalNode {
+ return s.GetToken(CypherParserOPTIONAL, 0)
+}
+
+func (s *ReservedWordContext) ORDER() antlr.TerminalNode {
+ return s.GetToken(CypherParserORDER, 0)
+}
+
+func (s *ReservedWordContext) REMOVE() antlr.TerminalNode {
+ return s.GetToken(CypherParserREMOVE, 0)
+}
+
+func (s *ReservedWordContext) RETURN() antlr.TerminalNode {
+ return s.GetToken(CypherParserRETURN, 0)
+}
+
+func (s *ReservedWordContext) SET() antlr.TerminalNode {
+ return s.GetToken(CypherParserSET, 0)
+}
+
+func (s *ReservedWordContext) SKIP_W() antlr.TerminalNode {
+ return s.GetToken(CypherParserSKIP_W, 0)
+}
+
+func (s *ReservedWordContext) WHERE() antlr.TerminalNode {
+ return s.GetToken(CypherParserWHERE, 0)
+}
+
+func (s *ReservedWordContext) WITH() antlr.TerminalNode {
+ return s.GetToken(CypherParserWITH, 0)
+}
+
+func (s *ReservedWordContext) UNION() antlr.TerminalNode {
+ return s.GetToken(CypherParserUNION, 0)
+}
+
+func (s *ReservedWordContext) UNWIND() antlr.TerminalNode {
+ return s.GetToken(CypherParserUNWIND, 0)
+}
+
+func (s *ReservedWordContext) AND() antlr.TerminalNode {
+ return s.GetToken(CypherParserAND, 0)
+}
+
+func (s *ReservedWordContext) AS() antlr.TerminalNode {
+ return s.GetToken(CypherParserAS, 0)
+}
+
+func (s *ReservedWordContext) CONTAINS() antlr.TerminalNode {
+ return s.GetToken(CypherParserCONTAINS, 0)
+}
+
+func (s *ReservedWordContext) DISTINCT() antlr.TerminalNode {
+ return s.GetToken(CypherParserDISTINCT, 0)
+}
+
+func (s *ReservedWordContext) ENDS() antlr.TerminalNode {
+ return s.GetToken(CypherParserENDS, 0)
+}
+
+func (s *ReservedWordContext) IN() antlr.TerminalNode {
+ return s.GetToken(CypherParserIN, 0)
+}
+
+func (s *ReservedWordContext) IS() antlr.TerminalNode {
+ return s.GetToken(CypherParserIS, 0)
+}
+
+func (s *ReservedWordContext) NOT() antlr.TerminalNode {
+ return s.GetToken(CypherParserNOT, 0)
+}
+
+func (s *ReservedWordContext) OR() antlr.TerminalNode {
+ return s.GetToken(CypherParserOR, 0)
+}
+
+func (s *ReservedWordContext) STARTS() antlr.TerminalNode {
+ return s.GetToken(CypherParserSTARTS, 0)
+}
+
+func (s *ReservedWordContext) XOR() antlr.TerminalNode {
+ return s.GetToken(CypherParserXOR, 0)
+}
+
+func (s *ReservedWordContext) FALSE() antlr.TerminalNode {
+ return s.GetToken(CypherParserFALSE, 0)
+}
+
+func (s *ReservedWordContext) TRUE() antlr.TerminalNode {
+ return s.GetToken(CypherParserTRUE, 0)
+}
+
+func (s *ReservedWordContext) NULL_W() antlr.TerminalNode {
+ return s.GetToken(CypherParserNULL_W, 0)
+}
+
+func (s *ReservedWordContext) CONSTRAINT() antlr.TerminalNode {
+ return s.GetToken(CypherParserCONSTRAINT, 0)
+}
+
+func (s *ReservedWordContext) DO() antlr.TerminalNode {
+ return s.GetToken(CypherParserDO, 0)
+}
+
+func (s *ReservedWordContext) FOR() antlr.TerminalNode {
+ return s.GetToken(CypherParserFOR, 0)
+}
+
+func (s *ReservedWordContext) REQUIRE() antlr.TerminalNode {
+ return s.GetToken(CypherParserREQUIRE, 0)
+}
+
+func (s *ReservedWordContext) UNIQUE() antlr.TerminalNode {
+ return s.GetToken(CypherParserUNIQUE, 0)
+}
+
+func (s *ReservedWordContext) CASE() antlr.TerminalNode {
+ return s.GetToken(CypherParserCASE, 0)
+}
+
+func (s *ReservedWordContext) WHEN() antlr.TerminalNode {
+ return s.GetToken(CypherParserWHEN, 0)
+}
+
+func (s *ReservedWordContext) THEN() antlr.TerminalNode {
+ return s.GetToken(CypherParserTHEN, 0)
+}
+
+func (s *ReservedWordContext) ELSE() antlr.TerminalNode {
+ return s.GetToken(CypherParserELSE, 0)
+}
+
+func (s *ReservedWordContext) END() antlr.TerminalNode {
+ return s.GetToken(CypherParserEND, 0)
+}
+
+func (s *ReservedWordContext) MANDATORY() antlr.TerminalNode {
+ return s.GetToken(CypherParserMANDATORY, 0)
+}
+
+func (s *ReservedWordContext) SCALAR() antlr.TerminalNode {
+ return s.GetToken(CypherParserSCALAR, 0)
+}
+
+func (s *ReservedWordContext) OF() antlr.TerminalNode {
+ return s.GetToken(CypherParserOF, 0)
+}
+
+func (s *ReservedWordContext) ADD() antlr.TerminalNode {
+ return s.GetToken(CypherParserADD, 0)
+}
+
+func (s *ReservedWordContext) DROP() antlr.TerminalNode {
+ return s.GetToken(CypherParserDROP, 0)
+}
+
+func (s *ReservedWordContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *ReservedWordContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *ReservedWordContext) EnterRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.EnterReservedWord(s)
+ }
+}
+
+func (s *ReservedWordContext) ExitRule(listener antlr.ParseTreeListener) {
+ if listenerT, ok := listener.(CypherParserListener); ok {
+ listenerT.ExitReservedWord(s)
+ }
+}
+
+func (p *CypherParser) ReservedWord() (localctx IReservedWordContext) {
+ localctx = NewReservedWordContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 194, CypherParserRULE_reservedWord)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(1081)
+ _la = p.GetTokenStream().LA(1)
+
+ if !((int64((_la-42)) & ^0x3f) == 0 && ((int64(1)<<(_la-42))&9007199254740991) != 0) {
+ p.GetErrorHandler().RecoverInline(p)
+ } else {
+ p.GetErrorHandler().ReportMatch(p)
+ p.Consume()
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
diff --git a/nornicdb/pkg/cypher/antlr/cypherparser_base_listener.go b/nornicdb/pkg/cypher/antlr/cypherparser_base_listener.go
new file mode 100644
index 0000000..065eb62
--- /dev/null
+++ b/nornicdb/pkg/cypher/antlr/cypherparser_base_listener.go
@@ -0,0 +1,614 @@
+// Code generated from CypherParser.g4 by ANTLR 4.13.2. DO NOT EDIT.
+
+package antlr // CypherParser
+import "github.com/antlr4-go/antlr/v4"
+
+// BaseCypherParserListener is a complete listener for a parse tree produced by CypherParser.
+type BaseCypherParserListener struct{}
+
+var _ CypherParserListener = &BaseCypherParserListener{}
+
+// VisitTerminal is called when a terminal node is visited.
+func (s *BaseCypherParserListener) VisitTerminal(node antlr.TerminalNode) {}
+
+// VisitErrorNode is called when an error node is visited.
+func (s *BaseCypherParserListener) VisitErrorNode(node antlr.ErrorNode) {}
+
+// EnterEveryRule is called when any rule is entered.
+func (s *BaseCypherParserListener) EnterEveryRule(ctx antlr.ParserRuleContext) {}
+
+// ExitEveryRule is called when any rule is exited.
+func (s *BaseCypherParserListener) ExitEveryRule(ctx antlr.ParserRuleContext) {}
+
+// EnterScript is called when production script is entered.
+func (s *BaseCypherParserListener) EnterScript(ctx *ScriptContext) {}
+
+// ExitScript is called when production script is exited.
+func (s *BaseCypherParserListener) ExitScript(ctx *ScriptContext) {}
+
+// EnterQuery is called when production query is entered.
+func (s *BaseCypherParserListener) EnterQuery(ctx *QueryContext) {}
+
+// ExitQuery is called when production query is exited.
+func (s *BaseCypherParserListener) ExitQuery(ctx *QueryContext) {}
+
+// EnterQueryPrefix is called when production queryPrefix is entered.
+func (s *BaseCypherParserListener) EnterQueryPrefix(ctx *QueryPrefixContext) {}
+
+// ExitQueryPrefix is called when production queryPrefix is exited.
+func (s *BaseCypherParserListener) ExitQueryPrefix(ctx *QueryPrefixContext) {}
+
+// EnterShowCommand is called when production showCommand is entered.
+func (s *BaseCypherParserListener) EnterShowCommand(ctx *ShowCommandContext) {}
+
+// ExitShowCommand is called when production showCommand is exited.
+func (s *BaseCypherParserListener) ExitShowCommand(ctx *ShowCommandContext) {}
+
+// EnterSchemaCommand is called when production schemaCommand is entered.
+func (s *BaseCypherParserListener) EnterSchemaCommand(ctx *SchemaCommandContext) {}
+
+// ExitSchemaCommand is called when production schemaCommand is exited.
+func (s *BaseCypherParserListener) ExitSchemaCommand(ctx *SchemaCommandContext) {}
+
+// EnterRegularQuery is called when production regularQuery is entered.
+func (s *BaseCypherParserListener) EnterRegularQuery(ctx *RegularQueryContext) {}
+
+// ExitRegularQuery is called when production regularQuery is exited.
+func (s *BaseCypherParserListener) ExitRegularQuery(ctx *RegularQueryContext) {}
+
+// EnterSingleQuery is called when production singleQuery is entered.
+func (s *BaseCypherParserListener) EnterSingleQuery(ctx *SingleQueryContext) {}
+
+// ExitSingleQuery is called when production singleQuery is exited.
+func (s *BaseCypherParserListener) ExitSingleQuery(ctx *SingleQueryContext) {}
+
+// EnterStandaloneCall is called when production standaloneCall is entered.
+func (s *BaseCypherParserListener) EnterStandaloneCall(ctx *StandaloneCallContext) {}
+
+// ExitStandaloneCall is called when production standaloneCall is exited.
+func (s *BaseCypherParserListener) ExitStandaloneCall(ctx *StandaloneCallContext) {}
+
+// EnterExistsSubquery is called when production existsSubquery is entered.
+func (s *BaseCypherParserListener) EnterExistsSubquery(ctx *ExistsSubqueryContext) {}
+
+// ExitExistsSubquery is called when production existsSubquery is exited.
+func (s *BaseCypherParserListener) ExitExistsSubquery(ctx *ExistsSubqueryContext) {}
+
+// EnterCountSubquery is called when production countSubquery is entered.
+func (s *BaseCypherParserListener) EnterCountSubquery(ctx *CountSubqueryContext) {}
+
+// ExitCountSubquery is called when production countSubquery is exited.
+func (s *BaseCypherParserListener) ExitCountSubquery(ctx *CountSubqueryContext) {}
+
+// EnterCallSubquery is called when production callSubquery is entered.
+func (s *BaseCypherParserListener) EnterCallSubquery(ctx *CallSubqueryContext) {}
+
+// ExitCallSubquery is called when production callSubquery is exited.
+func (s *BaseCypherParserListener) ExitCallSubquery(ctx *CallSubqueryContext) {}
+
+// EnterSubqueryBody is called when production subqueryBody is entered.
+func (s *BaseCypherParserListener) EnterSubqueryBody(ctx *SubqueryBodyContext) {}
+
+// ExitSubqueryBody is called when production subqueryBody is exited.
+func (s *BaseCypherParserListener) ExitSubqueryBody(ctx *SubqueryBodyContext) {}
+
+// EnterReturnSt is called when production returnSt is entered.
+func (s *BaseCypherParserListener) EnterReturnSt(ctx *ReturnStContext) {}
+
+// ExitReturnSt is called when production returnSt is exited.
+func (s *BaseCypherParserListener) ExitReturnSt(ctx *ReturnStContext) {}
+
+// EnterWithSt is called when production withSt is entered.
+func (s *BaseCypherParserListener) EnterWithSt(ctx *WithStContext) {}
+
+// ExitWithSt is called when production withSt is exited.
+func (s *BaseCypherParserListener) ExitWithSt(ctx *WithStContext) {}
+
+// EnterSkipSt is called when production skipSt is entered.
+func (s *BaseCypherParserListener) EnterSkipSt(ctx *SkipStContext) {}
+
+// ExitSkipSt is called when production skipSt is exited.
+func (s *BaseCypherParserListener) ExitSkipSt(ctx *SkipStContext) {}
+
+// EnterLimitSt is called when production limitSt is entered.
+func (s *BaseCypherParserListener) EnterLimitSt(ctx *LimitStContext) {}
+
+// ExitLimitSt is called when production limitSt is exited.
+func (s *BaseCypherParserListener) ExitLimitSt(ctx *LimitStContext) {}
+
+// EnterProjectionBody is called when production projectionBody is entered.
+func (s *BaseCypherParserListener) EnterProjectionBody(ctx *ProjectionBodyContext) {}
+
+// ExitProjectionBody is called when production projectionBody is exited.
+func (s *BaseCypherParserListener) ExitProjectionBody(ctx *ProjectionBodyContext) {}
+
+// EnterProjectionItems is called when production projectionItems is entered.
+func (s *BaseCypherParserListener) EnterProjectionItems(ctx *ProjectionItemsContext) {}
+
+// ExitProjectionItems is called when production projectionItems is exited.
+func (s *BaseCypherParserListener) ExitProjectionItems(ctx *ProjectionItemsContext) {}
+
+// EnterProjectionItem is called when production projectionItem is entered.
+func (s *BaseCypherParserListener) EnterProjectionItem(ctx *ProjectionItemContext) {}
+
+// ExitProjectionItem is called when production projectionItem is exited.
+func (s *BaseCypherParserListener) ExitProjectionItem(ctx *ProjectionItemContext) {}
+
+// EnterOrderItem is called when production orderItem is entered.
+func (s *BaseCypherParserListener) EnterOrderItem(ctx *OrderItemContext) {}
+
+// ExitOrderItem is called when production orderItem is exited.
+func (s *BaseCypherParserListener) ExitOrderItem(ctx *OrderItemContext) {}
+
+// EnterOrderSt is called when production orderSt is entered.
+func (s *BaseCypherParserListener) EnterOrderSt(ctx *OrderStContext) {}
+
+// ExitOrderSt is called when production orderSt is exited.
+func (s *BaseCypherParserListener) ExitOrderSt(ctx *OrderStContext) {}
+
+// EnterSinglePartQ is called when production singlePartQ is entered.
+func (s *BaseCypherParserListener) EnterSinglePartQ(ctx *SinglePartQContext) {}
+
+// ExitSinglePartQ is called when production singlePartQ is exited.
+func (s *BaseCypherParserListener) ExitSinglePartQ(ctx *SinglePartQContext) {}
+
+// EnterMultiPartQ is called when production multiPartQ is entered.
+func (s *BaseCypherParserListener) EnterMultiPartQ(ctx *MultiPartQContext) {}
+
+// ExitMultiPartQ is called when production multiPartQ is exited.
+func (s *BaseCypherParserListener) ExitMultiPartQ(ctx *MultiPartQContext) {}
+
+// EnterMatchSt is called when production matchSt is entered.
+func (s *BaseCypherParserListener) EnterMatchSt(ctx *MatchStContext) {}
+
+// ExitMatchSt is called when production matchSt is exited.
+func (s *BaseCypherParserListener) ExitMatchSt(ctx *MatchStContext) {}
+
+// EnterUnwindSt is called when production unwindSt is entered.
+func (s *BaseCypherParserListener) EnterUnwindSt(ctx *UnwindStContext) {}
+
+// ExitUnwindSt is called when production unwindSt is exited.
+func (s *BaseCypherParserListener) ExitUnwindSt(ctx *UnwindStContext) {}
+
+// EnterReadingStatement is called when production readingStatement is entered.
+func (s *BaseCypherParserListener) EnterReadingStatement(ctx *ReadingStatementContext) {}
+
+// ExitReadingStatement is called when production readingStatement is exited.
+func (s *BaseCypherParserListener) ExitReadingStatement(ctx *ReadingStatementContext) {}
+
+// EnterUpdatingStatement is called when production updatingStatement is entered.
+func (s *BaseCypherParserListener) EnterUpdatingStatement(ctx *UpdatingStatementContext) {}
+
+// ExitUpdatingStatement is called when production updatingStatement is exited.
+func (s *BaseCypherParserListener) ExitUpdatingStatement(ctx *UpdatingStatementContext) {}
+
+// EnterDeleteSt is called when production deleteSt is entered.
+func (s *BaseCypherParserListener) EnterDeleteSt(ctx *DeleteStContext) {}
+
+// ExitDeleteSt is called when production deleteSt is exited.
+func (s *BaseCypherParserListener) ExitDeleteSt(ctx *DeleteStContext) {}
+
+// EnterRemoveSt is called when production removeSt is entered.
+func (s *BaseCypherParserListener) EnterRemoveSt(ctx *RemoveStContext) {}
+
+// ExitRemoveSt is called when production removeSt is exited.
+func (s *BaseCypherParserListener) ExitRemoveSt(ctx *RemoveStContext) {}
+
+// EnterRemoveItem is called when production removeItem is entered.
+func (s *BaseCypherParserListener) EnterRemoveItem(ctx *RemoveItemContext) {}
+
+// ExitRemoveItem is called when production removeItem is exited.
+func (s *BaseCypherParserListener) ExitRemoveItem(ctx *RemoveItemContext) {}
+
+// EnterQueryCallSt is called when production queryCallSt is entered.
+func (s *BaseCypherParserListener) EnterQueryCallSt(ctx *QueryCallStContext) {}
+
+// ExitQueryCallSt is called when production queryCallSt is exited.
+func (s *BaseCypherParserListener) ExitQueryCallSt(ctx *QueryCallStContext) {}
+
+// EnterParenExpressionChain is called when production parenExpressionChain is entered.
+func (s *BaseCypherParserListener) EnterParenExpressionChain(ctx *ParenExpressionChainContext) {}
+
+// ExitParenExpressionChain is called when production parenExpressionChain is exited.
+func (s *BaseCypherParserListener) ExitParenExpressionChain(ctx *ParenExpressionChainContext) {}
+
+// EnterYieldItems is called when production yieldItems is entered.
+func (s *BaseCypherParserListener) EnterYieldItems(ctx *YieldItemsContext) {}
+
+// ExitYieldItems is called when production yieldItems is exited.
+func (s *BaseCypherParserListener) ExitYieldItems(ctx *YieldItemsContext) {}
+
+// EnterYieldItem is called when production yieldItem is entered.
+func (s *BaseCypherParserListener) EnterYieldItem(ctx *YieldItemContext) {}
+
+// ExitYieldItem is called when production yieldItem is exited.
+func (s *BaseCypherParserListener) ExitYieldItem(ctx *YieldItemContext) {}
+
+// EnterMergeSt is called when production mergeSt is entered.
+func (s *BaseCypherParserListener) EnterMergeSt(ctx *MergeStContext) {}
+
+// ExitMergeSt is called when production mergeSt is exited.
+func (s *BaseCypherParserListener) ExitMergeSt(ctx *MergeStContext) {}
+
+// EnterMergeAction is called when production mergeAction is entered.
+func (s *BaseCypherParserListener) EnterMergeAction(ctx *MergeActionContext) {}
+
+// ExitMergeAction is called when production mergeAction is exited.
+func (s *BaseCypherParserListener) ExitMergeAction(ctx *MergeActionContext) {}
+
+// EnterSetSt is called when production setSt is entered.
+func (s *BaseCypherParserListener) EnterSetSt(ctx *SetStContext) {}
+
+// ExitSetSt is called when production setSt is exited.
+func (s *BaseCypherParserListener) ExitSetSt(ctx *SetStContext) {}
+
+// EnterSetItem is called when production setItem is entered.
+func (s *BaseCypherParserListener) EnterSetItem(ctx *SetItemContext) {}
+
+// ExitSetItem is called when production setItem is exited.
+func (s *BaseCypherParserListener) ExitSetItem(ctx *SetItemContext) {}
+
+// EnterNodeLabels is called when production nodeLabels is entered.
+func (s *BaseCypherParserListener) EnterNodeLabels(ctx *NodeLabelsContext) {}
+
+// ExitNodeLabels is called when production nodeLabels is exited.
+func (s *BaseCypherParserListener) ExitNodeLabels(ctx *NodeLabelsContext) {}
+
+// EnterCreateSt is called when production createSt is entered.
+func (s *BaseCypherParserListener) EnterCreateSt(ctx *CreateStContext) {}
+
+// ExitCreateSt is called when production createSt is exited.
+func (s *BaseCypherParserListener) ExitCreateSt(ctx *CreateStContext) {}
+
+// EnterPatternWhere is called when production patternWhere is entered.
+func (s *BaseCypherParserListener) EnterPatternWhere(ctx *PatternWhereContext) {}
+
+// ExitPatternWhere is called when production patternWhere is exited.
+func (s *BaseCypherParserListener) ExitPatternWhere(ctx *PatternWhereContext) {}
+
+// EnterWhere is called when production where is entered.
+func (s *BaseCypherParserListener) EnterWhere(ctx *WhereContext) {}
+
+// ExitWhere is called when production where is exited.
+func (s *BaseCypherParserListener) ExitWhere(ctx *WhereContext) {}
+
+// EnterPattern is called when production pattern is entered.
+func (s *BaseCypherParserListener) EnterPattern(ctx *PatternContext) {}
+
+// ExitPattern is called when production pattern is exited.
+func (s *BaseCypherParserListener) ExitPattern(ctx *PatternContext) {}
+
+// EnterExpression is called when production expression is entered.
+func (s *BaseCypherParserListener) EnterExpression(ctx *ExpressionContext) {}
+
+// ExitExpression is called when production expression is exited.
+func (s *BaseCypherParserListener) ExitExpression(ctx *ExpressionContext) {}
+
+// EnterXorExpression is called when production xorExpression is entered.
+func (s *BaseCypherParserListener) EnterXorExpression(ctx *XorExpressionContext) {}
+
+// ExitXorExpression is called when production xorExpression is exited.
+func (s *BaseCypherParserListener) ExitXorExpression(ctx *XorExpressionContext) {}
+
+// EnterAndExpression is called when production andExpression is entered.
+func (s *BaseCypherParserListener) EnterAndExpression(ctx *AndExpressionContext) {}
+
+// ExitAndExpression is called when production andExpression is exited.
+func (s *BaseCypherParserListener) ExitAndExpression(ctx *AndExpressionContext) {}
+
+// EnterNotExpression is called when production notExpression is entered.
+func (s *BaseCypherParserListener) EnterNotExpression(ctx *NotExpressionContext) {}
+
+// ExitNotExpression is called when production notExpression is exited.
+func (s *BaseCypherParserListener) ExitNotExpression(ctx *NotExpressionContext) {}
+
+// EnterComparisonExpression is called when production comparisonExpression is entered.
+func (s *BaseCypherParserListener) EnterComparisonExpression(ctx *ComparisonExpressionContext) {}
+
+// ExitComparisonExpression is called when production comparisonExpression is exited.
+func (s *BaseCypherParserListener) ExitComparisonExpression(ctx *ComparisonExpressionContext) {}
+
+// EnterComparisonSigns is called when production comparisonSigns is entered.
+func (s *BaseCypherParserListener) EnterComparisonSigns(ctx *ComparisonSignsContext) {}
+
+// ExitComparisonSigns is called when production comparisonSigns is exited.
+func (s *BaseCypherParserListener) ExitComparisonSigns(ctx *ComparisonSignsContext) {}
+
+// EnterAddSubExpression is called when production addSubExpression is entered.
+func (s *BaseCypherParserListener) EnterAddSubExpression(ctx *AddSubExpressionContext) {}
+
+// ExitAddSubExpression is called when production addSubExpression is exited.
+func (s *BaseCypherParserListener) ExitAddSubExpression(ctx *AddSubExpressionContext) {}
+
+// EnterMultDivExpression is called when production multDivExpression is entered.
+func (s *BaseCypherParserListener) EnterMultDivExpression(ctx *MultDivExpressionContext) {}
+
+// ExitMultDivExpression is called when production multDivExpression is exited.
+func (s *BaseCypherParserListener) ExitMultDivExpression(ctx *MultDivExpressionContext) {}
+
+// EnterPowerExpression is called when production powerExpression is entered.
+func (s *BaseCypherParserListener) EnterPowerExpression(ctx *PowerExpressionContext) {}
+
+// ExitPowerExpression is called when production powerExpression is exited.
+func (s *BaseCypherParserListener) ExitPowerExpression(ctx *PowerExpressionContext) {}
+
+// EnterUnaryAddSubExpression is called when production unaryAddSubExpression is entered.
+func (s *BaseCypherParserListener) EnterUnaryAddSubExpression(ctx *UnaryAddSubExpressionContext) {}
+
+// ExitUnaryAddSubExpression is called when production unaryAddSubExpression is exited.
+func (s *BaseCypherParserListener) ExitUnaryAddSubExpression(ctx *UnaryAddSubExpressionContext) {}
+
+// EnterAtomicExpression is called when production atomicExpression is entered.
+func (s *BaseCypherParserListener) EnterAtomicExpression(ctx *AtomicExpressionContext) {}
+
+// ExitAtomicExpression is called when production atomicExpression is exited.
+func (s *BaseCypherParserListener) ExitAtomicExpression(ctx *AtomicExpressionContext) {}
+
+// EnterListExpression is called when production listExpression is entered.
+func (s *BaseCypherParserListener) EnterListExpression(ctx *ListExpressionContext) {}
+
+// ExitListExpression is called when production listExpression is exited.
+func (s *BaseCypherParserListener) ExitListExpression(ctx *ListExpressionContext) {}
+
+// EnterStringExpression is called when production stringExpression is entered.
+func (s *BaseCypherParserListener) EnterStringExpression(ctx *StringExpressionContext) {}
+
+// ExitStringExpression is called when production stringExpression is exited.
+func (s *BaseCypherParserListener) ExitStringExpression(ctx *StringExpressionContext) {}
+
+// EnterStringExpPrefix is called when production stringExpPrefix is entered.
+func (s *BaseCypherParserListener) EnterStringExpPrefix(ctx *StringExpPrefixContext) {}
+
+// ExitStringExpPrefix is called when production stringExpPrefix is exited.
+func (s *BaseCypherParserListener) ExitStringExpPrefix(ctx *StringExpPrefixContext) {}
+
+// EnterNullExpression is called when production nullExpression is entered.
+func (s *BaseCypherParserListener) EnterNullExpression(ctx *NullExpressionContext) {}
+
+// ExitNullExpression is called when production nullExpression is exited.
+func (s *BaseCypherParserListener) ExitNullExpression(ctx *NullExpressionContext) {}
+
+// EnterPropertyOrLabelExpression is called when production propertyOrLabelExpression is entered.
+func (s *BaseCypherParserListener) EnterPropertyOrLabelExpression(ctx *PropertyOrLabelExpressionContext) {
+}
+
+// ExitPropertyOrLabelExpression is called when production propertyOrLabelExpression is exited.
+func (s *BaseCypherParserListener) ExitPropertyOrLabelExpression(ctx *PropertyOrLabelExpressionContext) {
+}
+
+// EnterPropertyExpression is called when production propertyExpression is entered.
+func (s *BaseCypherParserListener) EnterPropertyExpression(ctx *PropertyExpressionContext) {}
+
+// ExitPropertyExpression is called when production propertyExpression is exited.
+func (s *BaseCypherParserListener) ExitPropertyExpression(ctx *PropertyExpressionContext) {}
+
+// EnterPatternPart is called when production patternPart is entered.
+func (s *BaseCypherParserListener) EnterPatternPart(ctx *PatternPartContext) {}
+
+// ExitPatternPart is called when production patternPart is exited.
+func (s *BaseCypherParserListener) ExitPatternPart(ctx *PatternPartContext) {}
+
+// EnterPathFunction is called when production pathFunction is entered.
+func (s *BaseCypherParserListener) EnterPathFunction(ctx *PathFunctionContext) {}
+
+// ExitPathFunction is called when production pathFunction is exited.
+func (s *BaseCypherParserListener) ExitPathFunction(ctx *PathFunctionContext) {}
+
+// EnterPatternElem is called when production patternElem is entered.
+func (s *BaseCypherParserListener) EnterPatternElem(ctx *PatternElemContext) {}
+
+// ExitPatternElem is called when production patternElem is exited.
+func (s *BaseCypherParserListener) ExitPatternElem(ctx *PatternElemContext) {}
+
+// EnterPatternElemChain is called when production patternElemChain is entered.
+func (s *BaseCypherParserListener) EnterPatternElemChain(ctx *PatternElemChainContext) {}
+
+// ExitPatternElemChain is called when production patternElemChain is exited.
+func (s *BaseCypherParserListener) ExitPatternElemChain(ctx *PatternElemChainContext) {}
+
+// EnterProperties is called when production properties is entered.
+func (s *BaseCypherParserListener) EnterProperties(ctx *PropertiesContext) {}
+
+// ExitProperties is called when production properties is exited.
+func (s *BaseCypherParserListener) ExitProperties(ctx *PropertiesContext) {}
+
+// EnterNodePattern is called when production nodePattern is entered.
+func (s *BaseCypherParserListener) EnterNodePattern(ctx *NodePatternContext) {}
+
+// ExitNodePattern is called when production nodePattern is exited.
+func (s *BaseCypherParserListener) ExitNodePattern(ctx *NodePatternContext) {}
+
+// EnterAtom is called when production atom is entered.
+func (s *BaseCypherParserListener) EnterAtom(ctx *AtomContext) {}
+
+// ExitAtom is called when production atom is exited.
+func (s *BaseCypherParserListener) ExitAtom(ctx *AtomContext) {}
+
+// EnterLhs is called when production lhs is entered.
+func (s *BaseCypherParserListener) EnterLhs(ctx *LhsContext) {}
+
+// ExitLhs is called when production lhs is exited.
+func (s *BaseCypherParserListener) ExitLhs(ctx *LhsContext) {}
+
+// EnterRelationshipPattern is called when production relationshipPattern is entered.
+func (s *BaseCypherParserListener) EnterRelationshipPattern(ctx *RelationshipPatternContext) {}
+
+// ExitRelationshipPattern is called when production relationshipPattern is exited.
+func (s *BaseCypherParserListener) ExitRelationshipPattern(ctx *RelationshipPatternContext) {}
+
+// EnterRelationDetail is called when production relationDetail is entered.
+func (s *BaseCypherParserListener) EnterRelationDetail(ctx *RelationDetailContext) {}
+
+// ExitRelationDetail is called when production relationDetail is exited.
+func (s *BaseCypherParserListener) ExitRelationDetail(ctx *RelationDetailContext) {}
+
+// EnterRelationshipTypes is called when production relationshipTypes is entered.
+func (s *BaseCypherParserListener) EnterRelationshipTypes(ctx *RelationshipTypesContext) {}
+
+// ExitRelationshipTypes is called when production relationshipTypes is exited.
+func (s *BaseCypherParserListener) ExitRelationshipTypes(ctx *RelationshipTypesContext) {}
+
+// EnterUnionSt is called when production unionSt is entered.
+func (s *BaseCypherParserListener) EnterUnionSt(ctx *UnionStContext) {}
+
+// ExitUnionSt is called when production unionSt is exited.
+func (s *BaseCypherParserListener) ExitUnionSt(ctx *UnionStContext) {}
+
+// EnterSubqueryExist is called when production subqueryExist is entered.
+func (s *BaseCypherParserListener) EnterSubqueryExist(ctx *SubqueryExistContext) {}
+
+// ExitSubqueryExist is called when production subqueryExist is exited.
+func (s *BaseCypherParserListener) ExitSubqueryExist(ctx *SubqueryExistContext) {}
+
+// EnterInvocationName is called when production invocationName is entered.
+func (s *BaseCypherParserListener) EnterInvocationName(ctx *InvocationNameContext) {}
+
+// ExitInvocationName is called when production invocationName is exited.
+func (s *BaseCypherParserListener) ExitInvocationName(ctx *InvocationNameContext) {}
+
+// EnterFunctionInvocation is called when production functionInvocation is entered.
+func (s *BaseCypherParserListener) EnterFunctionInvocation(ctx *FunctionInvocationContext) {}
+
+// ExitFunctionInvocation is called when production functionInvocation is exited.
+func (s *BaseCypherParserListener) ExitFunctionInvocation(ctx *FunctionInvocationContext) {}
+
+// EnterParenthesizedExpression is called when production parenthesizedExpression is entered.
+func (s *BaseCypherParserListener) EnterParenthesizedExpression(ctx *ParenthesizedExpressionContext) {
+}
+
+// ExitParenthesizedExpression is called when production parenthesizedExpression is exited.
+func (s *BaseCypherParserListener) ExitParenthesizedExpression(ctx *ParenthesizedExpressionContext) {}
+
+// EnterFilterWith is called when production filterWith is entered.
+func (s *BaseCypherParserListener) EnterFilterWith(ctx *FilterWithContext) {}
+
+// ExitFilterWith is called when production filterWith is exited.
+func (s *BaseCypherParserListener) ExitFilterWith(ctx *FilterWithContext) {}
+
+// EnterPatternComprehension is called when production patternComprehension is entered.
+func (s *BaseCypherParserListener) EnterPatternComprehension(ctx *PatternComprehensionContext) {}
+
+// ExitPatternComprehension is called when production patternComprehension is exited.
+func (s *BaseCypherParserListener) ExitPatternComprehension(ctx *PatternComprehensionContext) {}
+
+// EnterRelationshipsChainPattern is called when production relationshipsChainPattern is entered.
+func (s *BaseCypherParserListener) EnterRelationshipsChainPattern(ctx *RelationshipsChainPatternContext) {
+}
+
+// ExitRelationshipsChainPattern is called when production relationshipsChainPattern is exited.
+func (s *BaseCypherParserListener) ExitRelationshipsChainPattern(ctx *RelationshipsChainPatternContext) {
+}
+
+// EnterListComprehension is called when production listComprehension is entered.
+func (s *BaseCypherParserListener) EnterListComprehension(ctx *ListComprehensionContext) {}
+
+// ExitListComprehension is called when production listComprehension is exited.
+func (s *BaseCypherParserListener) ExitListComprehension(ctx *ListComprehensionContext) {}
+
+// EnterFilterExpression is called when production filterExpression is entered.
+func (s *BaseCypherParserListener) EnterFilterExpression(ctx *FilterExpressionContext) {}
+
+// ExitFilterExpression is called when production filterExpression is exited.
+func (s *BaseCypherParserListener) ExitFilterExpression(ctx *FilterExpressionContext) {}
+
+// EnterCountAll is called when production countAll is entered.
+func (s *BaseCypherParserListener) EnterCountAll(ctx *CountAllContext) {}
+
+// ExitCountAll is called when production countAll is exited.
+func (s *BaseCypherParserListener) ExitCountAll(ctx *CountAllContext) {}
+
+// EnterExpressionChain is called when production expressionChain is entered.
+func (s *BaseCypherParserListener) EnterExpressionChain(ctx *ExpressionChainContext) {}
+
+// ExitExpressionChain is called when production expressionChain is exited.
+func (s *BaseCypherParserListener) ExitExpressionChain(ctx *ExpressionChainContext) {}
+
+// EnterCaseExpression is called when production caseExpression is entered.
+func (s *BaseCypherParserListener) EnterCaseExpression(ctx *CaseExpressionContext) {}
+
+// ExitCaseExpression is called when production caseExpression is exited.
+func (s *BaseCypherParserListener) ExitCaseExpression(ctx *CaseExpressionContext) {}
+
+// EnterParameter is called when production parameter is entered.
+func (s *BaseCypherParserListener) EnterParameter(ctx *ParameterContext) {}
+
+// ExitParameter is called when production parameter is exited.
+func (s *BaseCypherParserListener) ExitParameter(ctx *ParameterContext) {}
+
+// EnterLiteral is called when production literal is entered.
+func (s *BaseCypherParserListener) EnterLiteral(ctx *LiteralContext) {}
+
+// ExitLiteral is called when production literal is exited.
+func (s *BaseCypherParserListener) ExitLiteral(ctx *LiteralContext) {}
+
+// EnterRangeLit is called when production rangeLit is entered.
+func (s *BaseCypherParserListener) EnterRangeLit(ctx *RangeLitContext) {}
+
+// ExitRangeLit is called when production rangeLit is exited.
+func (s *BaseCypherParserListener) ExitRangeLit(ctx *RangeLitContext) {}
+
+// EnterBoolLit is called when production boolLit is entered.
+func (s *BaseCypherParserListener) EnterBoolLit(ctx *BoolLitContext) {}
+
+// ExitBoolLit is called when production boolLit is exited.
+func (s *BaseCypherParserListener) ExitBoolLit(ctx *BoolLitContext) {}
+
+// EnterIntegerLit is called when production integerLit is entered.
+func (s *BaseCypherParserListener) EnterIntegerLit(ctx *IntegerLitContext) {}
+
+// ExitIntegerLit is called when production integerLit is exited.
+func (s *BaseCypherParserListener) ExitIntegerLit(ctx *IntegerLitContext) {}
+
+// EnterNumLit is called when production numLit is entered.
+func (s *BaseCypherParserListener) EnterNumLit(ctx *NumLitContext) {}
+
+// ExitNumLit is called when production numLit is exited.
+func (s *BaseCypherParserListener) ExitNumLit(ctx *NumLitContext) {}
+
+// EnterStringLit is called when production stringLit is entered.
+func (s *BaseCypherParserListener) EnterStringLit(ctx *StringLitContext) {}
+
+// ExitStringLit is called when production stringLit is exited.
+func (s *BaseCypherParserListener) ExitStringLit(ctx *StringLitContext) {}
+
+// EnterCharLit is called when production charLit is entered.
+func (s *BaseCypherParserListener) EnterCharLit(ctx *CharLitContext) {}
+
+// ExitCharLit is called when production charLit is exited.
+func (s *BaseCypherParserListener) ExitCharLit(ctx *CharLitContext) {}
+
+// EnterListLit is called when production listLit is entered.
+func (s *BaseCypherParserListener) EnterListLit(ctx *ListLitContext) {}
+
+// ExitListLit is called when production listLit is exited.
+func (s *BaseCypherParserListener) ExitListLit(ctx *ListLitContext) {}
+
+// EnterMapLit is called when production mapLit is entered.
+func (s *BaseCypherParserListener) EnterMapLit(ctx *MapLitContext) {}
+
+// ExitMapLit is called when production mapLit is exited.
+func (s *BaseCypherParserListener) ExitMapLit(ctx *MapLitContext) {}
+
+// EnterMapPair is called when production mapPair is entered.
+func (s *BaseCypherParserListener) EnterMapPair(ctx *MapPairContext) {}
+
+// ExitMapPair is called when production mapPair is exited.
+func (s *BaseCypherParserListener) ExitMapPair(ctx *MapPairContext) {}
+
+// EnterName is called when production name is entered.
+func (s *BaseCypherParserListener) EnterName(ctx *NameContext) {}
+
+// ExitName is called when production name is exited.
+func (s *BaseCypherParserListener) ExitName(ctx *NameContext) {}
+
+// EnterSymbol is called when production symbol is entered.
+func (s *BaseCypherParserListener) EnterSymbol(ctx *SymbolContext) {}
+
+// ExitSymbol is called when production symbol is exited.
+func (s *BaseCypherParserListener) ExitSymbol(ctx *SymbolContext) {}
+
+// EnterReservedWord is called when production reservedWord is entered.
+func (s *BaseCypherParserListener) EnterReservedWord(ctx *ReservedWordContext) {}
+
+// ExitReservedWord is called when production reservedWord is exited.
+func (s *BaseCypherParserListener) ExitReservedWord(ctx *ReservedWordContext) {}
diff --git a/nornicdb/pkg/cypher/antlr/cypherparser_listener.go b/nornicdb/pkg/cypher/antlr/cypherparser_listener.go
new file mode 100644
index 0000000..0eff6c0
--- /dev/null
+++ b/nornicdb/pkg/cypher/antlr/cypherparser_listener.go
@@ -0,0 +1,597 @@
+// Code generated from CypherParser.g4 by ANTLR 4.13.2. DO NOT EDIT.
+
+package antlr // CypherParser
+import "github.com/antlr4-go/antlr/v4"
+
+// CypherParserListener is a complete listener for a parse tree produced by CypherParser.
+type CypherParserListener interface {
+ antlr.ParseTreeListener
+
+ // EnterScript is called when entering the script production.
+ EnterScript(c *ScriptContext)
+
+ // EnterQuery is called when entering the query production.
+ EnterQuery(c *QueryContext)
+
+ // EnterQueryPrefix is called when entering the queryPrefix production.
+ EnterQueryPrefix(c *QueryPrefixContext)
+
+ // EnterShowCommand is called when entering the showCommand production.
+ EnterShowCommand(c *ShowCommandContext)
+
+ // EnterSchemaCommand is called when entering the schemaCommand production.
+ EnterSchemaCommand(c *SchemaCommandContext)
+
+ // EnterRegularQuery is called when entering the regularQuery production.
+ EnterRegularQuery(c *RegularQueryContext)
+
+ // EnterSingleQuery is called when entering the singleQuery production.
+ EnterSingleQuery(c *SingleQueryContext)
+
+ // EnterStandaloneCall is called when entering the standaloneCall production.
+ EnterStandaloneCall(c *StandaloneCallContext)
+
+ // EnterExistsSubquery is called when entering the existsSubquery production.
+ EnterExistsSubquery(c *ExistsSubqueryContext)
+
+ // EnterCountSubquery is called when entering the countSubquery production.
+ EnterCountSubquery(c *CountSubqueryContext)
+
+ // EnterCallSubquery is called when entering the callSubquery production.
+ EnterCallSubquery(c *CallSubqueryContext)
+
+ // EnterSubqueryBody is called when entering the subqueryBody production.
+ EnterSubqueryBody(c *SubqueryBodyContext)
+
+ // EnterReturnSt is called when entering the returnSt production.
+ EnterReturnSt(c *ReturnStContext)
+
+ // EnterWithSt is called when entering the withSt production.
+ EnterWithSt(c *WithStContext)
+
+ // EnterSkipSt is called when entering the skipSt production.
+ EnterSkipSt(c *SkipStContext)
+
+ // EnterLimitSt is called when entering the limitSt production.
+ EnterLimitSt(c *LimitStContext)
+
+ // EnterProjectionBody is called when entering the projectionBody production.
+ EnterProjectionBody(c *ProjectionBodyContext)
+
+ // EnterProjectionItems is called when entering the projectionItems production.
+ EnterProjectionItems(c *ProjectionItemsContext)
+
+ // EnterProjectionItem is called when entering the projectionItem production.
+ EnterProjectionItem(c *ProjectionItemContext)
+
+ // EnterOrderItem is called when entering the orderItem production.
+ EnterOrderItem(c *OrderItemContext)
+
+ // EnterOrderSt is called when entering the orderSt production.
+ EnterOrderSt(c *OrderStContext)
+
+ // EnterSinglePartQ is called when entering the singlePartQ production.
+ EnterSinglePartQ(c *SinglePartQContext)
+
+ // EnterMultiPartQ is called when entering the multiPartQ production.
+ EnterMultiPartQ(c *MultiPartQContext)
+
+ // EnterMatchSt is called when entering the matchSt production.
+ EnterMatchSt(c *MatchStContext)
+
+ // EnterUnwindSt is called when entering the unwindSt production.
+ EnterUnwindSt(c *UnwindStContext)
+
+ // EnterReadingStatement is called when entering the readingStatement production.
+ EnterReadingStatement(c *ReadingStatementContext)
+
+ // EnterUpdatingStatement is called when entering the updatingStatement production.
+ EnterUpdatingStatement(c *UpdatingStatementContext)
+
+ // EnterDeleteSt is called when entering the deleteSt production.
+ EnterDeleteSt(c *DeleteStContext)
+
+ // EnterRemoveSt is called when entering the removeSt production.
+ EnterRemoveSt(c *RemoveStContext)
+
+ // EnterRemoveItem is called when entering the removeItem production.
+ EnterRemoveItem(c *RemoveItemContext)
+
+ // EnterQueryCallSt is called when entering the queryCallSt production.
+ EnterQueryCallSt(c *QueryCallStContext)
+
+ // EnterParenExpressionChain is called when entering the parenExpressionChain production.
+ EnterParenExpressionChain(c *ParenExpressionChainContext)
+
+ // EnterYieldItems is called when entering the yieldItems production.
+ EnterYieldItems(c *YieldItemsContext)
+
+ // EnterYieldItem is called when entering the yieldItem production.
+ EnterYieldItem(c *YieldItemContext)
+
+ // EnterMergeSt is called when entering the mergeSt production.
+ EnterMergeSt(c *MergeStContext)
+
+ // EnterMergeAction is called when entering the mergeAction production.
+ EnterMergeAction(c *MergeActionContext)
+
+ // EnterSetSt is called when entering the setSt production.
+ EnterSetSt(c *SetStContext)
+
+ // EnterSetItem is called when entering the setItem production.
+ EnterSetItem(c *SetItemContext)
+
+ // EnterNodeLabels is called when entering the nodeLabels production.
+ EnterNodeLabels(c *NodeLabelsContext)
+
+ // EnterCreateSt is called when entering the createSt production.
+ EnterCreateSt(c *CreateStContext)
+
+ // EnterPatternWhere is called when entering the patternWhere production.
+ EnterPatternWhere(c *PatternWhereContext)
+
+ // EnterWhere is called when entering the where production.
+ EnterWhere(c *WhereContext)
+
+ // EnterPattern is called when entering the pattern production.
+ EnterPattern(c *PatternContext)
+
+ // EnterExpression is called when entering the expression production.
+ EnterExpression(c *ExpressionContext)
+
+ // EnterXorExpression is called when entering the xorExpression production.
+ EnterXorExpression(c *XorExpressionContext)
+
+ // EnterAndExpression is called when entering the andExpression production.
+ EnterAndExpression(c *AndExpressionContext)
+
+ // EnterNotExpression is called when entering the notExpression production.
+ EnterNotExpression(c *NotExpressionContext)
+
+ // EnterComparisonExpression is called when entering the comparisonExpression production.
+ EnterComparisonExpression(c *ComparisonExpressionContext)
+
+ // EnterComparisonSigns is called when entering the comparisonSigns production.
+ EnterComparisonSigns(c *ComparisonSignsContext)
+
+ // EnterAddSubExpression is called when entering the addSubExpression production.
+ EnterAddSubExpression(c *AddSubExpressionContext)
+
+ // EnterMultDivExpression is called when entering the multDivExpression production.
+ EnterMultDivExpression(c *MultDivExpressionContext)
+
+ // EnterPowerExpression is called when entering the powerExpression production.
+ EnterPowerExpression(c *PowerExpressionContext)
+
+ // EnterUnaryAddSubExpression is called when entering the unaryAddSubExpression production.
+ EnterUnaryAddSubExpression(c *UnaryAddSubExpressionContext)
+
+ // EnterAtomicExpression is called when entering the atomicExpression production.
+ EnterAtomicExpression(c *AtomicExpressionContext)
+
+ // EnterListExpression is called when entering the listExpression production.
+ EnterListExpression(c *ListExpressionContext)
+
+ // EnterStringExpression is called when entering the stringExpression production.
+ EnterStringExpression(c *StringExpressionContext)
+
+ // EnterStringExpPrefix is called when entering the stringExpPrefix production.
+ EnterStringExpPrefix(c *StringExpPrefixContext)
+
+ // EnterNullExpression is called when entering the nullExpression production.
+ EnterNullExpression(c *NullExpressionContext)
+
+ // EnterPropertyOrLabelExpression is called when entering the propertyOrLabelExpression production.
+ EnterPropertyOrLabelExpression(c *PropertyOrLabelExpressionContext)
+
+ // EnterPropertyExpression is called when entering the propertyExpression production.
+ EnterPropertyExpression(c *PropertyExpressionContext)
+
+ // EnterPatternPart is called when entering the patternPart production.
+ EnterPatternPart(c *PatternPartContext)
+
+ // EnterPathFunction is called when entering the pathFunction production.
+ EnterPathFunction(c *PathFunctionContext)
+
+ // EnterPatternElem is called when entering the patternElem production.
+ EnterPatternElem(c *PatternElemContext)
+
+ // EnterPatternElemChain is called when entering the patternElemChain production.
+ EnterPatternElemChain(c *PatternElemChainContext)
+
+ // EnterProperties is called when entering the properties production.
+ EnterProperties(c *PropertiesContext)
+
+ // EnterNodePattern is called when entering the nodePattern production.
+ EnterNodePattern(c *NodePatternContext)
+
+ // EnterAtom is called when entering the atom production.
+ EnterAtom(c *AtomContext)
+
+ // EnterLhs is called when entering the lhs production.
+ EnterLhs(c *LhsContext)
+
+ // EnterRelationshipPattern is called when entering the relationshipPattern production.
+ EnterRelationshipPattern(c *RelationshipPatternContext)
+
+ // EnterRelationDetail is called when entering the relationDetail production.
+ EnterRelationDetail(c *RelationDetailContext)
+
+ // EnterRelationshipTypes is called when entering the relationshipTypes production.
+ EnterRelationshipTypes(c *RelationshipTypesContext)
+
+ // EnterUnionSt is called when entering the unionSt production.
+ EnterUnionSt(c *UnionStContext)
+
+ // EnterSubqueryExist is called when entering the subqueryExist production.
+ EnterSubqueryExist(c *SubqueryExistContext)
+
+ // EnterInvocationName is called when entering the invocationName production.
+ EnterInvocationName(c *InvocationNameContext)
+
+ // EnterFunctionInvocation is called when entering the functionInvocation production.
+ EnterFunctionInvocation(c *FunctionInvocationContext)
+
+ // EnterParenthesizedExpression is called when entering the parenthesizedExpression production.
+ EnterParenthesizedExpression(c *ParenthesizedExpressionContext)
+
+ // EnterFilterWith is called when entering the filterWith production.
+ EnterFilterWith(c *FilterWithContext)
+
+ // EnterPatternComprehension is called when entering the patternComprehension production.
+ EnterPatternComprehension(c *PatternComprehensionContext)
+
+ // EnterRelationshipsChainPattern is called when entering the relationshipsChainPattern production.
+ EnterRelationshipsChainPattern(c *RelationshipsChainPatternContext)
+
+ // EnterListComprehension is called when entering the listComprehension production.
+ EnterListComprehension(c *ListComprehensionContext)
+
+ // EnterFilterExpression is called when entering the filterExpression production.
+ EnterFilterExpression(c *FilterExpressionContext)
+
+ // EnterCountAll is called when entering the countAll production.
+ EnterCountAll(c *CountAllContext)
+
+ // EnterExpressionChain is called when entering the expressionChain production.
+ EnterExpressionChain(c *ExpressionChainContext)
+
+ // EnterCaseExpression is called when entering the caseExpression production.
+ EnterCaseExpression(c *CaseExpressionContext)
+
+ // EnterParameter is called when entering the parameter production.
+ EnterParameter(c *ParameterContext)
+
+ // EnterLiteral is called when entering the literal production.
+ EnterLiteral(c *LiteralContext)
+
+ // EnterRangeLit is called when entering the rangeLit production.
+ EnterRangeLit(c *RangeLitContext)
+
+ // EnterBoolLit is called when entering the boolLit production.
+ EnterBoolLit(c *BoolLitContext)
+
+ // EnterIntegerLit is called when entering the integerLit production.
+ EnterIntegerLit(c *IntegerLitContext)
+
+ // EnterNumLit is called when entering the numLit production.
+ EnterNumLit(c *NumLitContext)
+
+ // EnterStringLit is called when entering the stringLit production.
+ EnterStringLit(c *StringLitContext)
+
+ // EnterCharLit is called when entering the charLit production.
+ EnterCharLit(c *CharLitContext)
+
+ // EnterListLit is called when entering the listLit production.
+ EnterListLit(c *ListLitContext)
+
+ // EnterMapLit is called when entering the mapLit production.
+ EnterMapLit(c *MapLitContext)
+
+ // EnterMapPair is called when entering the mapPair production.
+ EnterMapPair(c *MapPairContext)
+
+ // EnterName is called when entering the name production.
+ EnterName(c *NameContext)
+
+ // EnterSymbol is called when entering the symbol production.
+ EnterSymbol(c *SymbolContext)
+
+ // EnterReservedWord is called when entering the reservedWord production.
+ EnterReservedWord(c *ReservedWordContext)
+
+ // ExitScript is called when exiting the script production.
+ ExitScript(c *ScriptContext)
+
+ // ExitQuery is called when exiting the query production.
+ ExitQuery(c *QueryContext)
+
+ // ExitQueryPrefix is called when exiting the queryPrefix production.
+ ExitQueryPrefix(c *QueryPrefixContext)
+
+ // ExitShowCommand is called when exiting the showCommand production.
+ ExitShowCommand(c *ShowCommandContext)
+
+ // ExitSchemaCommand is called when exiting the schemaCommand production.
+ ExitSchemaCommand(c *SchemaCommandContext)
+
+ // ExitRegularQuery is called when exiting the regularQuery production.
+ ExitRegularQuery(c *RegularQueryContext)
+
+ // ExitSingleQuery is called when exiting the singleQuery production.
+ ExitSingleQuery(c *SingleQueryContext)
+
+ // ExitStandaloneCall is called when exiting the standaloneCall production.
+ ExitStandaloneCall(c *StandaloneCallContext)
+
+ // ExitExistsSubquery is called when exiting the existsSubquery production.
+ ExitExistsSubquery(c *ExistsSubqueryContext)
+
+ // ExitCountSubquery is called when exiting the countSubquery production.
+ ExitCountSubquery(c *CountSubqueryContext)
+
+ // ExitCallSubquery is called when exiting the callSubquery production.
+ ExitCallSubquery(c *CallSubqueryContext)
+
+ // ExitSubqueryBody is called when exiting the subqueryBody production.
+ ExitSubqueryBody(c *SubqueryBodyContext)
+
+ // ExitReturnSt is called when exiting the returnSt production.
+ ExitReturnSt(c *ReturnStContext)
+
+ // ExitWithSt is called when exiting the withSt production.
+ ExitWithSt(c *WithStContext)
+
+ // ExitSkipSt is called when exiting the skipSt production.
+ ExitSkipSt(c *SkipStContext)
+
+ // ExitLimitSt is called when exiting the limitSt production.
+ ExitLimitSt(c *LimitStContext)
+
+ // ExitProjectionBody is called when exiting the projectionBody production.
+ ExitProjectionBody(c *ProjectionBodyContext)
+
+ // ExitProjectionItems is called when exiting the projectionItems production.
+ ExitProjectionItems(c *ProjectionItemsContext)
+
+ // ExitProjectionItem is called when exiting the projectionItem production.
+ ExitProjectionItem(c *ProjectionItemContext)
+
+ // ExitOrderItem is called when exiting the orderItem production.
+ ExitOrderItem(c *OrderItemContext)
+
+ // ExitOrderSt is called when exiting the orderSt production.
+ ExitOrderSt(c *OrderStContext)
+
+ // ExitSinglePartQ is called when exiting the singlePartQ production.
+ ExitSinglePartQ(c *SinglePartQContext)
+
+ // ExitMultiPartQ is called when exiting the multiPartQ production.
+ ExitMultiPartQ(c *MultiPartQContext)
+
+ // ExitMatchSt is called when exiting the matchSt production.
+ ExitMatchSt(c *MatchStContext)
+
+ // ExitUnwindSt is called when exiting the unwindSt production.
+ ExitUnwindSt(c *UnwindStContext)
+
+ // ExitReadingStatement is called when exiting the readingStatement production.
+ ExitReadingStatement(c *ReadingStatementContext)
+
+ // ExitUpdatingStatement is called when exiting the updatingStatement production.
+ ExitUpdatingStatement(c *UpdatingStatementContext)
+
+ // ExitDeleteSt is called when exiting the deleteSt production.
+ ExitDeleteSt(c *DeleteStContext)
+
+ // ExitRemoveSt is called when exiting the removeSt production.
+ ExitRemoveSt(c *RemoveStContext)
+
+ // ExitRemoveItem is called when exiting the removeItem production.
+ ExitRemoveItem(c *RemoveItemContext)
+
+ // ExitQueryCallSt is called when exiting the queryCallSt production.
+ ExitQueryCallSt(c *QueryCallStContext)
+
+ // ExitParenExpressionChain is called when exiting the parenExpressionChain production.
+ ExitParenExpressionChain(c *ParenExpressionChainContext)
+
+ // ExitYieldItems is called when exiting the yieldItems production.
+ ExitYieldItems(c *YieldItemsContext)
+
+ // ExitYieldItem is called when exiting the yieldItem production.
+ ExitYieldItem(c *YieldItemContext)
+
+ // ExitMergeSt is called when exiting the mergeSt production.
+ ExitMergeSt(c *MergeStContext)
+
+ // ExitMergeAction is called when exiting the mergeAction production.
+ ExitMergeAction(c *MergeActionContext)
+
+ // ExitSetSt is called when exiting the setSt production.
+ ExitSetSt(c *SetStContext)
+
+ // ExitSetItem is called when exiting the setItem production.
+ ExitSetItem(c *SetItemContext)
+
+ // ExitNodeLabels is called when exiting the nodeLabels production.
+ ExitNodeLabels(c *NodeLabelsContext)
+
+ // ExitCreateSt is called when exiting the createSt production.
+ ExitCreateSt(c *CreateStContext)
+
+ // ExitPatternWhere is called when exiting the patternWhere production.
+ ExitPatternWhere(c *PatternWhereContext)
+
+ // ExitWhere is called when exiting the where production.
+ ExitWhere(c *WhereContext)
+
+ // ExitPattern is called when exiting the pattern production.
+ ExitPattern(c *PatternContext)
+
+ // ExitExpression is called when exiting the expression production.
+ ExitExpression(c *ExpressionContext)
+
+ // ExitXorExpression is called when exiting the xorExpression production.
+ ExitXorExpression(c *XorExpressionContext)
+
+ // ExitAndExpression is called when exiting the andExpression production.
+ ExitAndExpression(c *AndExpressionContext)
+
+ // ExitNotExpression is called when exiting the notExpression production.
+ ExitNotExpression(c *NotExpressionContext)
+
+ // ExitComparisonExpression is called when exiting the comparisonExpression production.
+ ExitComparisonExpression(c *ComparisonExpressionContext)
+
+ // ExitComparisonSigns is called when exiting the comparisonSigns production.
+ ExitComparisonSigns(c *ComparisonSignsContext)
+
+ // ExitAddSubExpression is called when exiting the addSubExpression production.
+ ExitAddSubExpression(c *AddSubExpressionContext)
+
+ // ExitMultDivExpression is called when exiting the multDivExpression production.
+ ExitMultDivExpression(c *MultDivExpressionContext)
+
+ // ExitPowerExpression is called when exiting the powerExpression production.
+ ExitPowerExpression(c *PowerExpressionContext)
+
+ // ExitUnaryAddSubExpression is called when exiting the unaryAddSubExpression production.
+ ExitUnaryAddSubExpression(c *UnaryAddSubExpressionContext)
+
+ // ExitAtomicExpression is called when exiting the atomicExpression production.
+ ExitAtomicExpression(c *AtomicExpressionContext)
+
+ // ExitListExpression is called when exiting the listExpression production.
+ ExitListExpression(c *ListExpressionContext)
+
+ // ExitStringExpression is called when exiting the stringExpression production.
+ ExitStringExpression(c *StringExpressionContext)
+
+ // ExitStringExpPrefix is called when exiting the stringExpPrefix production.
+ ExitStringExpPrefix(c *StringExpPrefixContext)
+
+ // ExitNullExpression is called when exiting the nullExpression production.
+ ExitNullExpression(c *NullExpressionContext)
+
+ // ExitPropertyOrLabelExpression is called when exiting the propertyOrLabelExpression production.
+ ExitPropertyOrLabelExpression(c *PropertyOrLabelExpressionContext)
+
+ // ExitPropertyExpression is called when exiting the propertyExpression production.
+ ExitPropertyExpression(c *PropertyExpressionContext)
+
+ // ExitPatternPart is called when exiting the patternPart production.
+ ExitPatternPart(c *PatternPartContext)
+
+ // ExitPathFunction is called when exiting the pathFunction production.
+ ExitPathFunction(c *PathFunctionContext)
+
+ // ExitPatternElem is called when exiting the patternElem production.
+ ExitPatternElem(c *PatternElemContext)
+
+ // ExitPatternElemChain is called when exiting the patternElemChain production.
+ ExitPatternElemChain(c *PatternElemChainContext)
+
+ // ExitProperties is called when exiting the properties production.
+ ExitProperties(c *PropertiesContext)
+
+ // ExitNodePattern is called when exiting the nodePattern production.
+ ExitNodePattern(c *NodePatternContext)
+
+ // ExitAtom is called when exiting the atom production.
+ ExitAtom(c *AtomContext)
+
+ // ExitLhs is called when exiting the lhs production.
+ ExitLhs(c *LhsContext)
+
+ // ExitRelationshipPattern is called when exiting the relationshipPattern production.
+ ExitRelationshipPattern(c *RelationshipPatternContext)
+
+ // ExitRelationDetail is called when exiting the relationDetail production.
+ ExitRelationDetail(c *RelationDetailContext)
+
+ // ExitRelationshipTypes is called when exiting the relationshipTypes production.
+ ExitRelationshipTypes(c *RelationshipTypesContext)
+
+ // ExitUnionSt is called when exiting the unionSt production.
+ ExitUnionSt(c *UnionStContext)
+
+ // ExitSubqueryExist is called when exiting the subqueryExist production.
+ ExitSubqueryExist(c *SubqueryExistContext)
+
+ // ExitInvocationName is called when exiting the invocationName production.
+ ExitInvocationName(c *InvocationNameContext)
+
+ // ExitFunctionInvocation is called when exiting the functionInvocation production.
+ ExitFunctionInvocation(c *FunctionInvocationContext)
+
+ // ExitParenthesizedExpression is called when exiting the parenthesizedExpression production.
+ ExitParenthesizedExpression(c *ParenthesizedExpressionContext)
+
+ // ExitFilterWith is called when exiting the filterWith production.
+ ExitFilterWith(c *FilterWithContext)
+
+ // ExitPatternComprehension is called when exiting the patternComprehension production.
+ ExitPatternComprehension(c *PatternComprehensionContext)
+
+ // ExitRelationshipsChainPattern is called when exiting the relationshipsChainPattern production.
+ ExitRelationshipsChainPattern(c *RelationshipsChainPatternContext)
+
+ // ExitListComprehension is called when exiting the listComprehension production.
+ ExitListComprehension(c *ListComprehensionContext)
+
+ // ExitFilterExpression is called when exiting the filterExpression production.
+ ExitFilterExpression(c *FilterExpressionContext)
+
+ // ExitCountAll is called when exiting the countAll production.
+ ExitCountAll(c *CountAllContext)
+
+ // ExitExpressionChain is called when exiting the expressionChain production.
+ ExitExpressionChain(c *ExpressionChainContext)
+
+ // ExitCaseExpression is called when exiting the caseExpression production.
+ ExitCaseExpression(c *CaseExpressionContext)
+
+ // ExitParameter is called when exiting the parameter production.
+ ExitParameter(c *ParameterContext)
+
+ // ExitLiteral is called when exiting the literal production.
+ ExitLiteral(c *LiteralContext)
+
+ // ExitRangeLit is called when exiting the rangeLit production.
+ ExitRangeLit(c *RangeLitContext)
+
+ // ExitBoolLit is called when exiting the boolLit production.
+ ExitBoolLit(c *BoolLitContext)
+
+ // ExitIntegerLit is called when exiting the integerLit production.
+ ExitIntegerLit(c *IntegerLitContext)
+
+ // ExitNumLit is called when exiting the numLit production.
+ ExitNumLit(c *NumLitContext)
+
+ // ExitStringLit is called when exiting the stringLit production.
+ ExitStringLit(c *StringLitContext)
+
+ // ExitCharLit is called when exiting the charLit production.
+ ExitCharLit(c *CharLitContext)
+
+ // ExitListLit is called when exiting the listLit production.
+ ExitListLit(c *ListLitContext)
+
+ // ExitMapLit is called when exiting the mapLit production.
+ ExitMapLit(c *MapLitContext)
+
+ // ExitMapPair is called when exiting the mapPair production.
+ ExitMapPair(c *MapPairContext)
+
+ // ExitName is called when exiting the name production.
+ ExitName(c *NameContext)
+
+ // ExitSymbol is called when exiting the symbol production.
+ ExitSymbol(c *SymbolContext)
+
+ // ExitReservedWord is called when exiting the reservedWord production.
+ ExitReservedWord(c *ReservedWordContext)
+}
diff --git a/nornicdb/pkg/cypher/antlr/expression.go b/nornicdb/pkg/cypher/antlr/expression.go
new file mode 100644
index 0000000..2fd3896
--- /dev/null
+++ b/nornicdb/pkg/cypher/antlr/expression.go
@@ -0,0 +1,2148 @@
+// Package antlr - Expression evaluation from AST nodes.
+// All expression evaluation walks the AST - no string parsing.
+package antlr
+
+import (
+ "fmt"
+ "reflect"
+ "strconv"
+ "strings"
+ "time"
+
+ "github.com/antlr4-go/antlr/v4"
+)
+
+// ExpressionEvaluator evaluates expressions from AST nodes
+type ExpressionEvaluator struct {
+ params map[string]interface{}
+ variables map[string]interface{}
+ row map[string]interface{} // Current row context for property lookups
+}
+
+// FunctionLookup is a callback to find custom/plugin functions by name
+// Returns the function implementation and true if found
+var FunctionLookup func(name string) (interface{}, bool)
+
+// NewExpressionEvaluator creates a new expression evaluator
+func NewExpressionEvaluator(params, variables map[string]interface{}) *ExpressionEvaluator {
+ return &ExpressionEvaluator{
+ params: params,
+ variables: variables,
+ row: make(map[string]interface{}),
+ }
+}
+
+// SetRow sets the current row context for property lookups
+func (e *ExpressionEvaluator) SetRow(row map[string]interface{}) {
+ e.row = row
+}
+
+// EvaluateWhere evaluates a WHERE expression and returns true/false
+func (e *ExpressionEvaluator) EvaluateWhere(expr IExpressionContext) bool {
+ if expr == nil {
+ return true
+ }
+
+ // Walk down the expression tree
+ // Expression -> XorExpression(s) with OR between them
+ xors := expr.AllXorExpression()
+ if len(xors) == 0 {
+ return true
+ }
+
+ // OR logic between xor expressions
+ if len(xors) > 1 {
+ for _, xor := range xors {
+ if e.evaluateXor(xor) {
+ return true
+ }
+ }
+ return false
+ }
+
+ return e.evaluateXor(xors[0])
+}
+
+// evaluateXor evaluates XOR expression from AST
+func (e *ExpressionEvaluator) evaluateXor(xor IXorExpressionContext) bool {
+ if xor == nil {
+ return true
+ }
+
+ ands := xor.AllAndExpression()
+ if len(ands) == 0 {
+ return true
+ }
+
+ if len(ands) == 1 {
+ return e.evaluateAnd(ands[0])
+ }
+
+ // XOR logic
+ result := e.evaluateAnd(ands[0])
+ for i := 1; i < len(ands); i++ {
+ result = result != e.evaluateAnd(ands[i])
+ }
+ return result
+}
+
+// evaluateAnd evaluates AND expression from AST
+func (e *ExpressionEvaluator) evaluateAnd(and IAndExpressionContext) bool {
+ if and == nil {
+ return true
+ }
+
+ nots := and.AllNotExpression()
+ if len(nots) == 0 {
+ return true
+ }
+
+ // AND logic - all must be true
+ for _, not := range nots {
+ if !e.evaluateNot(not) {
+ return false
+ }
+ }
+ return true
+}
+
+// evaluateNot evaluates NOT expression from AST
+func (e *ExpressionEvaluator) evaluateNot(not INotExpressionContext) bool {
+ if not == nil {
+ return true
+ }
+
+ // Check for NOT token
+ hasNot := not.NOT() != nil
+
+ comp := not.ComparisonExpression()
+ if comp == nil {
+ return !hasNot
+ }
+
+ result := e.evaluateComparison(comp)
+
+ if hasNot {
+ return !result
+ }
+ return result
+}
+
+// evaluateComparison evaluates comparison expression from AST
+// Grammar: comparisonExpression : addSubExpression (comparisonSigns addSubExpression)*
+func (e *ExpressionEvaluator) evaluateComparison(comp IComparisonExpressionContext) bool {
+ if comp == nil {
+ return true
+ }
+
+ adds := comp.AllAddSubExpression()
+ if len(adds) == 0 {
+ return true
+ }
+
+ // Get comparison signs
+ signs := comp.AllComparisonSigns()
+
+ // If no comparison signs, this might be a standalone boolean expression
+ // like "n.name CONTAINS 'li'" or "n.email IS NULL" or "(nested AND expression)"
+ if len(signs) == 0 {
+ // Check if this is a parenthesized expression that needs recursive evaluation
+ if parentExpr := e.findParenthesizedExprInAddSub(adds[0]); parentExpr != nil {
+ // Recursively evaluate the inner expression as a boolean
+ return e.EvaluateWhere(parentExpr)
+ }
+
+ // Check if this is an atomic expression with string/list/null predicates
+ atomic := e.findAtomicInAddSub(adds[0])
+ if atomic != nil {
+ if result, handled := e.evaluateAtomicAsBool(atomic); handled {
+ return result
+ }
+ }
+ // Fall back to truthiness check
+ leftVal := e.evaluateAddSub(adds[0])
+ return e.isTruthy(leftVal)
+ }
+
+ // Get left value
+ leftVal := e.evaluateAddSub(adds[0])
+
+ // Evaluate each comparison
+ currentLeft := leftVal
+ for i, sign := range signs {
+ if i+1 >= len(adds) {
+ break
+ }
+ rightVal := e.evaluateAddSub(adds[i+1])
+
+ // Check comparison operator from AST tokens
+ result := e.evaluateComparisonSign(currentLeft, sign, rightVal)
+ if !result {
+ return false
+ }
+
+ // Chain comparisons: a < b < c means a < b AND b < c
+ currentLeft = rightVal
+ }
+
+ return true
+}
+
+// findAtomicInAddSub walks down to find the AtomicExpression
+func (e *ExpressionEvaluator) findAtomicInAddSub(add IAddSubExpressionContext) IAtomicExpressionContext {
+ if add == nil {
+ return nil
+ }
+
+ mults := add.AllMultDivExpression()
+ if len(mults) != 1 {
+ return nil
+ }
+
+ powers := mults[0].AllPowerExpression()
+ if len(powers) != 1 {
+ return nil
+ }
+
+ unarys := powers[0].AllUnaryAddSubExpression()
+ if len(unarys) != 1 {
+ return nil
+ }
+
+ return unarys[0].AtomicExpression()
+}
+
+// findParenthesizedExprInAddSub walks down to find a parenthesized expression that contains a nested boolean
+func (e *ExpressionEvaluator) findParenthesizedExprInAddSub(add IAddSubExpressionContext) IExpressionContext {
+ atomic := e.findAtomicInAddSub(add)
+ if atomic == nil {
+ return nil
+ }
+
+ propOrLabel := atomic.PropertyOrLabelExpression()
+ if propOrLabel == nil {
+ return nil
+ }
+
+ propExpr := propOrLabel.PropertyExpression()
+ if propExpr == nil {
+ return nil
+ }
+
+ atom := propExpr.Atom()
+ if atom == nil {
+ return nil
+ }
+
+ paren := atom.ParenthesizedExpression()
+ if paren == nil {
+ return nil
+ }
+
+ return paren.Expression()
+}
+
+// evaluateComparisonSign evaluates a comparison sign from AST tokens
+func (e *ExpressionEvaluator) evaluateComparisonSign(leftVal interface{}, sign IComparisonSignsContext, rightVal interface{}) bool {
+ if sign == nil {
+ return true
+ }
+
+ // Check comparison operators using AST tokens
+ if sign.ASSIGN() != nil { // =
+ return e.valuesEqual(leftVal, rightVal)
+ }
+ if sign.NOT_EQUAL() != nil { // <> or !=
+ return !e.valuesEqual(leftVal, rightVal)
+ }
+ if sign.LT() != nil { // <
+ return e.compareValues(leftVal, rightVal) < 0
+ }
+ if sign.GT() != nil { // >
+ return e.compareValues(leftVal, rightVal) > 0
+ }
+ if sign.LE() != nil { // <=
+ return e.compareValues(leftVal, rightVal) <= 0
+ }
+ if sign.GE() != nil { // >=
+ return e.compareValues(leftVal, rightVal) >= 0
+ }
+
+ return true
+}
+
+// evaluateAddSub evaluates an AddSubExpression
+func (e *ExpressionEvaluator) evaluateAddSub(add IAddSubExpressionContext) interface{} {
+ if add == nil {
+ return nil
+ }
+
+ mults := add.AllMultDivExpression()
+ if len(mults) == 0 {
+ return nil
+ }
+
+ if len(mults) == 1 {
+ return e.evaluateMultDiv(mults[0])
+ }
+
+ // Handle + and - operations
+ result := e.toFloat64(e.evaluateMultDiv(mults[0]))
+ // Check for PLUS/SUB tokens between expressions
+ plusTokens := add.AllPLUS()
+ subTokens := add.AllSUB()
+
+ for i := 1; i < len(mults); i++ {
+ val := e.toFloat64(e.evaluateMultDiv(mults[i]))
+ // Simple heuristic: if we have SUB tokens, treat as subtraction
+ if len(subTokens) > 0 && i <= len(subTokens) {
+ result -= val
+ } else {
+ result += val
+ }
+ }
+ _ = plusTokens // Used for type checking
+ return maybeInt64(result)
+}
+
+// evaluateMultDiv evaluates a MultDivExpression
+func (e *ExpressionEvaluator) evaluateMultDiv(mult IMultDivExpressionContext) interface{} {
+ if mult == nil {
+ return nil
+ }
+
+ powers := mult.AllPowerExpression()
+ if len(powers) == 0 {
+ return nil
+ }
+
+ if len(powers) == 1 {
+ return e.evaluatePower(powers[0])
+ }
+
+ result := e.toFloat64(e.evaluatePower(powers[0]))
+
+ // Get operator tokens in order from children
+ children := mult.GetChildren()
+ opIndex := 0
+
+ for i := 1; i < len(powers); i++ {
+ val := e.toFloat64(e.evaluatePower(powers[i]))
+
+ // Find the operator between powers[i-1] and powers[i]
+ for opIndex < len(children) {
+ child := children[opIndex]
+ opIndex++
+ if term, ok := child.(antlr.TerminalNode); ok {
+ tokenType := term.GetSymbol().GetTokenType()
+ switch tokenType {
+ case CypherParserMULT:
+ result *= val
+ goto nextPower
+ case CypherParserDIV:
+ if val != 0 {
+ result /= val
+ }
+ goto nextPower
+ case CypherParserMOD:
+ if val != 0 {
+ result = float64(int64(result) % int64(val))
+ }
+ goto nextPower
+ }
+ }
+ }
+ nextPower:
+ }
+ return maybeInt64(result)
+}
+
+// evaluatePower evaluates a PowerExpression
+func (e *ExpressionEvaluator) evaluatePower(power IPowerExpressionContext) interface{} {
+ if power == nil {
+ return nil
+ }
+
+ unarys := power.AllUnaryAddSubExpression()
+ if len(unarys) == 0 {
+ return nil
+ }
+
+ return e.evaluateUnary(unarys[0])
+}
+
+// evaluateUnary evaluates a UnaryAddSubExpression
+func (e *ExpressionEvaluator) evaluateUnary(unary IUnaryAddSubExpressionContext) interface{} {
+ if unary == nil {
+ return nil
+ }
+
+ // Check for unary minus
+ hasMinus := unary.SUB() != nil
+
+ atomic := unary.AtomicExpression()
+ if atomic == nil {
+ return nil
+ }
+
+ val := e.evaluateAtomic(atomic)
+
+ if hasMinus {
+ return -e.toFloat64(val)
+ }
+ return val
+}
+
+// evaluateAtomic evaluates an AtomicExpression
+// Grammar: atomicExpression : propertyOrLabelExpression (stringExpression | listExpression | nullExpression)*
+func (e *ExpressionEvaluator) evaluateAtomic(atomic IAtomicExpressionContext) interface{} {
+ if atomic == nil {
+ return nil
+ }
+
+ propOrLabel := atomic.PropertyOrLabelExpression()
+ if propOrLabel == nil {
+ return nil
+ }
+
+ baseVal := e.evaluatePropertyOrLabel(propOrLabel)
+
+ // Check for NullExpression (IS NULL / IS NOT NULL)
+ // Returns boolean true/false for the null check
+ nullExprs := atomic.AllNullExpression()
+ if len(nullExprs) > 0 {
+ for _, nullExpr := range nullExprs {
+ isNot := nullExpr.NOT() != nil
+ if isNot {
+ // IS NOT NULL - true if value is not null
+ return baseVal != nil
+ } else {
+ // IS NULL - true if value is null
+ return baseVal == nil
+ }
+ }
+ }
+
+ // Check for StringExpression (STARTS WITH, ENDS WITH, CONTAINS)
+ strExprs := atomic.AllStringExpression()
+ if len(strExprs) > 0 {
+ for _, strExpr := range strExprs {
+ prefix := strExpr.StringExpPrefix()
+ if prefix == nil {
+ continue
+ }
+ operand := strExpr.PropertyOrLabelExpression()
+ if operand == nil {
+ continue
+ }
+ operandVal := e.evaluatePropertyOrLabel(operand)
+
+ baseStr, baseOk := baseVal.(string)
+ operandStr, operandOk := operandVal.(string)
+ if !baseOk || !operandOk {
+ return false
+ }
+
+ if prefix.STARTS() != nil {
+ return strings.HasPrefix(baseStr, operandStr)
+ } else if prefix.ENDS() != nil {
+ return strings.HasSuffix(baseStr, operandStr)
+ } else if prefix.CONTAINS() != nil {
+ return strings.Contains(baseStr, operandStr)
+ }
+ }
+ }
+
+ // Check for ListExpression (IN list)
+ listExprs := atomic.AllListExpression()
+ if len(listExprs) > 0 {
+ for _, listExpr := range listExprs {
+ if listExpr.IN() != nil {
+ listPropOrLabel := listExpr.PropertyOrLabelExpression()
+ if listPropOrLabel != nil {
+ listVal := e.evaluatePropertyOrLabel(listPropOrLabel)
+ if list, ok := listVal.([]interface{}); ok {
+ for _, item := range list {
+ if e.valuesEqual(baseVal, item) {
+ return true
+ }
+ }
+ }
+ return false
+ }
+ }
+ }
+ }
+
+ return baseVal
+}
+
+// evaluateAtomicAsBool evaluates atomic expression as boolean (for WHERE)
+// Handles IS NULL, IS NOT NULL, IN list, STARTS WITH, ENDS WITH, CONTAINS
+func (e *ExpressionEvaluator) evaluateAtomicAsBool(atomic IAtomicExpressionContext) (bool, bool) {
+ if atomic == nil {
+ return true, false // No constraint, not handled
+ }
+
+ propOrLabel := atomic.PropertyOrLabelExpression()
+ if propOrLabel == nil {
+ return true, false
+ }
+
+ baseVal := e.evaluatePropertyOrLabel(propOrLabel)
+
+ // Check for NullExpression (IS NULL / IS NOT NULL)
+ nullExprs := atomic.AllNullExpression()
+ if len(nullExprs) > 0 {
+ for _, nullExpr := range nullExprs {
+ isNot := nullExpr.NOT() != nil
+ if isNot {
+ if baseVal == nil {
+ return false, true // IS NOT NULL but value is null
+ }
+ } else {
+ if baseVal != nil {
+ return false, true // IS NULL but value is not null
+ }
+ }
+ }
+ return true, true
+ }
+
+ // Check for StringExpression (STARTS WITH, ENDS WITH, CONTAINS)
+ strExprs := atomic.AllStringExpression()
+ if len(strExprs) > 0 {
+ for _, strExpr := range strExprs {
+ prefix := strExpr.StringExpPrefix()
+ if prefix == nil {
+ continue
+ }
+ operand := strExpr.PropertyOrLabelExpression()
+ if operand == nil {
+ continue
+ }
+ operandVal := e.evaluatePropertyOrLabel(operand)
+
+ baseStr, baseOk := baseVal.(string)
+ operandStr, operandOk := operandVal.(string)
+ if !baseOk || !operandOk {
+ return false, true
+ }
+
+ if prefix.STARTS() != nil { // STARTS WITH
+ if len(baseStr) < len(operandStr) || baseStr[:len(operandStr)] != operandStr {
+ return false, true
+ }
+ }
+ if prefix.ENDS() != nil { // ENDS WITH
+ if len(baseStr) < len(operandStr) || baseStr[len(baseStr)-len(operandStr):] != operandStr {
+ return false, true
+ }
+ }
+ if prefix.CONTAINS() != nil { // CONTAINS
+ found := false
+ for i := 0; i <= len(baseStr)-len(operandStr); i++ {
+ if baseStr[i:i+len(operandStr)] == operandStr {
+ found = true
+ break
+ }
+ }
+ if !found {
+ return false, true
+ }
+ }
+ }
+ return true, true
+ }
+
+ // Check for ListExpression (IN list)
+ listExprs := atomic.AllListExpression()
+ if len(listExprs) > 0 {
+ for _, listExpr := range listExprs {
+ if listExpr.IN() != nil {
+ operand := listExpr.PropertyOrLabelExpression()
+ if operand == nil {
+ continue
+ }
+ listVal := e.evaluatePropertyOrLabel(operand)
+ if list, ok := listVal.([]interface{}); ok {
+ found := false
+ for _, item := range list {
+ if e.valuesEqual(baseVal, item) {
+ found = true
+ break
+ }
+ }
+ if !found {
+ return false, true
+ }
+ }
+ }
+ }
+ return true, true
+ }
+
+ return true, false // Not handled as bool
+}
+
+// evaluatePropertyOrLabel evaluates property access from AST
+func (e *ExpressionEvaluator) evaluatePropertyOrLabel(propOrLabel IPropertyOrLabelExpressionContext) interface{} {
+ if propOrLabel == nil {
+ return nil
+ }
+
+ propExpr := propOrLabel.PropertyExpression()
+ if propExpr == nil {
+ return nil
+ }
+
+ atom := propExpr.Atom()
+ if atom == nil {
+ return nil
+ }
+
+ baseVal := e.evaluateAtom(atom)
+
+ // Check for property access via DOT tokens
+ dots := propExpr.AllDOT()
+ if len(dots) == 0 {
+ return baseVal
+ }
+
+ // Get property names from Name nodes
+ names := propExpr.AllName()
+ currentVal := baseVal
+ for _, name := range names {
+ propName := name.GetText()
+ if nodeMap, ok := currentVal.(map[string]interface{}); ok {
+ currentVal = nodeMap[propName]
+ } else {
+ return nil
+ }
+ }
+
+ return currentVal
+}
+
+// evaluateAtom evaluates an Atom
+func (e *ExpressionEvaluator) evaluateAtom(atom IAtomContext) interface{} {
+ if atom == nil {
+ return nil
+ }
+
+ // Check for COUNT(*)
+ if countAll := atom.CountAll(); countAll != nil {
+ // This is COUNT(*) - handled specially in aggregation
+ return "COUNT(*)"
+ }
+
+ // Check for literal
+ if lit := atom.Literal(); lit != nil {
+ return e.evaluateLiteral(lit)
+ }
+
+ // Check for parameter
+ if param := atom.Parameter(); param != nil {
+ if sym := param.Symbol(); sym != nil {
+ if val, ok := e.params[sym.GetText()]; ok {
+ return val
+ }
+ }
+ return nil
+ }
+
+ // Check for symbol (variable reference)
+ if sym := atom.Symbol(); sym != nil {
+ varName := sym.GetText()
+ if val, ok := e.row[varName]; ok {
+ return val
+ }
+ if val, ok := e.variables[varName]; ok {
+ return val
+ }
+ return nil
+ }
+
+ // Check for function invocation
+ if funcInvoc := atom.FunctionInvocation(); funcInvoc != nil {
+ return e.evaluateFunctionInvocation(funcInvoc)
+ }
+
+ // Check for parenthesized expression
+ if paren := atom.ParenthesizedExpression(); paren != nil {
+ if innerExpr := paren.Expression(); innerExpr != nil {
+ return e.Evaluate(innerExpr)
+ }
+ }
+
+ // List and Map literals are handled in Literal, not directly in Atom
+
+ return nil
+}
+
+// evaluateLiteral evaluates a literal from AST
+func (e *ExpressionEvaluator) evaluateLiteral(lit ILiteralContext) interface{} {
+ if lit == nil {
+ return nil
+ }
+
+ // Boolean - check AST tokens
+ if boolLit := lit.BoolLit(); boolLit != nil {
+ if boolLit.TRUE() != nil {
+ return true
+ }
+ return false
+ }
+
+ // Null - check AST token
+ if lit.NULL_W() != nil {
+ return nil
+ }
+
+ // Number
+ if numLit := lit.NumLit(); numLit != nil {
+ if floatLit := numLit.FLOAT(); floatLit != nil {
+ if f, err := strconv.ParseFloat(floatLit.GetText(), 64); err == nil {
+ return f
+ }
+ }
+ if intLit := numLit.IntegerLit(); intLit != nil {
+ if i, err := strconv.ParseInt(intLit.GetText(), 10, 64); err == nil {
+ return i
+ }
+ }
+ }
+
+ // String - get text and remove quotes
+ if strLit := lit.StringLit(); strLit != nil {
+ text := strLit.GetText()
+ if len(text) >= 2 {
+ return text[1 : len(text)-1]
+ }
+ return text
+ }
+
+ // Char
+ if charLit := lit.CharLit(); charLit != nil {
+ text := charLit.GetText()
+ if len(text) >= 2 {
+ return text[1 : len(text)-1]
+ }
+ return text
+ }
+
+ // List
+ if listLit := lit.ListLit(); listLit != nil {
+ if exprChain := listLit.ExpressionChain(); exprChain != nil {
+ var result []interface{}
+ for _, expr := range exprChain.AllExpression() {
+ result = append(result, e.Evaluate(expr))
+ }
+ return result
+ }
+ return []interface{}{}
+ }
+
+ // Map
+ if mapLit := lit.MapLit(); mapLit != nil {
+ result := make(map[string]interface{})
+ for _, pair := range mapLit.AllMapPair() {
+ if name := pair.Name(); name != nil {
+ if expr := pair.Expression(); expr != nil {
+ result[name.GetText()] = e.Evaluate(expr)
+ }
+ }
+ }
+ return result
+ }
+
+ return nil
+}
+
+// evaluateFunctionInvocation evaluates a function call
+func (e *ExpressionEvaluator) evaluateFunctionInvocation(funcInvoc IFunctionInvocationContext) interface{} {
+ if funcInvoc == nil {
+ return nil
+ }
+
+ // Get function name
+ invocName := funcInvoc.InvocationName()
+ if invocName == nil {
+ return nil
+ }
+
+ // Get arguments
+ var args []interface{}
+ if exprChain := funcInvoc.ExpressionChain(); exprChain != nil {
+ for _, expr := range exprChain.AllExpression() {
+ args = append(args, e.Evaluate(expr))
+ }
+ }
+
+ // Get function name from symbols
+ symbols := invocName.AllSymbol()
+ if len(symbols) == 0 {
+ return nil
+ }
+
+ // Check for aggregation functions by token type
+ firstSym := symbols[0]
+
+ // COUNT token
+ if firstSym.COUNT() != nil {
+ // Aggregation - return marker
+ return &AggregationMarker{FuncName: "COUNT", Args: args}
+ }
+
+ // SUM token
+ if firstSym.SUM() != nil {
+ return &AggregationMarker{FuncName: "SUM", Args: args}
+ }
+
+ // AVG token
+ if firstSym.AVG() != nil {
+ return &AggregationMarker{FuncName: "AVG", Args: args}
+ }
+
+ // MIN token
+ if firstSym.MIN() != nil {
+ return &AggregationMarker{FuncName: "MIN", Args: args}
+ }
+
+ // MAX token
+ if firstSym.MAX() != nil {
+ return &AggregationMarker{FuncName: "MAX", Args: args}
+ }
+
+ // COLLECT token
+ if firstSym.COLLECT() != nil {
+ return &AggregationMarker{FuncName: "COLLECT", Args: args}
+ }
+
+ // Build full function name (may have multiple parts like "apoc.coll.sum")
+ var funcNameParts []string
+ for _, sym := range symbols {
+ funcNameParts = append(funcNameParts, sym.GetText())
+ }
+ funcName := strings.Join(funcNameParts, ".")
+
+ // Try to call plugin/custom function
+ if FunctionLookup != nil {
+ if fn, found := FunctionLookup(funcName); found {
+ return e.callPluginFunction(fn, args)
+ }
+ }
+
+ // Built-in functions
+ return e.evaluateBuiltInFunction(funcName, args)
+}
+
+// callPluginFunction calls a plugin function with the given arguments
+func (e *ExpressionEvaluator) callPluginFunction(fn interface{}, args []interface{}) interface{} {
+ // fn should be a function that takes []interface{} and returns interface{}
+ switch f := fn.(type) {
+ case func([]interface{}) interface{}:
+ return f(args)
+ case func(...interface{}) interface{}:
+ return f(args...)
+ }
+
+ // Use reflection for other function signatures
+ fnValue := reflect.ValueOf(fn)
+ if fnValue.Kind() != reflect.Func {
+ return nil
+ }
+
+ fnType := fnValue.Type()
+ numIn := fnType.NumIn()
+
+ // Build argument values
+ inArgs := make([]reflect.Value, numIn)
+ for i := 0; i < numIn; i++ {
+ paramType := fnType.In(i)
+
+ var arg interface{}
+ if i < len(args) {
+ arg = args[i]
+ }
+
+ // Convert arg to the expected type
+ argValue := convertToType(arg, paramType)
+ if !argValue.IsValid() {
+ argValue = reflect.Zero(paramType)
+ }
+ inArgs[i] = argValue
+ }
+
+ // Call the function
+ results := fnValue.Call(inArgs)
+ if len(results) > 0 {
+ return results[0].Interface()
+ }
+ return nil
+}
+
+// convertToType converts a value to the specified reflect.Type
+func convertToType(val interface{}, targetType reflect.Type) reflect.Value {
+ if val == nil {
+ return reflect.Zero(targetType)
+ }
+
+ srcValue := reflect.ValueOf(val)
+ srcType := srcValue.Type()
+
+ // If types match directly
+ if srcType == targetType || srcType.AssignableTo(targetType) {
+ return srcValue
+ }
+
+ // Convertible types
+ if srcType.ConvertibleTo(targetType) {
+ return srcValue.Convert(targetType)
+ }
+
+ // Handle numeric conversions
+ switch targetType.Kind() {
+ case reflect.Float64:
+ switch v := val.(type) {
+ case int64:
+ return reflect.ValueOf(float64(v))
+ case int:
+ return reflect.ValueOf(float64(v))
+ case float32:
+ return reflect.ValueOf(float64(v))
+ case float64:
+ return reflect.ValueOf(v)
+ }
+ case reflect.Int64:
+ switch v := val.(type) {
+ case float64:
+ return reflect.ValueOf(int64(v))
+ case int:
+ return reflect.ValueOf(int64(v))
+ case int64:
+ return reflect.ValueOf(v)
+ }
+ case reflect.Int:
+ switch v := val.(type) {
+ case float64:
+ return reflect.ValueOf(int(v))
+ case int64:
+ return reflect.ValueOf(int(v))
+ case int:
+ return reflect.ValueOf(v)
+ }
+ }
+
+ return reflect.Zero(targetType)
+}
+
+// evaluateBuiltInFunction evaluates built-in functions by name
+func (e *ExpressionEvaluator) evaluateBuiltInFunction(name string, args []interface{}) interface{} {
+ nameLower := strings.ToLower(name)
+
+ switch nameLower {
+ case "tostring":
+ if len(args) > 0 {
+ return fmt.Sprintf("%v", args[0])
+ }
+ case "tointeger", "toint":
+ if len(args) > 0 {
+ return e.toInt64(args[0])
+ }
+ case "tofloat":
+ if len(args) > 0 {
+ return e.toFloat64(args[0])
+ }
+ case "toboolean":
+ if len(args) > 0 {
+ return e.toBool(args[0])
+ }
+ case "size", "length":
+ if len(args) > 0 {
+ return e.size(args[0])
+ }
+ case "head":
+ if len(args) > 0 {
+ if list, ok := args[0].([]interface{}); ok && len(list) > 0 {
+ return list[0]
+ }
+ }
+ case "tail":
+ if len(args) > 0 {
+ if list, ok := args[0].([]interface{}); ok && len(list) > 1 {
+ return list[1:]
+ }
+ }
+ case "last":
+ if len(args) > 0 {
+ if list, ok := args[0].([]interface{}); ok && len(list) > 0 {
+ return list[len(list)-1]
+ }
+ }
+ case "reverse":
+ if len(args) > 0 {
+ if list, ok := args[0].([]interface{}); ok {
+ reversed := make([]interface{}, len(list))
+ for i, v := range list {
+ reversed[len(list)-1-i] = v
+ }
+ return reversed
+ }
+ }
+ case "range":
+ if len(args) >= 2 {
+ start := int(e.toFloat64(args[0]))
+ end := int(e.toFloat64(args[1]))
+ step := 1
+ if len(args) >= 3 {
+ step = int(e.toFloat64(args[2]))
+ }
+ if step == 0 {
+ step = 1
+ }
+ var result []interface{}
+ if step > 0 {
+ for i := start; i <= end; i += step {
+ result = append(result, int64(i))
+ }
+ } else {
+ for i := start; i >= end; i += step {
+ result = append(result, int64(i))
+ }
+ }
+ return result
+ }
+ case "coalesce":
+ for _, arg := range args {
+ if arg != nil {
+ return arg
+ }
+ }
+ case "abs":
+ if len(args) > 0 {
+ v := e.toFloat64(args[0])
+ if v < 0 {
+ v = -v
+ }
+ return maybeInt64(v)
+ }
+ case "ceil":
+ if len(args) > 0 {
+ return int64(e.toFloat64(args[0]) + 0.999999999)
+ }
+ case "floor":
+ if len(args) > 0 {
+ return int64(e.toFloat64(args[0]))
+ }
+ case "round":
+ if len(args) > 0 {
+ v := e.toFloat64(args[0])
+ return int64(v + 0.5)
+ }
+ case "trim":
+ if len(args) > 0 {
+ return strings.TrimSpace(fmt.Sprintf("%v", args[0]))
+ }
+ case "ltrim":
+ if len(args) > 0 {
+ return strings.TrimLeft(fmt.Sprintf("%v", args[0]), " \t\n\r")
+ }
+ case "rtrim":
+ if len(args) > 0 {
+ return strings.TrimRight(fmt.Sprintf("%v", args[0]), " \t\n\r")
+ }
+ case "toupper":
+ if len(args) > 0 {
+ return strings.ToUpper(fmt.Sprintf("%v", args[0]))
+ }
+ case "tolower":
+ if len(args) > 0 {
+ return strings.ToLower(fmt.Sprintf("%v", args[0]))
+ }
+ case "replace":
+ if len(args) >= 3 {
+ s := fmt.Sprintf("%v", args[0])
+ old := fmt.Sprintf("%v", args[1])
+ new := fmt.Sprintf("%v", args[2])
+ return strings.ReplaceAll(s, old, new)
+ }
+ case "substring":
+ if len(args) >= 2 {
+ s := fmt.Sprintf("%v", args[0])
+ start := int(e.toFloat64(args[1]))
+ if start < 0 {
+ start = 0
+ }
+ if start >= len(s) {
+ return ""
+ }
+ if len(args) >= 3 {
+ length := int(e.toFloat64(args[2]))
+ if start+length > len(s) {
+ length = len(s) - start
+ }
+ return s[start : start+length]
+ }
+ return s[start:]
+ }
+ case "left":
+ if len(args) >= 2 {
+ s := fmt.Sprintf("%v", args[0])
+ n := int(e.toFloat64(args[1]))
+ if n >= len(s) {
+ return s
+ }
+ return s[:n]
+ }
+ case "right":
+ if len(args) >= 2 {
+ s := fmt.Sprintf("%v", args[0])
+ n := int(e.toFloat64(args[1]))
+ if n >= len(s) {
+ return s
+ }
+ return s[len(s)-n:]
+ }
+ case "split":
+ if len(args) >= 2 {
+ s := fmt.Sprintf("%v", args[0])
+ sep := fmt.Sprintf("%v", args[1])
+ parts := strings.Split(s, sep)
+ result := make([]interface{}, len(parts))
+ for i, p := range parts {
+ result[i] = p
+ }
+ return result
+ }
+ // APOC-like collection functions
+ case "apoc.coll.sum":
+ if len(args) > 0 {
+ if list, ok := args[0].([]interface{}); ok {
+ sum := float64(0)
+ for _, v := range list {
+ sum += e.toFloat64(v)
+ }
+ return maybeInt64(sum)
+ }
+ }
+ case "apoc.coll.avg":
+ if len(args) > 0 {
+ if list, ok := args[0].([]interface{}); ok && len(list) > 0 {
+ sum := float64(0)
+ for _, v := range list {
+ sum += e.toFloat64(v)
+ }
+ return sum / float64(len(list))
+ }
+ }
+ case "apoc.coll.min":
+ if len(args) > 0 {
+ if list, ok := args[0].([]interface{}); ok && len(list) > 0 {
+ min := e.toFloat64(list[0])
+ for _, v := range list[1:] {
+ val := e.toFloat64(v)
+ if val < min {
+ min = val
+ }
+ }
+ return maybeInt64(min)
+ }
+ }
+ case "apoc.coll.max":
+ if len(args) > 0 {
+ if list, ok := args[0].([]interface{}); ok && len(list) > 0 {
+ max := e.toFloat64(list[0])
+ for _, v := range list[1:] {
+ val := e.toFloat64(v)
+ if val > max {
+ max = val
+ }
+ }
+ return maybeInt64(max)
+ }
+ }
+ case "apoc.coll.reverse":
+ if len(args) > 0 {
+ if list, ok := args[0].([]interface{}); ok {
+ reversed := make([]interface{}, len(list))
+ for i, v := range list {
+ reversed[len(list)-1-i] = v
+ }
+ return reversed
+ }
+ }
+
+ // Graph element functions
+ case "type":
+ // type(relationship) - returns the type of a relationship
+ if len(args) > 0 {
+ if relMap, ok := args[0].(map[string]interface{}); ok {
+ if t, ok := relMap["_type"]; ok {
+ return t
+ }
+ }
+ }
+ return nil
+
+ case "id":
+ // id(node) or id(relationship) - returns the internal ID
+ if len(args) > 0 {
+ if nodeMap, ok := args[0].(map[string]interface{}); ok {
+ if id, ok := nodeMap["_nodeId"]; ok {
+ return id
+ }
+ if id, ok := nodeMap["_edgeId"]; ok {
+ return id
+ }
+ }
+ }
+ return nil
+
+ case "labels":
+ // labels(node) - returns labels of a node
+ if len(args) > 0 {
+ if nodeMap, ok := args[0].(map[string]interface{}); ok {
+ if labels, ok := nodeMap["_labels"]; ok {
+ return labels
+ }
+ }
+ }
+ return nil
+
+ case "keys":
+ // keys(map or node) - returns keys of a map/node properties
+ if len(args) > 0 {
+ if m, ok := args[0].(map[string]interface{}); ok {
+ var keys []interface{}
+ for k := range m {
+ // Skip internal properties
+ if !strings.HasPrefix(k, "_") {
+ keys = append(keys, k)
+ }
+ }
+ return keys
+ }
+ }
+ return nil
+
+ case "properties":
+ // properties(node or relationship) - returns properties as map
+ if len(args) > 0 {
+ if m, ok := args[0].(map[string]interface{}); ok {
+ props := make(map[string]interface{})
+ for k, v := range m {
+ // Skip internal properties
+ if !strings.HasPrefix(k, "_") {
+ props[k] = v
+ }
+ }
+ return props
+ }
+ }
+ return nil
+
+ case "timestamp":
+ // timestamp() - returns current timestamp in milliseconds
+ return time.Now().UnixMilli()
+
+ case "date":
+ // date() - returns current date as string
+ return time.Now().Format("2006-01-02")
+
+ case "datetime":
+ // datetime() - returns current datetime as string
+ return time.Now().Format(time.RFC3339)
+
+ case "exists":
+ // exists(property) - returns true if property exists and is not null
+ if len(args) > 0 {
+ return args[0] != nil
+ }
+ return false
+ }
+
+ return nil
+}
+
+// toInt64 converts a value to int64
+func (e *ExpressionEvaluator) toInt64(val interface{}) int64 {
+ switch v := val.(type) {
+ case int64:
+ return v
+ case int:
+ return int64(v)
+ case float64:
+ return int64(v)
+ case float32:
+ return int64(v)
+ case string:
+ if i, err := strconv.ParseInt(v, 10, 64); err == nil {
+ return i
+ }
+ }
+ return 0
+}
+
+// toBool converts a value to bool
+func (e *ExpressionEvaluator) toBool(val interface{}) bool {
+ switch v := val.(type) {
+ case bool:
+ return v
+ case string:
+ return strings.ToLower(v) == "true"
+ case int64:
+ return v != 0
+ case float64:
+ return v != 0
+ }
+ return false
+}
+
+// size returns the size/length of a value
+func (e *ExpressionEvaluator) size(val interface{}) int64 {
+ switch v := val.(type) {
+ case []interface{}:
+ return int64(len(v))
+ case string:
+ return int64(len(v))
+ case map[string]interface{}:
+ return int64(len(v))
+ }
+ return 0
+}
+
+// Evaluate evaluates any expression and returns its value
+func (e *ExpressionEvaluator) Evaluate(expr IExpressionContext) interface{} {
+ if expr == nil {
+ return nil
+ }
+
+ xors := expr.AllXorExpression()
+ if len(xors) != 1 {
+ return nil
+ }
+
+ ands := xors[0].AllAndExpression()
+ if len(ands) != 1 {
+ return nil
+ }
+
+ nots := ands[0].AllNotExpression()
+ if len(nots) != 1 {
+ return nil
+ }
+
+ comp := nots[0].ComparisonExpression()
+ if comp == nil {
+ return nil
+ }
+
+ adds := comp.AllAddSubExpression()
+ if len(adds) != 1 {
+ return nil
+ }
+
+ return e.evaluateAddSub(adds[0])
+}
+
+// AggregationMarker marks an aggregation function for later processing
+type AggregationMarker struct {
+ FuncName string
+ Args []interface{}
+ Distinct bool
+}
+
+// IsAggregation checks if a value is an aggregation marker
+func IsAggregation(val interface{}) (*AggregationMarker, bool) {
+ if marker, ok := val.(*AggregationMarker); ok {
+ return marker, true
+ }
+ return nil, false
+}
+
+// Helper functions
+
+func (e *ExpressionEvaluator) isTruthy(val interface{}) bool {
+ if val == nil {
+ return false
+ }
+ switch v := val.(type) {
+ case bool:
+ return v
+ case int64:
+ return v != 0
+ case float64:
+ return v != 0
+ case string:
+ return v != ""
+ }
+ return true
+}
+
+func (e *ExpressionEvaluator) valuesEqual(a, b interface{}) bool {
+ switch av := a.(type) {
+ case int64:
+ switch bv := b.(type) {
+ case int64:
+ return av == bv
+ case float64:
+ return float64(av) == bv
+ case int:
+ return av == int64(bv)
+ }
+ case float64:
+ switch bv := b.(type) {
+ case float64:
+ return av == bv
+ case int64:
+ return av == float64(bv)
+ case int:
+ return av == float64(bv)
+ }
+ case string:
+ if bv, ok := b.(string); ok {
+ return av == bv
+ }
+ case bool:
+ if bv, ok := b.(bool); ok {
+ return av == bv
+ }
+ }
+ return false
+}
+
+func (e *ExpressionEvaluator) compareValues(a, b interface{}) int {
+ aNum, aIsNum := e.toNumericOk(a)
+ bNum, bIsNum := e.toNumericOk(b)
+ if aIsNum && bIsNum {
+ if aNum < bNum {
+ return -1
+ } else if aNum > bNum {
+ return 1
+ }
+ return 0
+ }
+
+ // String comparison fallback
+ aStr, aOk := a.(string)
+ bStr, bOk := b.(string)
+ if aOk && bOk {
+ if aStr < bStr {
+ return -1
+ } else if aStr > bStr {
+ return 1
+ }
+ return 0
+ }
+
+ return 0
+}
+
+func (e *ExpressionEvaluator) toFloat64(val interface{}) float64 {
+ switch v := val.(type) {
+ case int64:
+ return float64(v)
+ case int:
+ return float64(v)
+ case float64:
+ return v
+ case float32:
+ return float64(v)
+ }
+ return 0
+}
+
+func (e *ExpressionEvaluator) toNumericOk(val interface{}) (float64, bool) {
+ switch v := val.(type) {
+ case int64:
+ return float64(v), true
+ case int:
+ return float64(v), true
+ case float64:
+ return v, true
+ case float32:
+ return float64(v), true
+ }
+ return 0, false
+}
+
+// maybeInt64 returns int64 if the float64 is a whole number, otherwise returns float64
+func maybeInt64(f float64) interface{} {
+ if f == float64(int64(f)) {
+ return int64(f)
+ }
+ return f
+}
+
+// ExtractPropertyAccess extracts variable and property name from a property expression AST
+func ExtractPropertyAccess(propExpr IPropertyExpressionContext) (varName string, propNames []string) {
+ if propExpr == nil {
+ return "", nil
+ }
+
+ atom := propExpr.Atom()
+ if atom == nil {
+ return "", nil
+ }
+
+ // Get variable name from symbol
+ if sym := atom.Symbol(); sym != nil {
+ varName = sym.GetText()
+ }
+
+ // Get property names from DOT accesses
+ for _, name := range propExpr.AllName() {
+ propNames = append(propNames, name.GetText())
+ }
+
+ return varName, propNames
+}
+
+// NodePatternInfo holds extracted node pattern info from AST
+type NodePatternInfo struct {
+ Variable string
+ Labels []string
+ Properties map[string]interface{}
+}
+
+// ExtractNodePattern extracts node pattern info from AST
+func ExtractNodePattern(node INodePatternContext, eval *ExpressionEvaluator) NodePatternInfo {
+ info := NodePatternInfo{
+ Properties: make(map[string]interface{}),
+ }
+
+ if node == nil {
+ return info
+ }
+
+ // Get variable from Symbol AST node
+ if sym := node.Symbol(); sym != nil {
+ info.Variable = sym.GetText()
+ }
+
+ // Get labels from NodeLabels AST node
+ if nodeLabels := node.NodeLabels(); nodeLabels != nil {
+ for _, name := range nodeLabels.AllName() {
+ info.Labels = append(info.Labels, name.GetText())
+ }
+ }
+
+ // Get properties from Properties AST node
+ if propsCtx := node.Properties(); propsCtx != nil {
+ info.Properties = ExtractProperties(propsCtx, eval)
+ }
+
+ return info
+}
+
+// ExtractProperties extracts properties map from AST
+func ExtractProperties(propsCtx IPropertiesContext, eval *ExpressionEvaluator) map[string]interface{} {
+ result := make(map[string]interface{})
+
+ if propsCtx == nil {
+ return result
+ }
+
+ if mapLit := propsCtx.MapLit(); mapLit != nil {
+ for _, pair := range mapLit.AllMapPair() {
+ if nameCtx := pair.Name(); nameCtx != nil {
+ key := nameCtx.GetText()
+ if key != "" {
+ if exprCtx := pair.Expression(); exprCtx != nil {
+ result[key] = eval.Evaluate(exprCtx)
+ }
+ }
+ }
+ }
+ }
+
+ return result
+}
+
+// RelationshipPatternInfo holds extracted relationship pattern info from AST
+type RelationshipPatternInfo struct {
+ Variable string
+ Type string
+ Properties map[string]interface{}
+ IsForward bool // true for -[r]-> false for <-[r]-
+}
+
+// ExtractRelationshipPattern extracts relationship pattern info from AST
+func ExtractRelationshipPattern(rel IRelationshipPatternContext, eval *ExpressionEvaluator) RelationshipPatternInfo {
+ info := RelationshipPatternInfo{
+ Properties: make(map[string]interface{}),
+ IsForward: true, // default
+ }
+
+ if rel == nil {
+ return info
+ }
+
+ // Check direction from AST tokens
+ // Pattern: LT SUB detail SUB GT? or SUB detail SUB GT
+ if rel.LT() != nil {
+ info.IsForward = false // <-[r]-
+ }
+
+ // Get relationship detail
+ if detail := rel.RelationDetail(); detail != nil {
+ // Get variable from Symbol
+ if sym := detail.Symbol(); sym != nil {
+ info.Variable = sym.GetText()
+ }
+
+ // Get type from RelationshipTypes
+ if types := detail.RelationshipTypes(); types != nil {
+ for _, name := range types.AllName() {
+ info.Type = name.GetText()
+ break // Take first type
+ }
+ }
+
+ // Get properties
+ if propsCtx := detail.Properties(); propsCtx != nil {
+ info.Properties = ExtractProperties(propsCtx, eval)
+ }
+ }
+
+ return info
+}
+
+// ProjectionItemInfo holds extracted projection item info from AST
+type ProjectionItemInfo struct {
+ Expression IExpressionContext
+ Alias string
+ IsAggregation bool
+ AggFunc string
+ AggArgs []IExpressionContext
+ IsDistinct bool
+}
+
+// ExtractProjectionItem extracts projection item info from AST
+func ExtractProjectionItem(item IProjectionItemContext) ProjectionItemInfo {
+ info := ProjectionItemInfo{}
+
+ if item == nil {
+ return info
+ }
+
+ info.Expression = item.Expression()
+
+ // Get alias from Symbol (AS alias)
+ if sym := item.Symbol(); sym != nil {
+ info.Alias = sym.GetText()
+ }
+
+ // If no alias, use expression text as column name
+ if info.Alias == "" && info.Expression != nil {
+ info.Alias = info.Expression.GetText()
+ }
+
+ // Check for aggregation by walking AST
+ if info.Expression != nil {
+ agg := ExtractAggregation(info.Expression)
+ info.IsAggregation = agg.IsAggregation
+ info.AggFunc = agg.FuncName
+ info.AggArgs = agg.Args
+ info.IsDistinct = agg.IsDistinct
+ }
+
+ return info
+}
+
+// AggregationInfo holds aggregation function info extracted from AST
+type AggregationInfo struct {
+ IsAggregation bool
+ IsCountAll bool // COUNT(*)
+ FuncName string
+ Args []IExpressionContext
+ IsDistinct bool
+}
+
+// ExtractAggregation extracts aggregation function info from expression AST
+func ExtractAggregation(expr IExpressionContext) AggregationInfo {
+ info := AggregationInfo{}
+ if expr == nil {
+ return info
+ }
+
+ atom := findAtomInExpression(expr)
+ if atom == nil {
+ return info
+ }
+
+ // Check for COUNT(*) - has its own AST node
+ if countAll := atom.CountAll(); countAll != nil {
+ info.IsAggregation = true
+ info.IsCountAll = true
+ info.FuncName = "COUNT"
+ return info
+ }
+
+ // Check for FunctionInvocation
+ funcInvoc := atom.FunctionInvocation()
+ if funcInvoc == nil {
+ return info
+ }
+
+ invocName := funcInvoc.InvocationName()
+ if invocName == nil {
+ return info
+ }
+
+ symbols := invocName.AllSymbol()
+ if len(symbols) == 0 {
+ return info
+ }
+
+ firstSym := symbols[0]
+
+ // Check aggregation function tokens
+ if firstSym.COUNT() != nil {
+ info.IsAggregation = true
+ info.FuncName = "COUNT"
+ } else if firstSym.SUM() != nil {
+ info.IsAggregation = true
+ info.FuncName = "SUM"
+ } else if firstSym.AVG() != nil {
+ info.IsAggregation = true
+ info.FuncName = "AVG"
+ } else if firstSym.MIN() != nil {
+ info.IsAggregation = true
+ info.FuncName = "MIN"
+ } else if firstSym.MAX() != nil {
+ info.IsAggregation = true
+ info.FuncName = "MAX"
+ } else if firstSym.COLLECT() != nil {
+ info.IsAggregation = true
+ info.FuncName = "COLLECT"
+ }
+
+ if info.IsAggregation {
+ info.IsDistinct = funcInvoc.DISTINCT() != nil
+ if exprChain := funcInvoc.ExpressionChain(); exprChain != nil {
+ info.Args = exprChain.AllExpression()
+ }
+ }
+
+ return info
+}
+
+func findAtomInExpression(expr IExpressionContext) IAtomContext {
+ if expr == nil {
+ return nil
+ }
+
+ xors := expr.AllXorExpression()
+ if len(xors) != 1 {
+ return nil
+ }
+
+ ands := xors[0].AllAndExpression()
+ if len(ands) != 1 {
+ return nil
+ }
+
+ nots := ands[0].AllNotExpression()
+ if len(nots) != 1 {
+ return nil
+ }
+
+ comp := nots[0].ComparisonExpression()
+ if comp == nil {
+ return nil
+ }
+
+ adds := comp.AllAddSubExpression()
+ if len(adds) != 1 {
+ return nil
+ }
+
+ mults := adds[0].AllMultDivExpression()
+ if len(mults) != 1 {
+ return nil
+ }
+
+ powers := mults[0].AllPowerExpression()
+ if len(powers) != 1 {
+ return nil
+ }
+
+ unarys := powers[0].AllUnaryAddSubExpression()
+ if len(unarys) != 1 {
+ return nil
+ }
+
+ atomic := unarys[0].AtomicExpression()
+ if atomic == nil {
+ return nil
+ }
+
+ propOrLabel := atomic.PropertyOrLabelExpression()
+ if propOrLabel == nil {
+ return nil
+ }
+
+ propExpr := propOrLabel.PropertyExpression()
+ if propExpr == nil {
+ return nil
+ }
+
+ return propExpr.Atom()
+}
+
+// ProcedureInfo holds procedure call info from AST
+type ProcedureInfo struct {
+ Name string
+ Namespace string // e.g. "db" for "db.labels"
+ IsDbProc bool
+}
+
+// ExtractProcedureName extracts procedure name from invocation AST
+func ExtractProcedureName(invocName IInvocationNameContext) ProcedureInfo {
+ info := ProcedureInfo{}
+ if invocName == nil {
+ return info
+ }
+
+ symbols := invocName.AllSymbol()
+ if len(symbols) == 0 {
+ return info
+ }
+
+ // Build full procedure name from symbols
+ var parts []string
+ for _, sym := range symbols {
+ parts = append(parts, sym.GetText())
+ }
+
+ info.Name = strings.Join(parts, ".")
+
+ // Check if it's a db.* procedure
+ if len(symbols) >= 2 {
+ firstSym := symbols[0]
+ if firstSym.DATABASE() != nil || firstSym.GetText() == "db" {
+ info.IsDbProc = true
+ info.Namespace = "db"
+ }
+ }
+
+ return info
+}
+
+// ShowCommandType represents types of SHOW commands
+type ShowCommandType int
+
+const (
+ ShowUnknown ShowCommandType = iota
+ ShowIndexes
+ ShowConstraints
+ ShowProcedures
+ ShowFunctions
+ ShowDatabase
+ ShowDatabases
+)
+
+// ExtractShowCommandType extracts the type of SHOW command from AST
+func ExtractShowCommandType(show IShowCommandContext) ShowCommandType {
+ if show == nil {
+ return ShowUnknown
+ }
+
+ // Check AST tokens directly
+ if show.INDEXES() != nil || show.INDEX() != nil {
+ return ShowIndexes
+ }
+ if show.CONSTRAINTS() != nil || show.CONSTRAINT() != nil {
+ return ShowConstraints
+ }
+ if show.PROCEDURES() != nil {
+ return ShowProcedures
+ }
+ if show.FUNCTIONS() != nil {
+ return ShowFunctions
+ }
+ if show.DATABASE() != nil {
+ return ShowDatabase
+ }
+ if show.DATABASES() != nil {
+ return ShowDatabases
+ }
+
+ return ShowUnknown
+}
+
+// SortItemInfo holds sort item info from AST
+type SortItemInfo struct {
+ Expression IExpressionContext
+ IsDesc bool
+}
+
+// ExtractSortItems extracts sort items from ORDER BY AST
+func ExtractSortItems(order IOrderStContext) []SortItemInfo {
+ if order == nil {
+ return nil
+ }
+
+ var items []SortItemInfo
+ for _, orderItem := range order.AllOrderItem() {
+ info := SortItemInfo{
+ Expression: orderItem.Expression(),
+ IsDesc: orderItem.DESC() != nil || orderItem.DESCENDING() != nil,
+ }
+ items = append(items, info)
+ }
+
+ return items
+}
+
+// GroupRows groups rows by expression values
+func GroupRows(rows []map[string]interface{}, keyExprs []IExpressionContext, eval *ExpressionEvaluator) [][]map[string]interface{} {
+ if len(keyExprs) == 0 {
+ return [][]map[string]interface{}{rows}
+ }
+
+ groupMap := make(map[string][]map[string]interface{})
+ var order []string
+
+ for _, row := range rows {
+ eval.SetRow(row)
+
+ var keyParts []string
+ for _, expr := range keyExprs {
+ val := eval.Evaluate(expr)
+ keyParts = append(keyParts, fmt.Sprintf("%v", val))
+ }
+ groupKey := strings.Join(keyParts, "\x00")
+
+ if _, exists := groupMap[groupKey]; !exists {
+ order = append(order, groupKey)
+ }
+ groupMap[groupKey] = append(groupMap[groupKey], row)
+ }
+
+ var result [][]map[string]interface{}
+ for _, k := range order {
+ result = append(result, groupMap[k])
+ }
+ return result
+}
+
+// ComputeAggregation computes an aggregation over a group of rows
+func ComputeAggregation(funcName string, args []IExpressionContext, isCountAll bool, group []map[string]interface{}, eval *ExpressionEvaluator) interface{} {
+ switch funcName {
+ case "COUNT":
+ if isCountAll {
+ return int64(len(group))
+ }
+ count := int64(0)
+ for _, row := range group {
+ eval.SetRow(row)
+ if len(args) > 0 {
+ val := eval.Evaluate(args[0])
+ if val != nil {
+ count++
+ }
+ }
+ }
+ return count
+
+ case "SUM":
+ sum := float64(0)
+ for _, row := range group {
+ eval.SetRow(row)
+ if len(args) > 0 {
+ val := eval.Evaluate(args[0])
+ sum += eval.toFloat64(val)
+ }
+ }
+ if sum == float64(int64(sum)) {
+ return int64(sum)
+ }
+ return sum
+
+ case "AVG":
+ if len(group) == 0 {
+ return nil
+ }
+ sum := float64(0)
+ count := 0
+ for _, row := range group {
+ eval.SetRow(row)
+ if len(args) > 0 {
+ val := eval.Evaluate(args[0])
+ if val != nil {
+ sum += eval.toFloat64(val)
+ count++
+ }
+ }
+ }
+ if count == 0 {
+ return nil
+ }
+ return sum / float64(count)
+
+ case "MIN":
+ var minVal interface{}
+ for _, row := range group {
+ eval.SetRow(row)
+ if len(args) > 0 {
+ val := eval.Evaluate(args[0])
+ if val == nil {
+ continue
+ }
+ if minVal == nil || eval.compareValues(val, minVal) < 0 {
+ minVal = val
+ }
+ }
+ }
+ return minVal
+
+ case "MAX":
+ var maxVal interface{}
+ for _, row := range group {
+ eval.SetRow(row)
+ if len(args) > 0 {
+ val := eval.Evaluate(args[0])
+ if val == nil {
+ continue
+ }
+ if maxVal == nil || eval.compareValues(val, maxVal) > 0 {
+ maxVal = val
+ }
+ }
+ }
+ return maxVal
+
+ case "COLLECT":
+ var result []interface{}
+ for _, row := range group {
+ eval.SetRow(row)
+ if len(args) > 0 {
+ val := eval.Evaluate(args[0])
+ result = append(result, val)
+ }
+ }
+ return result
+ }
+
+ return nil
+}
+
+// CompareValues compares two values, returns -1, 0, or 1
+func CompareValues(a, b interface{}) int {
+ eval := &ExpressionEvaluator{}
+ return eval.compareValues(a, b)
+}
+
+// ValuesEqual checks if two values are equal
+func ValuesEqual(a, b interface{}) bool {
+ eval := &ExpressionEvaluator{}
+ return eval.valuesEqual(a, b)
+}
+
+// ToFloat64 converts a value to float64
+func ToFloat64(val interface{}) float64 {
+ eval := &ExpressionEvaluator{}
+ return eval.toFloat64(val)
+}
+
+// ExtractVariablesFromExpressionChain extracts variable names from an expression chain AST
+func ExtractVariablesFromExpressionChain(chain IExpressionChainContext) []string {
+ if chain == nil {
+ return nil
+ }
+
+ var vars []string
+ for _, expr := range chain.AllExpression() {
+ if varName := ExtractVariableFromExpression(expr); varName != "" {
+ vars = append(vars, varName)
+ }
+ }
+ return vars
+}
+
+// ExtractVariableFromExpression extracts a simple variable name from an expression AST
+func ExtractVariableFromExpression(expr IExpressionContext) string {
+ if expr == nil {
+ return ""
+ }
+
+ // Walk down to find Symbol
+ xors := expr.AllXorExpression()
+ if len(xors) != 1 {
+ return ""
+ }
+
+ ands := xors[0].AllAndExpression()
+ if len(ands) != 1 {
+ return ""
+ }
+
+ nots := ands[0].AllNotExpression()
+ if len(nots) != 1 {
+ return ""
+ }
+
+ comp := nots[0].ComparisonExpression()
+ if comp == nil {
+ return ""
+ }
+
+ adds := comp.AllAddSubExpression()
+ if len(adds) != 1 {
+ return ""
+ }
+
+ mults := adds[0].AllMultDivExpression()
+ if len(mults) != 1 {
+ return ""
+ }
+
+ powers := mults[0].AllPowerExpression()
+ if len(powers) != 1 {
+ return ""
+ }
+
+ unarys := powers[0].AllUnaryAddSubExpression()
+ if len(unarys) != 1 {
+ return ""
+ }
+
+ atomic := unarys[0].AtomicExpression()
+ if atomic == nil {
+ return ""
+ }
+
+ propOrLabel := atomic.PropertyOrLabelExpression()
+ if propOrLabel == nil {
+ return ""
+ }
+
+ propExpr := propOrLabel.PropertyExpression()
+ if propExpr == nil {
+ return ""
+ }
+
+ // No property access - just a variable
+ if len(propExpr.AllDOT()) > 0 {
+ return ""
+ }
+
+ atom := propExpr.Atom()
+ if atom == nil {
+ return ""
+ }
+
+ // Not a function
+ if atom.FunctionInvocation() != nil {
+ return ""
+ }
+
+ if sym := atom.Symbol(); sym != nil {
+ return sym.GetText()
+ }
+
+ return ""
+}
diff --git a/nornicdb/pkg/cypher/antlr/parse.go b/nornicdb/pkg/cypher/antlr/parse.go
new file mode 100644
index 0000000..1fe0c8f
--- /dev/null
+++ b/nornicdb/pkg/cypher/antlr/parse.go
@@ -0,0 +1,180 @@
+// Package antlr provides ANTLR-based Cypher parsing for NornicDB.
+//
+// OPTIMIZATIONS APPLIED:
+// 1. Parser/Lexer pooling - reuse instances via SetInputStream (avoids allocation)
+// 2. SLL prediction mode - O(n) vs LL's O(n^4) worst case
+// 3. Shared DFA cache - builds up over time for faster decisions
+// 4. Parse tree caching - avoid re-parsing identical queries
+package antlr
+
+import (
+ "fmt"
+ "strings"
+ "sync"
+ "sync/atomic"
+
+ "github.com/antlr4-go/antlr/v4"
+)
+
+// ParseResult contains the parsed ANTLR tree and any errors
+type ParseResult struct {
+ Tree IScriptContext
+ Errors []string
+}
+
+// parserWrapper holds reusable parser components
+type parserWrapper struct {
+ lexer *CypherLexer
+ tokens *antlr.CommonTokenStream
+ parser *CypherParser
+}
+
+// Global parser pool and cache
+var (
+ parserPool sync.Pool
+ treeCache sync.Map // query string -> *ParseResult
+ cacheHits atomic.Int64
+ cacheMisses atomic.Int64
+ poolOnce sync.Once
+)
+
+// initPool initializes the parser pool
+func initPool() {
+ parserPool = sync.Pool{
+ New: func() interface{} {
+ // Create lexer with empty input
+ input := antlr.NewInputStream("")
+ lexer := NewCypherLexer(input)
+ lexer.RemoveErrorListeners()
+
+ // Create token stream
+ tokens := antlr.NewCommonTokenStream(lexer, antlr.TokenDefaultChannel)
+
+ // Create parser
+ parser := NewCypherParser(tokens)
+ parser.RemoveErrorListeners()
+
+ // OPTIMIZATION: Use SLL prediction mode (faster)
+ parser.GetInterpreter().SetPredictionMode(antlr.PredictionModeSLL)
+
+ return &parserWrapper{
+ lexer: lexer,
+ tokens: tokens,
+ parser: parser,
+ }
+ },
+ }
+}
+
+// Parse parses a Cypher query string using ANTLR and returns the parse tree
+func Parse(query string) (*ParseResult, error) {
+ query = strings.TrimSpace(query)
+ if query == "" {
+ return nil, fmt.Errorf("empty query")
+ }
+
+ // OPTIMIZATION 1: Check cache first
+ if cached, ok := treeCache.Load(query); ok {
+ cacheHits.Add(1)
+ return cached.(*ParseResult), nil
+ }
+ cacheMisses.Add(1)
+
+ // Initialize pool on first use
+ poolOnce.Do(initPool)
+
+ // OPTIMIZATION 2: Get parser from pool (reuse)
+ pw := parserPool.Get().(*parserWrapper)
+ defer parserPool.Put(pw)
+
+ // OPTIMIZATION 3: Reuse via SetInputStream (avoids allocation)
+ input := antlr.NewInputStream(query)
+ pw.lexer.SetInputStream(input)
+ pw.tokens.SetTokenSource(pw.lexer)
+ pw.parser.SetTokenStream(pw.tokens)
+
+ // Add error listener for this parse
+ errorListener := &parseErrorListener{}
+ pw.parser.AddErrorListener(errorListener)
+ pw.lexer.AddErrorListener(errorListener)
+
+ // Parse (SLL mode - fast path)
+ tree := pw.parser.Script()
+
+ // Remove error listeners before returning to pool
+ pw.parser.RemoveErrorListeners()
+ pw.lexer.RemoveErrorListeners()
+
+ result := &ParseResult{
+ Tree: tree,
+ Errors: errorListener.errors,
+ }
+
+ // Check for errors
+ if len(errorListener.errors) > 0 {
+ return result, fmt.Errorf("syntax error: %s", strings.Join(errorListener.errors, "; "))
+ }
+
+ // OPTIMIZATION 4: Cache successful parses
+ treeCache.Store(query, result)
+
+ return result, nil
+}
+
+// ParseNoCache parses without caching (for parameterized queries)
+func ParseNoCache(query string) (*ParseResult, error) {
+ query = strings.TrimSpace(query)
+ if query == "" {
+ return nil, fmt.Errorf("empty query")
+ }
+
+ poolOnce.Do(initPool)
+
+ pw := parserPool.Get().(*parserWrapper)
+ defer parserPool.Put(pw)
+
+ input := antlr.NewInputStream(query)
+ pw.lexer.SetInputStream(input)
+ pw.tokens.SetTokenSource(pw.lexer)
+ pw.parser.SetTokenStream(pw.tokens)
+
+ errorListener := &parseErrorListener{}
+ pw.parser.AddErrorListener(errorListener)
+ pw.lexer.AddErrorListener(errorListener)
+
+ tree := pw.parser.Script()
+
+ pw.parser.RemoveErrorListeners()
+ pw.lexer.RemoveErrorListeners()
+
+ result := &ParseResult{
+ Tree: tree,
+ Errors: errorListener.errors,
+ }
+
+ if len(errorListener.errors) > 0 {
+ return result, fmt.Errorf("syntax error: %s", strings.Join(errorListener.errors, "; "))
+ }
+
+ return result, nil
+}
+
+// ClearCache clears the parse tree cache
+func ClearCache() {
+ treeCache = sync.Map{}
+}
+
+// CacheStats returns cache hit/miss statistics
+func CacheStats() (hits, misses int64) {
+ return cacheHits.Load(), cacheMisses.Load()
+}
+
+// parseErrorListener collects syntax errors during parsing
+type parseErrorListener struct {
+ *antlr.DefaultErrorListener
+ errors []string
+}
+
+func (e *parseErrorListener) SyntaxError(recognizer antlr.Recognizer, offendingSymbol interface{}, line, column int, msg string, ex antlr.RecognitionException) {
+ e.errors = append(e.errors, fmt.Sprintf("line %d:%d %s", line, column, msg))
+}
diff --git a/nornicdb/pkg/cypher/antlr/parser_test.go b/nornicdb/pkg/cypher/antlr/parser_test.go
new file mode 100644
index 0000000..8abd31d
--- /dev/null
+++ b/nornicdb/pkg/cypher/antlr/parser_test.go
@@ -0,0 +1,175 @@
+package antlr
+
+import (
+ "testing"
+
+ "github.com/antlr4-go/antlr/v4"
+)
+
+// TestANTLRParserBasicQueries tests that ANTLR can parse basic Cypher queries
+func TestANTLRParserBasicQueries(t *testing.T) {
+ queries := []struct {
+ name string
+ query string
+ }{
+ // Basic MATCH
+ {"simple match", "MATCH (n) RETURN n"},
+ {"match with label", "MATCH (n:Person) RETURN n"},
+ {"match with properties", "MATCH (n:Person {name: 'Alice'}) RETURN n"},
+ {"match with variable", "MATCH (n:Person {name: $name}) RETURN n"},
+
+ // MATCH with WHERE
+ {"match where equals", "MATCH (n:Person) WHERE n.name = 'Alice' RETURN n"},
+ {"match where gt", "MATCH (n:Person) WHERE n.age > 21 RETURN n"},
+ {"match where and", "MATCH (n:Person) WHERE n.age > 21 AND n.city = 'NYC' RETURN n"},
+ {"match where or", "MATCH (n:Person) WHERE n.age > 21 OR n.active = true RETURN n"},
+ {"match where not", "MATCH (n:Person) WHERE NOT n.active RETURN n"},
+ {"match where is null", "MATCH (n:Person) WHERE n.email IS NULL RETURN n"},
+ {"match where is not null", "MATCH (n:Person) WHERE n.email IS NOT NULL RETURN n"},
+ {"match where in", "MATCH (n:Person) WHERE n.city IN ['NYC', 'LA', 'SF'] RETURN n"},
+ {"match where starts with", "MATCH (n:Person) WHERE n.name STARTS WITH 'A' RETURN n"},
+ {"match where contains", "MATCH (n:Person) WHERE n.name CONTAINS 'li' RETURN n"},
+
+ // Relationships
+ {"match relationship", "MATCH (a)-[r]->(b) RETURN a, b"},
+ {"match typed relationship", "MATCH (a)-[r:KNOWS]->(b) RETURN a, b"},
+ {"match relationship with props", "MATCH (a)-[r:KNOWS {since: 2020}]->(b) RETURN a, b"},
+ {"match variable length", "MATCH (a)-[r*1..3]->(b) RETURN b"},
+ {"match variable length unbounded", "MATCH (a)-[r*]->(b) RETURN b"},
+ {"match variable length min only", "MATCH (a)-[r*2..]->(b) RETURN b"},
+ {"match variable length max only", "MATCH (a)-[r*..5]->(b) RETURN b"},
+ {"match reverse relationship", "MATCH (a)<-[r:KNOWS]-(b) RETURN a, b"},
+ {"match undirected", "MATCH (a)-[r:KNOWS]-(b) RETURN a, b"},
+
+ // CREATE
+ {"create node", "CREATE (n:Person {name: 'Alice'})"},
+ {"create with return", "CREATE (n:Person {name: 'Alice'}) RETURN n"},
+ {"create relationship", "CREATE (a:Person {name: 'Alice'})-[:KNOWS]->(b:Person {name: 'Bob'})"},
+ {"match create", "MATCH (a:Person {name: 'Alice'}) CREATE (a)-[:KNOWS]->(b:Person {name: 'Bob'})"},
+
+ // MERGE
+ {"merge node", "MERGE (n:Person {name: 'Alice'})"},
+ {"merge with on create", "MERGE (n:Person {name: 'Alice'}) ON CREATE SET n.created = timestamp()"},
+ {"merge with on match", "MERGE (n:Person {name: 'Alice'}) ON MATCH SET n.lastSeen = timestamp()"},
+ {"merge relationship", "MATCH (a:Person), (b:Person) MERGE (a)-[:KNOWS]->(b)"},
+
+ // SET
+ {"set property", "MATCH (n:Person {name: 'Alice'}) SET n.age = 30"},
+ {"set multiple", "MATCH (n:Person {name: 'Alice'}) SET n.age = 30, n.city = 'NYC'"},
+ {"set label", "MATCH (n:Person {name: 'Alice'}) SET n:Employee"},
+
+ // DELETE
+ {"delete node", "MATCH (n:Person {name: 'Alice'}) DELETE n"},
+ {"detach delete", "MATCH (n:Person {name: 'Alice'}) DETACH DELETE n"},
+
+ // RETURN variations
+ {"return star", "MATCH (n) RETURN *"},
+ {"return alias", "MATCH (n:Person) RETURN n.name AS name"},
+ {"return distinct", "MATCH (n:Person) RETURN DISTINCT n.city"},
+ {"return limit", "MATCH (n:Person) RETURN n LIMIT 10"},
+ {"return skip", "MATCH (n:Person) RETURN n SKIP 5"},
+ {"return order by", "MATCH (n:Person) RETURN n ORDER BY n.name"},
+ {"return order desc", "MATCH (n:Person) RETURN n ORDER BY n.age DESC"},
+
+ // WITH clause
+ {"with simple", "MATCH (n:Person) WITH n.name AS name RETURN name"},
+ {"with where", "MATCH (n:Person) WITH n WHERE n.age > 21 RETURN n"},
+ {"with aggregation", "MATCH (n:Person) WITH n.city AS city, COUNT(n) AS cnt RETURN city, cnt"},
+
+ // Aggregations
+ {"count all", "MATCH (n:Person) RETURN COUNT(*)"},
+ {"count nodes", "MATCH (n:Person) RETURN COUNT(n)"},
+ {"sum", "MATCH (n:Person) RETURN SUM(n.age)"},
+ {"avg", "MATCH (n:Person) RETURN AVG(n.age)"},
+ {"min max", "MATCH (n:Person) RETURN MIN(n.age), MAX(n.age)"},
+ {"collect", "MATCH (n:Person) RETURN COLLECT(n.name)"},
+
+ // Functions
+ {"function upper", "MATCH (n:Person) RETURN toUpper(n.name)"},
+ {"function lower", "MATCH (n:Person) RETURN toLower(n.name)"},
+ {"function size", "MATCH (n:Person) RETURN SIZE(n.friends)"},
+ {"function coalesce", "MATCH (n:Person) RETURN COALESCE(n.nickname, n.name)"},
+
+ // UNWIND
+ {"unwind list", "UNWIND [1, 2, 3] AS x RETURN x"},
+ {"unwind with match", "MATCH (n:Person) UNWIND n.friends AS friend RETURN friend"},
+
+ // OPTIONAL MATCH
+ {"optional match", "MATCH (a:Person) OPTIONAL MATCH (a)-[:KNOWS]->(b) RETURN a, b"},
+
+ // UNION
+ {"union", "MATCH (n:Person) RETURN n.name AS name UNION MATCH (c:Company) RETURN c.name AS name"},
+ {"union all", "MATCH (n:Person) RETURN n.name UNION ALL MATCH (c:Company) RETURN c.name"},
+
+ // CASE
+ {"case when", "MATCH (n:Person) RETURN CASE WHEN n.age < 18 THEN 'minor' ELSE 'adult' END"},
+ {"case simple", "MATCH (n:Person) RETURN CASE n.status WHEN 'active' THEN 1 WHEN 'inactive' THEN 0 END"},
+
+ // Complex patterns
+ {"multi-hop", "MATCH (a:Person)-[r:KNOWS*2..4]->(b:Person) RETURN a, b"},
+ {"path variable", "MATCH path = (a:Person)-[:KNOWS*]->(b:Person) RETURN path"},
+ {"multiple patterns", "MATCH (a:Person), (b:Company) WHERE a.employer = b.name RETURN a, b"},
+
+ // CALL
+ {"call procedure", "CALL db.labels()"},
+ {"call with yield", "CALL db.labels() YIELD label RETURN label"},
+ }
+
+ for _, tt := range queries {
+ t.Run(tt.name, func(t *testing.T) {
+ // Create ANTLR input stream
+ input := antlr.NewInputStream(tt.query)
+
+ // Create lexer
+ lexer := NewCypherLexer(input)
+
+ // Create token stream
+ tokens := antlr.NewCommonTokenStream(lexer, antlr.TokenDefaultChannel)
+
+ // Create parser
+ parser := NewCypherParser(tokens)
+
+ // Collect errors
+ errorListener := &testErrorListener{}
+ parser.RemoveErrorListeners()
+ parser.AddErrorListener(errorListener)
+
+ // Parse
+ tree := parser.Script()
+
+ // Check for errors
+ if len(errorListener.errors) > 0 {
+ t.Errorf("Parse errors: %v", errorListener.errors)
+ }
+
+ // Verify we got a valid tree
+ if tree == nil {
+ t.Error("Got nil parse tree")
+ }
+ })
+ }
+}
+
+type testErrorListener struct {
+ *antlr.DefaultErrorListener
+ errors []string
+}
+
+func (e *testErrorListener) SyntaxError(recognizer antlr.Recognizer, offendingSymbol interface{}, line, column int, msg string, ex antlr.RecognitionException) {
+ e.errors = append(e.errors, msg)
+}
+
+// BenchmarkANTLRParser measures ANTLR parser performance
+func BenchmarkANTLRParser(b *testing.B) {
+ query := "MATCH (n:Person {name: 'Alice'})-[r:KNOWS*1..3]->(m:Person) WHERE m.age > 21 AND m.city IN ['NYC', 'LA'] WITH m, COUNT(r) AS cnt ORDER BY cnt DESC LIMIT 10 RETURN m.name, m.age, cnt"
+
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ input := antlr.NewInputStream(query)
+ lexer := NewCypherLexer(input)
+ tokens := antlr.NewCommonTokenStream(lexer, antlr.TokenDefaultChannel)
+ parser := NewCypherParser(tokens)
+ parser.RemoveErrorListeners()
+ _ = parser.Script()
+ }
+}
diff --git a/nornicdb/pkg/cypher/ast_executor.go b/nornicdb/pkg/cypher/ast_executor.go
new file mode 100644
index 0000000..9b5e613
--- /dev/null
+++ b/nornicdb/pkg/cypher/ast_executor.go
@@ -0,0 +1,2970 @@
+// Package cypher - AST-first Cypher executor.
+//
+// This executor walks the ANTLR parse tree directly instead of parsing strings.
+// All clause data is extracted from AST nodes - NO string parsing at all.
+package cypher
+
+import (
+ "context"
+ "fmt"
+ "sort"
+ "strconv"
+ "strings"
+ "sync"
+ "sync/atomic"
+
+ cyantlr "github.com/orneryd/nornicdb/pkg/cypher/antlr"
+ "github.com/orneryd/nornicdb/pkg/storage"
+)
+
+// ID generator for AST executor
+var astIDGen int64
+
+// ASTExecutor executes Cypher queries by walking the ANTLR parse tree directly.
+// No string parsing - all data comes from AST nodes.
+type ASTExecutor struct {
+ storage storage.Engine
+ cache *QueryPlanCache // Caches parse trees by query string
+
+ // Callbacks and integrations
+ nodeCreatedCallback NodeCreatedCallback
+ embedder QueryEmbedder
+
+ // Node lookup cache for fast MATCH pattern lookups
+ nodeLookupCache map[string]*storage.Node
+ nodeLookupCacheMu sync.RWMutex
+
+ // Transaction context
+ txContext *TransactionContext
+
+ // Execution context passed through tree walk
+ ctx context.Context
+ params map[string]interface{}
+ variables map[string]interface{} // Variable bindings during execution
+ result *ExecuteResult
+ matchedRows []map[string]interface{} // Current matched rows
+
+ // Query optimization hints
+ matchLimit int // If >0, early terminate MATCH cross product at this limit
+}
+
+// NewASTExecutor creates a new AST-first executor
+func NewASTExecutor(store storage.Engine) *ASTExecutor {
+ return &ASTExecutor{
+ storage: store,
+ cache: NewQueryPlanCache(1000),
+ variables: make(map[string]interface{}),
+ nodeLookupCache: make(map[string]*storage.Node, 1000),
+ }
+}
+
+// SetNodeCreatedCallback sets the callback for node creation events
+func (e *ASTExecutor) SetNodeCreatedCallback(cb NodeCreatedCallback) {
+ e.nodeCreatedCallback = cb
+}
+
+// SetEmbedder sets the embedding function for vector operations
+func (e *ASTExecutor) SetEmbedder(embedder QueryEmbedder) {
+ e.embedder = embedder
+}
+
+// notifyNodeCreated calls the callback if set
+func (e *ASTExecutor) notifyNodeCreated(nodeID string) {
+ if e.nodeCreatedCallback != nil {
+ e.nodeCreatedCallback(nodeID)
+ }
+}
+
+// Execute parses and executes a Cypher query using AST walking
+func (e *ASTExecutor) Execute(ctx context.Context, cypher string, params map[string]interface{}) (*ExecuteResult, error) {
+ // Parse query (or get from cache)
+ parseResult, err := cyantlr.Parse(cypher)
+ if err != nil {
+ return nil, err
+ }
+
+ // Initialize execution context
+ e.ctx = ctx
+ e.params = params
+ e.variables = make(map[string]interface{})
+ e.result = &ExecuteResult{
+ Columns: []string{},
+ Rows: [][]interface{}{},
+ Stats: &QueryStats{},
+ }
+ e.matchedRows = nil
+
+ // Execute by walking the AST
+ if err := e.executeScript(parseResult.Tree); err != nil {
+ return nil, err
+ }
+
+ return e.result, nil
+}
+
+// executeScript executes a script (top-level rule)
+func (e *ASTExecutor) executeScript(tree cyantlr.IScriptContext) error {
+ if tree == nil {
+ return fmt.Errorf("nil parse tree")
+ }
+
+ // Script contains one or more queries
+ for _, query := range tree.AllQuery() {
+ if err := e.executeQuery(query); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// executeQuery executes a single query
+func (e *ASTExecutor) executeQuery(query cyantlr.IQueryContext) error {
+ if query == nil {
+ return nil
+ }
+
+ // Check for standalone CALL
+ if call := query.StandaloneCall(); call != nil {
+ return e.executeStandaloneCall(call)
+ }
+
+ // Check for SHOW command
+ if show := query.ShowCommand(); show != nil {
+ return e.executeShowCommand(show)
+ }
+
+ // Check for schema command (CREATE/DROP INDEX/CONSTRAINT)
+ if schema := query.SchemaCommand(); schema != nil {
+ return e.executeSchemaCommand(schema)
+ }
+
+ // Regular query
+ if regular := query.RegularQuery(); regular != nil {
+ return e.executeRegularQuery(regular)
+ }
+
+ return nil
+}
+
+// executeRegularQuery handles MATCH/CREATE/MERGE/etc queries
+func (e *ASTExecutor) executeRegularQuery(query cyantlr.IRegularQueryContext) error {
+ if query == nil {
+ return nil
+ }
+
+ // Get single query
+ if single := query.SingleQuery(); single != nil {
+ return e.executeSingleQuery(single)
+ }
+
+ return nil
+}
+
+// executeSingleQuery handles a single query (may be multi-part with WITH)
+func (e *ASTExecutor) executeSingleQuery(query cyantlr.ISingleQueryContext) error {
+ if query == nil {
+ return nil
+ }
+
+ // Single-part query
+ if singlePart := query.SinglePartQ(); singlePart != nil {
+ return e.executeSinglePartQuery(singlePart)
+ }
+
+ // Multi-part query (with WITH clauses)
+ if multiPart := query.MultiPartQ(); multiPart != nil {
+ return e.executeMultiPartQuery(multiPart)
+ }
+
+ return nil
+}
+
+// executeSinglePartQuery handles a query without WITH chaining
+func (e *ASTExecutor) executeSinglePartQuery(query cyantlr.ISinglePartQContext) error {
+ if query == nil {
+ return nil
+ }
+
+ // Execute reading statements (MATCH, UNWIND, etc.)
+ for _, reading := range query.AllReadingStatement() {
+ if err := e.executeReadingStatement(reading); err != nil {
+ return err
+ }
+ }
+
+ // Execute updating statements (CREATE, MERGE, DELETE, SET, REMOVE)
+ for _, updating := range query.AllUpdatingStatement() {
+ if err := e.executeUpdatingStatement(updating); err != nil {
+ return err
+ }
+ }
+
+ // Execute RETURN
+ if ret := query.ReturnSt(); ret != nil {
+ return e.executeReturn(ret)
+ }
+
+ return nil
+}
+
+// executeMultiPartQuery handles queries with WITH clauses
+func (e *ASTExecutor) executeMultiPartQuery(query cyantlr.IMultiPartQContext) error {
+ if query == nil {
+ return nil
+ }
+
+ // Pre-analyze: Check if the first WITH clause has a LIMIT
+ // This allows us to optimize MATCH cross products
+ e.matchLimit = 0 // Reset
+ withClauses := query.AllWithSt()
+ if len(withClauses) > 0 {
+ firstWith := withClauses[0]
+ if firstWith != nil {
+ if projBody := firstWith.ProjectionBody(); projBody != nil {
+ if limit := projBody.LimitSt(); limit != nil {
+ if limitExpr := limit.Expression(); limitExpr != nil {
+ eval := cyantlr.NewExpressionEvaluator(e.params, e.variables)
+ if limitVal := eval.Evaluate(limitExpr); limitVal != nil {
+ switch v := limitVal.(type) {
+ case int64:
+ e.matchLimit = int(v)
+ case float64:
+ e.matchLimit = int(v)
+ case int:
+ e.matchLimit = v
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Multi-part queries have: reading/updating statements, then WITH, repeated, then final single part
+ // Execute all reading statements first
+ for _, reading := range query.AllReadingStatement() {
+ if err := e.executeReadingStatement(reading); err != nil {
+ return err
+ }
+ }
+
+ // Reset matchLimit after MATCH completes
+ e.matchLimit = 0
+
+ // Execute all updating statements
+ for _, updating := range query.AllUpdatingStatement() {
+ if err := e.executeUpdatingStatement(updating); err != nil {
+ return err
+ }
+ }
+
+ // Execute WITH clauses in sequence
+ for _, with := range withClauses {
+ if err := e.executeWith(with); err != nil {
+ return err
+ }
+ }
+
+ // Execute the final single part
+ if singlePart := query.SinglePartQ(); singlePart != nil {
+ return e.executeSinglePartQuery(singlePart)
+ }
+
+ return nil
+}
+
+// executeReadingStatement handles MATCH, UNWIND, CALL subquery, CALL procedure
+func (e *ASTExecutor) executeReadingStatement(stmt cyantlr.IReadingStatementContext) error {
+ if stmt == nil {
+ return nil
+ }
+
+ // MATCH clause
+ if match := stmt.MatchSt(); match != nil {
+ return e.executeMatch(match)
+ }
+
+ // UNWIND clause
+ if unwind := stmt.UnwindSt(); unwind != nil {
+ return e.executeUnwind(unwind)
+ }
+
+ // CALL procedure (e.g., CALL db.labels())
+ if queryCall := stmt.QueryCallSt(); queryCall != nil {
+ return e.executeQueryCall(queryCall)
+ }
+
+ // CALL {} subquery
+ if call := stmt.CallSubquery(); call != nil {
+ return e.executeCallSubquery(call)
+ }
+
+ return nil
+}
+
+// executeUpdatingStatement handles CREATE, MERGE, DELETE, SET, REMOVE
+func (e *ASTExecutor) executeUpdatingStatement(stmt cyantlr.IUpdatingStatementContext) error {
+ if stmt == nil {
+ return nil
+ }
+
+ // CREATE clause
+ if create := stmt.CreateSt(); create != nil {
+ return e.executeCreate(create)
+ }
+
+ // MERGE clause
+ if merge := stmt.MergeSt(); merge != nil {
+ return e.executeMerge(merge)
+ }
+
+ // DELETE clause
+ if del := stmt.DeleteSt(); del != nil {
+ return e.executeDelete(del)
+ }
+
+ // SET clause
+ if set := stmt.SetSt(); set != nil {
+ return e.executeSet(set)
+ }
+
+ // REMOVE clause
+ if remove := stmt.RemoveSt(); remove != nil {
+ return e.executeRemove(remove)
+ }
+
+ return nil
+}
+
+// executeMatch handles MATCH clause by walking AST
+func (e *ASTExecutor) executeMatch(match cyantlr.IMatchStContext) error {
+ if match == nil {
+ return nil
+ }
+
+ isOptional := match.OPTIONAL() != nil
+
+ // Get pattern from PatternWhere
+ patternWhere := match.PatternWhere()
+ if patternWhere == nil {
+ return nil
+ }
+
+ pattern := patternWhere.Pattern()
+ if pattern == nil {
+ return nil
+ }
+
+ var matchedRows []map[string]interface{}
+ var err error
+
+ // If there are existing matched rows (e.g., from UNWIND), execute match for EACH row
+ // This allows UNWIND variables to be used in MATCH property filters
+ if len(e.matchedRows) > 0 {
+ var allResults []map[string]interface{}
+
+ for _, existingRow := range e.matchedRows {
+ // Set up variables from the existing row for property resolution
+ savedVars := make(map[string]interface{})
+ for k, v := range e.variables {
+ savedVars[k] = v
+ }
+ for k, v := range existingRow {
+ e.variables[k] = v
+ }
+
+ // Execute pattern matching with current row's context
+ // Use matchLimit hint if available (from WITH LIMIT lookahead)
+ rowResults, matchErr := e.matchPatternWithLimit(pattern, isOptional, e.matchLimit)
+ if matchErr != nil {
+ // Restore variables
+ e.variables = savedVars
+ return matchErr
+ }
+
+ // Apply WHERE filter if present
+ if where := patternWhere.Where(); where != nil {
+ rowResults, matchErr = e.filterByWhere(rowResults, where)
+ if matchErr != nil {
+ e.variables = savedVars
+ return matchErr
+ }
+ }
+
+ // Merge existing row data with match results
+ for _, matchRow := range rowResults {
+ combined := make(map[string]interface{})
+ for k, v := range existingRow {
+ combined[k] = v
+ }
+ for k, v := range matchRow {
+ combined[k] = v
+ }
+ allResults = append(allResults, combined)
+ }
+
+ // If optional match and no results, keep the existing row with nulls
+ if isOptional && len(rowResults) == 0 {
+ allResults = append(allResults, existingRow)
+ }
+
+ // Restore variables
+ e.variables = savedVars
+ }
+
+ matchedRows = allResults
+ } else {
+ // No existing rows - execute match normally
+ // Use matchLimit hint if available (from WITH LIMIT lookahead)
+ matchedRows, err = e.matchPatternWithLimit(pattern, isOptional, e.matchLimit)
+ if err != nil {
+ return err
+ }
+
+ // Apply WHERE filter if present
+ if where := patternWhere.Where(); where != nil {
+ matchedRows, err = e.filterByWhere(matchedRows, where)
+ if err != nil {
+ return err
+ }
+ }
+ }
+
+ // Store matched rows for subsequent clauses
+ // Ensure matchedRows is non-nil to indicate MATCH was executed
+ // (nil means no MATCH, empty slice means MATCH found nothing)
+ if matchedRows == nil {
+ matchedRows = []map[string]interface{}{}
+ }
+
+ e.matchedRows = matchedRows
+
+ return nil
+}
+
+// matchPattern executes pattern matching from AST
+func (e *ASTExecutor) matchPattern(pattern cyantlr.IPatternContext, isOptional bool) ([]map[string]interface{}, error) {
+ return e.matchPatternWithLimit(pattern, isOptional, 0) // 0 = no limit
+}
+
+// matchPatternWithLimit executes pattern matching with optional early termination
+// limit of 0 means no limit
+func (e *ASTExecutor) matchPatternWithLimit(pattern cyantlr.IPatternContext, isOptional bool, limit int) ([]map[string]interface{}, error) {
+ allParts := pattern.AllPatternPart()
+ if len(allParts) == 0 {
+ if isOptional {
+ return []map[string]interface{}{{}}, nil
+ }
+ return nil, nil
+ }
+
+ // Start with results from first pattern part
+ results, err := e.matchPatternPart(allParts[0])
+ if err != nil {
+ if isOptional {
+ return []map[string]interface{}{{}}, nil
+ }
+ return nil, err
+ }
+
+ // Apply limit early if only one pattern part
+ if limit > 0 && len(results) > limit {
+ results = results[:limit]
+ }
+
+ // For subsequent pattern parts, do a cross product with early termination
+ for i := 1; i < len(allParts); i++ {
+ partResults, err := e.matchPatternPart(allParts[i])
+ if err != nil {
+ if isOptional {
+ continue
+ }
+ return nil, err
+ }
+
+ // Cross product with early termination if limit is set
+ var combined []map[string]interface{}
+ crossProduct:
+ for _, existingRow := range results {
+ for _, newRow := range partResults {
+ combinedRow := make(map[string]interface{})
+ for k, v := range existingRow {
+ combinedRow[k] = v
+ }
+ for k, v := range newRow {
+ combinedRow[k] = v
+ }
+ combined = append(combined, combinedRow)
+
+ // Early termination if we have enough results
+ if limit > 0 && len(combined) >= limit {
+ break crossProduct
+ }
+ }
+ }
+ results = combined
+ }
+
+ if len(results) == 0 && isOptional {
+ results = append(results, make(map[string]interface{}))
+ }
+
+ return results, nil
+}
+
+// matchPatternPart matches a single pattern part like (n:Label)-[r]->(m)
+func (e *ASTExecutor) matchPatternPart(part cyantlr.IPatternPartContext) ([]map[string]interface{}, error) {
+ if part == nil {
+ return nil, nil
+ }
+
+ // Get pattern element - use PatternElem() not AnonymousPatternPart()
+ patternElem := part.PatternElem()
+ if patternElem == nil {
+ return nil, nil
+ }
+
+ // Extract variable name if pattern is assigned (p = ...)
+ var pathVar string
+ if sym := part.Symbol(); sym != nil {
+ pathVar = sym.GetText()
+ }
+
+ // Match the pattern element (node and relationships)
+ return e.matchPatternElem(patternElem, pathVar)
+}
+
+// matchPatternElem matches nodes and relationships
+func (e *ASTExecutor) matchPatternElem(elem cyantlr.IPatternElemContext, pathVar string) ([]map[string]interface{}, error) {
+ if elem == nil {
+ return nil, nil
+ }
+
+ // Get the node pattern
+ nodePattern := elem.NodePattern()
+ if nodePattern == nil {
+ return nil, nil
+ }
+
+ // Extract node info from AST
+ nodeVar, labels, props := e.extractNodePattern(nodePattern)
+
+ // Find matching nodes
+ nodes, err := e.findNodes(labels, props)
+ if err != nil {
+ return nil, err
+ }
+
+ // Build result rows
+ var results []map[string]interface{}
+ for _, node := range nodes {
+ row := make(map[string]interface{})
+ if nodeVar != "" {
+ row[nodeVar] = e.nodeToMap(node)
+ }
+ results = append(results, row)
+ }
+
+ // Handle relationship chains
+ for _, chain := range elem.AllPatternElemChain() {
+ results, err = e.extendWithChain(results, chain)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ return results, nil
+}
+
+// extractNodePattern extracts variable, labels, and properties from node pattern AST
+func (e *ASTExecutor) extractNodePattern(node cyantlr.INodePatternContext) (variable string, labels []string, props map[string]interface{}) {
+ props = make(map[string]interface{})
+
+ if node == nil {
+ return
+ }
+
+ // Get variable name
+ if sym := node.Symbol(); sym != nil {
+ variable = sym.GetText()
+ }
+
+ // Get labels - NodeLabels has AllName() for label names
+ if nodeLabels := node.NodeLabels(); nodeLabels != nil {
+ for _, name := range nodeLabels.AllName() {
+ labels = append(labels, name.GetText())
+ }
+ }
+
+ // Get properties
+ if propsCtx := node.Properties(); propsCtx != nil {
+ props = e.extractProperties(propsCtx)
+ }
+
+ return
+}
+
+// extractProperties extracts property map from AST
+func (e *ASTExecutor) extractProperties(propsCtx cyantlr.IPropertiesContext) map[string]interface{} {
+ result := make(map[string]interface{})
+
+ if propsCtx == nil {
+ return result
+ }
+
+ // Use proper AST-based expression evaluator for property values
+ eval := cyantlr.NewExpressionEvaluator(e.params, e.variables)
+
+ // MapLit contains map pairs
+ if mapLit := propsCtx.MapLit(); mapLit != nil {
+ for _, pair := range mapLit.AllMapPair() {
+ key := ""
+ if nameCtx := pair.Name(); nameCtx != nil {
+ key = nameCtx.GetText()
+ }
+ if key != "" {
+ if exprCtx := pair.Expression(); exprCtx != nil {
+ result[key] = eval.Evaluate(exprCtx)
+ }
+ }
+ }
+ }
+
+ return result
+}
+
+// evaluateExpression evaluates an expression AST node
+func (e *ASTExecutor) evaluateExpression(expr cyantlr.IExpressionContext) interface{} {
+ if expr == nil {
+ return nil
+ }
+
+ // Get the text and try to parse as literal
+ text := strings.TrimSpace(expr.GetText())
+
+ // Check for parameter
+ if len(text) > 0 && text[0] == '$' {
+ paramName := text[1:]
+ if val, ok := e.params[paramName]; ok {
+ return val
+ }
+ return nil
+ }
+
+ // Try to parse as number
+ if i, err := strconv.ParseInt(text, 10, 64); err == nil {
+ return i
+ }
+ if f, err := strconv.ParseFloat(text, 64); err == nil {
+ return f
+ }
+
+ // Boolean
+ lower := strings.ToLower(text)
+ if lower == "true" {
+ return true
+ }
+ if lower == "false" {
+ return false
+ }
+ if lower == "null" {
+ return nil
+ }
+
+ // String literal - remove quotes
+ if len(text) >= 2 {
+ if (text[0] == '\'' && text[len(text)-1] == '\'') ||
+ (text[0] == '"' && text[len(text)-1] == '"') {
+ return text[1 : len(text)-1]
+ }
+ }
+
+ // Return as-is (might be a variable reference)
+ return text
+}
+
+// findNodes finds nodes matching labels and properties
+func (e *ASTExecutor) findNodes(labels []string, props map[string]interface{}) ([]*storage.Node, error) {
+ var result []*storage.Node
+
+ if len(labels) > 0 {
+ // Find nodes that have ALL specified labels
+ // Start with nodes matching first label
+ firstNodes, err := e.storage.GetNodesByLabel(labels[0])
+ if err != nil {
+ return nil, err
+ }
+
+ if len(labels) == 1 {
+ result = firstNodes
+ } else {
+ // Filter to nodes that have ALL labels
+ for _, node := range firstNodes {
+ hasAllLabels := true
+ for _, label := range labels[1:] {
+ if !e.nodeHasLabel(node, label) {
+ hasAllLabels = false
+ break
+ }
+ }
+ if hasAllLabels {
+ result = append(result, node)
+ }
+ }
+ }
+ } else {
+ // Get all nodes - returns []*Node, no error
+ result = e.storage.GetAllNodes()
+ }
+
+ // Filter by properties
+ if len(props) > 0 {
+ filtered := make([]*storage.Node, 0)
+ for _, node := range result {
+ if e.nodeMatchesProps(node, props) {
+ filtered = append(filtered, node)
+ }
+ }
+ result = filtered
+ }
+
+ return result, nil
+}
+
+// nodeHasLabel checks if a node has a specific label
+func (e *ASTExecutor) nodeHasLabel(node *storage.Node, label string) bool {
+ for _, l := range node.Labels {
+ if l == label {
+ return true
+ }
+ }
+ return false
+}
+
+// nodeMatchesProps checks if node has all required properties
+func (e *ASTExecutor) nodeMatchesProps(node *storage.Node, props map[string]interface{}) bool {
+ for key, val := range props {
+ nodeVal, exists := node.Properties[key]
+ if !exists {
+ return false
+ }
+ if !e.valuesEqual(nodeVal, val) {
+ return false
+ }
+ }
+ return true
+}
+
+// valuesEqual compares two values
+func (e *ASTExecutor) valuesEqual(a, b interface{}) bool {
+ switch av := a.(type) {
+ case int64:
+ switch bv := b.(type) {
+ case int64:
+ return av == bv
+ case float64:
+ return float64(av) == bv
+ case int:
+ return av == int64(bv)
+ }
+ case float64:
+ switch bv := b.(type) {
+ case float64:
+ return av == bv
+ case int64:
+ return av == float64(bv)
+ case int:
+ return av == float64(bv)
+ }
+ case string:
+ if bv, ok := b.(string); ok {
+ return av == bv
+ }
+ case bool:
+ if bv, ok := b.(bool); ok {
+ return av == bv
+ }
+ }
+ return fmt.Sprintf("%v", a) == fmt.Sprintf("%v", b)
+}
+
+// nodeToMap converts a storage.Node to a map for result rows
+func (e *ASTExecutor) nodeToMap(node *storage.Node) map[string]interface{} {
+ result := make(map[string]interface{})
+ result["_nodeId"] = string(node.ID)
+ result["_labels"] = node.Labels
+ for k, v := range node.Properties {
+ result[k] = v
+ }
+ return result
+}
+
+// getNodeFromVariable retrieves a storage.Node from a variable name if it exists
+func (e *ASTExecutor) getNodeFromVariable(varName string) *storage.Node {
+ if varName == "" {
+ return nil
+ }
+
+ varVal, ok := e.variables[varName]
+ if !ok {
+ return nil
+ }
+
+ nodeMap, ok := varVal.(map[string]interface{})
+ if !ok {
+ return nil
+ }
+
+ nodeID, ok := nodeMap["_nodeId"].(string)
+ if !ok {
+ return nil
+ }
+
+ node, err := e.storage.GetNode(storage.NodeID(nodeID))
+ if err != nil {
+ return nil
+ }
+
+ return node
+}
+
+// executeCreate handles CREATE clause
+func (e *ASTExecutor) executeCreate(create cyantlr.ICreateStContext) error {
+ if create == nil {
+ return nil
+ }
+
+ pattern := create.Pattern()
+ if pattern == nil {
+ return nil
+ }
+
+ // If there are matched rows from a preceding MATCH, iterate over them
+ // This allows CREATE (a)-[:KNOWS]->(b) where a and b come from MATCH
+ if len(e.matchedRows) > 0 {
+ for _, row := range e.matchedRows {
+ // Populate e.variables with this row's bindings
+ for k, v := range row {
+ e.variables[k] = v
+ }
+
+ // Create nodes/relationships from pattern for this row
+ for _, part := range pattern.AllPatternPart() {
+ if err := e.createPatternPart(part); err != nil {
+ return err
+ }
+ }
+ }
+ } else {
+ // No preceding MATCH - just create the pattern
+ for _, part := range pattern.AllPatternPart() {
+ if err := e.createPatternPart(part); err != nil {
+ return err
+ }
+ }
+ }
+
+ return nil
+}
+
+// createPatternPart creates nodes and relationships from a pattern part
+func (e *ASTExecutor) createPatternPart(part cyantlr.IPatternPartContext) error {
+ if part == nil {
+ return nil
+ }
+
+ patternElem := part.PatternElem()
+ if patternElem == nil {
+ return nil
+ }
+
+ return e.createPatternElem(patternElem)
+}
+
+// createPatternElem creates nodes and relationships
+func (e *ASTExecutor) createPatternElem(elem cyantlr.IPatternElemContext) error {
+ if elem == nil {
+ return nil
+ }
+
+ // Get first node
+ nodePattern := elem.NodePattern()
+ if nodePattern == nil {
+ return nil
+ }
+
+ nodeVar, labels, props := e.extractNodePattern(nodePattern)
+
+ // Check if variable already exists (from MATCH) - reuse it
+ var node *storage.Node
+ var err error
+ if nodeVar != "" {
+ if existingNode := e.getNodeFromVariable(nodeVar); existingNode != nil {
+ node = existingNode
+ }
+ }
+
+ // Create new node only if not reusing an existing one
+ if node == nil {
+ node, err = e.createNode(labels, props)
+ if err != nil {
+ return err
+ }
+ e.result.Stats.NodesCreated++
+
+ // Store in variables if named
+ if nodeVar != "" {
+ e.variables[nodeVar] = e.nodeToMap(node)
+ }
+ }
+
+ // Create relationships in chains
+ lastNode := node
+ for _, chain := range elem.AllPatternElemChain() {
+ lastNode, err = e.createChain(lastNode, chain)
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+// generateID creates a unique ID for nodes/edges
+func (e *ASTExecutor) generateID() string {
+ id := atomic.AddInt64(&astIDGen, 1)
+ return fmt.Sprintf("n%d", id)
+}
+
+// createNode creates a new node in storage
+func (e *ASTExecutor) createNode(labels []string, props map[string]interface{}) (*storage.Node, error) {
+ node := &storage.Node{
+ ID: storage.NodeID(e.generateID()),
+ Labels: labels,
+ Properties: props,
+ }
+
+ if err := e.storage.CreateNode(node); err != nil {
+ return nil, err
+ }
+
+ e.notifyNodeCreated(string(node.ID))
+
+ return node, nil
+}
+
+// createChain creates relationships in a pattern chain
+func (e *ASTExecutor) createChain(startNode *storage.Node, chain cyantlr.IPatternElemChainContext) (*storage.Node, error) {
+ if chain == nil {
+ return startNode, nil
+ }
+
+ // Get relationship detail
+ relPattern := chain.RelationshipPattern()
+ if relPattern == nil {
+ return startNode, nil
+ }
+
+ // Get end node
+ endNodePattern := chain.NodePattern()
+ if endNodePattern == nil {
+ return startNode, nil
+ }
+
+ // Check if end node variable already exists (from MATCH)
+ endVar, endLabels, endProps := e.extractNodePattern(endNodePattern)
+
+ var endNode *storage.Node
+ var err error
+
+ // Reuse existing node if variable exists
+ if endVar != "" {
+ if existingNode := e.getNodeFromVariable(endVar); existingNode != nil {
+ endNode = existingNode
+ }
+ }
+
+ // Create new node only if not reusing
+ if endNode == nil {
+ endNode, err = e.createNode(endLabels, endProps)
+ if err != nil {
+ return nil, err
+ }
+ e.result.Stats.NodesCreated++
+
+ if endVar != "" {
+ e.variables[endVar] = e.nodeToMap(endNode)
+ }
+ }
+
+ // Extract relationship info and create
+ relVar, relType, relProps, isForward := e.extractRelationshipPattern(relPattern)
+
+ var edge *storage.Edge
+ edgeID := storage.EdgeID(e.generateID())
+ if isForward {
+ edge = &storage.Edge{
+ ID: edgeID,
+ Type: relType,
+ StartNode: startNode.ID,
+ EndNode: endNode.ID,
+ Properties: relProps,
+ }
+ } else {
+ edge = &storage.Edge{
+ ID: edgeID,
+ Type: relType,
+ StartNode: endNode.ID,
+ EndNode: startNode.ID,
+ Properties: relProps,
+ }
+ }
+
+ if err := e.storage.CreateEdge(edge); err != nil {
+ return nil, err
+ }
+ e.result.Stats.RelationshipsCreated++
+
+ if relVar != "" {
+ e.variables[relVar] = map[string]interface{}{
+ "_edgeId": string(edge.ID),
+ "_type": edge.Type,
+ }
+ }
+
+ return endNode, nil
+}
+
+// extractRelationshipPattern extracts relationship info from AST
+func (e *ASTExecutor) extractRelationshipPattern(rel cyantlr.IRelationshipPatternContext) (variable, relType string, props map[string]interface{}, isForward bool) {
+ props = make(map[string]interface{})
+ isForward = true // default
+
+ if rel == nil {
+ return
+ }
+
+ // Check direction from arrows in the text
+ text := rel.GetText()
+ if len(text) > 0 && text[0] == '<' {
+ isForward = false
+ }
+
+ // Get relationship detail
+ if detail := rel.RelationDetail(); detail != nil {
+ // Get variable
+ if sym := detail.Symbol(); sym != nil {
+ variable = sym.GetText()
+ }
+
+ // Get type
+ if types := detail.RelationshipTypes(); types != nil {
+ for _, t := range types.AllName() {
+ relType = t.GetText()
+ break // Just take first type
+ }
+ }
+
+ // Get properties
+ if propsCtx := detail.Properties(); propsCtx != nil {
+ props = e.extractProperties(propsCtx)
+ }
+ }
+
+ return
+}
+
+// executeDelete handles DELETE clause
+func (e *ASTExecutor) executeDelete(del cyantlr.IDeleteStContext) error {
+ if del == nil {
+ return nil
+ }
+
+ isDetach := del.DETACH() != nil
+
+ // Get expression chain (variables to delete)
+ exprChain := del.ExpressionChain()
+ if exprChain == nil {
+ return nil
+ }
+
+ // Get variable names to delete
+ varsToDelete := e.extractExpressionChainVars(exprChain)
+
+ // Delete from matched rows
+ for _, row := range e.matchedRows {
+ for _, varName := range varsToDelete {
+ val, exists := row[varName]
+ if !exists {
+ continue
+ }
+
+ // Check if it's a node or edge
+ if nodeMap, ok := val.(map[string]interface{}); ok {
+ if edgeID, ok := nodeMap["_edgeId"].(string); ok {
+ // Delete edge
+ if err := e.storage.DeleteEdge(storage.EdgeID(edgeID)); err == nil {
+ e.result.Stats.RelationshipsDeleted++
+ }
+ } else if nodeID, ok := nodeMap["_nodeId"].(string); ok {
+ // Delete node
+ if isDetach {
+ // Delete connected edges first
+ edges, _ := e.storage.GetOutgoingEdges(storage.NodeID(nodeID))
+ for _, edge := range edges {
+ e.storage.DeleteEdge(edge.ID)
+ e.result.Stats.RelationshipsDeleted++
+ }
+ edges, _ = e.storage.GetIncomingEdges(storage.NodeID(nodeID))
+ for _, edge := range edges {
+ e.storage.DeleteEdge(edge.ID)
+ e.result.Stats.RelationshipsDeleted++
+ }
+ }
+ if err := e.storage.DeleteNode(storage.NodeID(nodeID)); err == nil {
+ e.result.Stats.NodesDeleted++
+ }
+ }
+ }
+ }
+ }
+
+ return nil
+}
+
+// extractExpressionChainVars extracts variable names from expression chain by walking the AST
+func (e *ASTExecutor) extractExpressionChainVars(chain cyantlr.IExpressionChainContext) []string {
+ var vars []string
+ if chain == nil {
+ return vars
+ }
+
+ for _, expr := range chain.AllExpression() {
+ if varName := e.extractVariableFromExpression(expr); varName != "" {
+ vars = append(vars, varName)
+ }
+ }
+
+ return vars
+}
+
+// extractVariableFromExpression walks the expression AST to find a simple variable reference
+func (e *ASTExecutor) extractVariableFromExpression(expr cyantlr.IExpressionContext) string {
+ if expr == nil {
+ return ""
+ }
+
+ // Walk down the expression tree to find Atom -> Symbol
+ // Expression -> XorExpression -> AndExpression -> NotExpression -> ComparisonExpression
+ // -> AddSubExpression -> MultDivExpression -> PowerExpression -> UnaryAddSubExpression
+ // -> AtomicExpression -> PropertyOrLabelExpression -> PropertyExpression -> Atom
+
+ xors := expr.AllXorExpression()
+ if len(xors) != 1 {
+ return ""
+ }
+
+ ands := xors[0].AllAndExpression()
+ if len(ands) != 1 {
+ return ""
+ }
+
+ nots := ands[0].AllNotExpression()
+ if len(nots) != 1 {
+ return ""
+ }
+
+ comp := nots[0].ComparisonExpression()
+ if comp == nil {
+ return ""
+ }
+
+ adds := comp.AllAddSubExpression()
+ if len(adds) != 1 {
+ return ""
+ }
+
+ mults := adds[0].AllMultDivExpression()
+ if len(mults) != 1 {
+ return ""
+ }
+
+ powers := mults[0].AllPowerExpression()
+ if len(powers) != 1 {
+ return ""
+ }
+
+ unarys := powers[0].AllUnaryAddSubExpression()
+ if len(unarys) != 1 {
+ return ""
+ }
+
+ atomic := unarys[0].AtomicExpression()
+ if atomic == nil {
+ return ""
+ }
+
+ propOrLabel := atomic.PropertyOrLabelExpression()
+ if propOrLabel == nil {
+ return ""
+ }
+
+ propExpr := propOrLabel.PropertyExpression()
+ if propExpr == nil {
+ return ""
+ }
+
+ // If there are property lookups (dots), it's not a simple variable
+ if len(propExpr.AllDOT()) > 0 {
+ return ""
+ }
+
+ atom := propExpr.Atom()
+ if atom == nil {
+ return ""
+ }
+
+ // Check it's not a function call
+ if atom.FunctionInvocation() != nil {
+ return ""
+ }
+
+ // Get the symbol
+ if sym := atom.Symbol(); sym != nil {
+ return sym.GetText()
+ }
+
+ return ""
+}
+
+// executeSet handles SET clause
+func (e *ASTExecutor) executeSet(set cyantlr.ISetStContext) error {
+ if set == nil {
+ return nil
+ }
+
+ // Process each set item
+ for _, item := range set.AllSetItem() {
+ if err := e.executeSetItem(item); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+// executeSetItem handles a single SET assignment
+func (e *ASTExecutor) executeSetItem(item cyantlr.ISetItemContext) error {
+ if item == nil {
+ return nil
+ }
+
+ // Check for property assignment
+ if propExpr := item.PropertyExpression(); propExpr != nil {
+ return e.executePropertySet(item)
+ }
+
+ return nil
+}
+
+// executePropertySet handles n.prop = value
+func (e *ASTExecutor) executePropertySet(item cyantlr.ISetItemContext) error {
+ propExpr := item.PropertyExpression()
+ if propExpr == nil {
+ return nil
+ }
+
+ // Get variable and property name from property expression text
+ text := propExpr.GetText()
+ dotIdx := strings.Index(text, ".")
+ if dotIdx < 0 {
+ return nil
+ }
+ varName := text[:dotIdx]
+ propName := text[dotIdx+1:]
+
+ // Get value expression
+ exprs := []cyantlr.IExpressionContext{item.Expression()}
+ if len(exprs) < 1 {
+ return nil
+ }
+ value := e.evaluateExpression(exprs[0])
+
+ // Update in matched rows
+ for _, row := range e.matchedRows {
+ val, exists := row[varName]
+ if !exists {
+ continue
+ }
+
+ if nodeMap, ok := val.(map[string]interface{}); ok {
+ if nodeID, ok := nodeMap["_nodeId"].(string); ok {
+ node, err := e.storage.GetNode(storage.NodeID(nodeID))
+ if err != nil {
+ continue
+ }
+ node.Properties[propName] = value
+ if err := e.storage.UpdateNode(node); err == nil {
+ e.result.Stats.PropertiesSet++
+ }
+ }
+ }
+ }
+
+ return nil
+}
+
+// executeRemove handles REMOVE clause
+func (e *ASTExecutor) executeRemove(remove cyantlr.IRemoveStContext) error {
+ if remove == nil {
+ return nil
+ }
+
+ for _, item := range remove.AllRemoveItem() {
+ if err := e.executeRemoveItem(item); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+// executeRemoveItem handles a single REMOVE item
+func (e *ASTExecutor) executeRemoveItem(item cyantlr.IRemoveItemContext) error {
+ if item == nil {
+ return nil
+ }
+
+ // Check for property removal (n.prop)
+ if propExpr := item.PropertyExpression(); propExpr != nil {
+ text := propExpr.GetText()
+ dotIdx := strings.Index(text, ".")
+ if dotIdx < 0 {
+ return nil
+ }
+ varName := text[:dotIdx]
+ propName := text[dotIdx+1:]
+
+ // Remove from matched nodes
+ for _, row := range e.matchedRows {
+ val, exists := row[varName]
+ if !exists {
+ continue
+ }
+
+ if nodeMap, ok := val.(map[string]interface{}); ok {
+ if nodeID, ok := nodeMap["_nodeId"].(string); ok {
+ node, err := e.storage.GetNode(storage.NodeID(nodeID))
+ if err != nil {
+ continue
+ }
+ delete(node.Properties, propName)
+ if err := e.storage.UpdateNode(node); err == nil {
+ e.result.Stats.PropertiesSet++
+ }
+ }
+ }
+ }
+ }
+
+ return nil
+}
+
+// executeMerge handles MERGE clause
+func (e *ASTExecutor) executeMerge(merge cyantlr.IMergeStContext) error {
+ if merge == nil {
+ return nil
+ }
+
+ patternPart := merge.PatternPart()
+ if patternPart == nil {
+ return nil
+ }
+
+ // Try to match first
+ matchResults, _ := e.matchPatternPart(patternPart)
+
+ if len(matchResults) > 0 {
+ // Matched - execute ON MATCH actions
+ e.matchedRows = matchResults
+ for _, action := range merge.AllMergeAction() {
+ if action.MATCH() != nil {
+ if setSt := action.SetSt(); setSt != nil {
+ if err := e.executeSet(setSt); err != nil {
+ return err
+ }
+ }
+ }
+ }
+ } else {
+ // Not matched - create and execute ON CREATE actions
+ if err := e.createPatternPart(patternPart); err != nil {
+ return err
+ }
+
+ // After creation, set up matchedRows from variables for ON CREATE SET
+ // The createPatternPart stores created nodes in e.variables
+ row := make(map[string]interface{})
+ for k, v := range e.variables {
+ row[k] = v
+ }
+ e.matchedRows = []map[string]interface{}{row}
+
+ for _, action := range merge.AllMergeAction() {
+ if action.CREATE() != nil {
+ if setSt := action.SetSt(); setSt != nil {
+ if err := e.executeSet(setSt); err != nil {
+ return err
+ }
+ }
+ }
+ }
+ }
+
+ return nil
+}
+
+// executeReturn handles RETURN clause - uses AST for all evaluation
+func (e *ASTExecutor) executeReturn(ret cyantlr.IReturnStContext) error {
+ if ret == nil {
+ return nil
+ }
+
+ projBody := ret.ProjectionBody()
+ if projBody == nil {
+ return nil
+ }
+
+ projItems := projBody.ProjectionItems()
+ if projItems == nil {
+ return nil
+ }
+
+ // Check for DISTINCT - AST token
+ isDistinct := projBody.DISTINCT() != nil
+
+ // Check for RETURN *
+ if projItems.MULT() != nil {
+ return e.executeReturnStar()
+ }
+
+ // Extract projection info using AST - NO string parsing
+ var projections []cyantlr.ProjectionItemInfo
+ hasAggregation := false
+
+ for _, item := range projItems.AllProjectionItem() {
+ pi := cyantlr.ExtractProjectionItem(item)
+ if pi.IsAggregation {
+ hasAggregation = true
+ }
+ projections = append(projections, pi)
+ }
+
+ // Set columns
+ for _, pi := range projections {
+ e.result.Columns = append(e.result.Columns, pi.Alias)
+ }
+
+ // Create expression evaluator
+ eval := cyantlr.NewExpressionEvaluator(e.params, e.variables)
+
+ // IMPORTANT: Apply ORDER BY on matchedRows BEFORE projection
+ // ORDER BY can reference expressions not in RETURN clause (e.g., ORDER BY n.age when RETURN n.name)
+ if orderBy := projBody.OrderSt(); orderBy != nil {
+ e.applyOrderByMatchedRows(orderBy)
+ }
+
+ if hasAggregation {
+ // Handle aggregation - group by non-aggregated columns
+ var groupKeyExprs []cyantlr.IExpressionContext
+ for _, pi := range projections {
+ if !pi.IsAggregation && pi.Expression != nil {
+ groupKeyExprs = append(groupKeyExprs, pi.Expression)
+ }
+ }
+
+ // Group rows
+ groups := cyantlr.GroupRows(e.matchedRows, groupKeyExprs, eval)
+
+ // Process each group
+ for _, group := range groups {
+ if len(group) == 0 {
+ continue
+ }
+ row := make([]interface{}, len(projections))
+
+ for i, pi := range projections {
+ if pi.IsAggregation {
+ aggInfo := cyantlr.ExtractAggregation(pi.Expression)
+ row[i] = cyantlr.ComputeAggregation(
+ aggInfo.FuncName,
+ aggInfo.Args,
+ aggInfo.IsCountAll,
+ group,
+ eval,
+ )
+ } else if pi.Expression != nil {
+ eval.SetRow(group[0])
+ row[i] = eval.Evaluate(pi.Expression)
+ }
+ }
+ e.result.Rows = append(e.result.Rows, row)
+ }
+ } else {
+ // No aggregation - simple projection using AST evaluator
+ if len(e.matchedRows) > 0 {
+ for _, matchRow := range e.matchedRows {
+ eval.SetRow(matchRow)
+ row := make([]interface{}, len(projections))
+ for i, pi := range projections {
+ if pi.Expression != nil {
+ row[i] = eval.Evaluate(pi.Expression)
+ }
+ }
+ e.result.Rows = append(e.result.Rows, row)
+ }
+ } else if e.matchedRows == nil {
+ // Standalone RETURN without MATCH (e.g., RETURN 'hello', RETURN 42)
+ // Only when matchedRows is nil (no MATCH ran), not when empty (MATCH found nothing)
+ eval.SetRow(e.variables)
+ row := make([]interface{}, len(projections))
+ for i, pi := range projections {
+ if pi.Expression != nil {
+ row[i] = eval.Evaluate(pi.Expression)
+ }
+ }
+ e.result.Rows = append(e.result.Rows, row)
+ }
+ // If matchedRows is empty slice (MATCH ran but found nothing), return 0 rows
+ }
+
+ // Apply DISTINCT - deduplicate result rows
+ if isDistinct {
+ e.applyDistinct()
+ }
+
+ // Apply SKIP if present - operates on result rows
+ if skip := projBody.SkipSt(); skip != nil {
+ e.applySkip(skip)
+ }
+
+ // Apply LIMIT if present - operates on result rows
+ if limit := projBody.LimitSt(); limit != nil {
+ e.applyLimit(limit)
+ }
+
+ return nil
+}
+
+// applyDistinct removes duplicate rows from result
+func (e *ASTExecutor) applyDistinct() {
+ if len(e.result.Rows) == 0 {
+ return
+ }
+
+ seen := make(map[string]bool)
+ var unique [][]interface{}
+
+ for _, row := range e.result.Rows {
+ // Create a key from the row values
+ key := fmt.Sprintf("%v", row)
+ if !seen[key] {
+ seen[key] = true
+ unique = append(unique, row)
+ }
+ }
+
+ e.result.Rows = unique
+}
+
+// executeReturnStar handles RETURN *
+func (e *ASTExecutor) executeReturnStar() error {
+ if len(e.matchedRows) == 0 {
+ return nil
+ }
+
+ // Get all column names from first row
+ firstRow := e.matchedRows[0]
+ var columns []string
+ for k := range firstRow {
+ if len(k) == 0 || k[0] != '_' {
+ columns = append(columns, k)
+ }
+ }
+
+ e.result.Columns = columns
+
+ for _, matchRow := range e.matchedRows {
+ row := make([]interface{}, len(columns))
+ for i, col := range columns {
+ row[i] = matchRow[col]
+ }
+ e.result.Rows = append(e.result.Rows, row)
+ }
+
+ return nil
+}
+
+// resolveExpression resolves an expression against a row context
+func (e *ASTExecutor) resolveExpression(expr string, row map[string]interface{}) interface{} {
+ // Check for property access (n.prop)
+ if dotIdx := strings.Index(expr, "."); dotIdx > 0 {
+ varName := expr[:dotIdx]
+ propName := expr[dotIdx+1:]
+ if val, ok := row[varName]; ok {
+ if nodeMap, ok := val.(map[string]interface{}); ok {
+ return nodeMap[propName]
+ }
+ }
+ }
+
+ // Direct variable
+ if val, ok := row[expr]; ok {
+ return val
+ }
+
+ // Literal or function - evaluate
+ return e.evaluateLiteral(expr)
+}
+
+// evaluateLiteral evaluates a literal expression
+func (e *ASTExecutor) evaluateLiteral(text string) interface{} {
+ if i, err := strconv.ParseInt(text, 10, 64); err == nil {
+ return i
+ }
+ if f, err := strconv.ParseFloat(text, 64); err == nil {
+ return f
+ }
+
+ lower := strings.ToLower(text)
+ if lower == "true" {
+ return true
+ }
+ if lower == "false" {
+ return false
+ }
+ if lower == "null" {
+ return nil
+ }
+
+ // String literal
+ if len(text) >= 2 {
+ if (text[0] == '\'' && text[len(text)-1] == '\'') ||
+ (text[0] == '"' && text[len(text)-1] == '"') {
+ return text[1 : len(text)-1]
+ }
+ }
+
+ return text
+}
+
+// executeUnwind handles UNWIND clause
+func (e *ASTExecutor) executeUnwind(unwind cyantlr.IUnwindStContext) error {
+ if unwind == nil {
+ return nil
+ }
+
+ // Get expression and variable
+ expr := unwind.Expression()
+ sym := unwind.Symbol()
+ if expr == nil || sym == nil {
+ return nil
+ }
+
+ varName := sym.GetText()
+
+ // Use AST evaluator for proper list literal parsing
+ eval := cyantlr.NewExpressionEvaluator(e.params, e.variables)
+ listVal := eval.Evaluate(expr)
+
+ // Convert to slice
+ var items []interface{}
+ switch v := listVal.(type) {
+ case []interface{}:
+ items = v
+ case []string:
+ for _, s := range v {
+ items = append(items, s)
+ }
+ default:
+ items = []interface{}{listVal}
+ }
+
+ // Expand rows
+ var newRows []map[string]interface{}
+ if len(e.matchedRows) > 0 {
+ for _, row := range e.matchedRows {
+ for _, item := range items {
+ newRow := make(map[string]interface{})
+ for k, v := range row {
+ newRow[k] = v
+ }
+ newRow[varName] = item
+ newRows = append(newRows, newRow)
+ }
+ }
+ } else {
+ for _, item := range items {
+ newRow := make(map[string]interface{})
+ newRow[varName] = item
+ newRows = append(newRows, newRow)
+ }
+ }
+
+ e.matchedRows = newRows
+ return nil
+}
+
+// executeQueryCall handles CALL procedure inside a query (e.g., CALL db.labels())
+func (e *ASTExecutor) executeQueryCall(call cyantlr.IQueryCallStContext) error {
+ if call == nil {
+ return nil
+ }
+
+ invName := call.InvocationName()
+ if invName == nil {
+ return nil
+ }
+
+ procName := invName.GetText()
+ return e.dispatchProcedure(procName)
+}
+
+// executeCallSubquery handles CALL {} subquery
+func (e *ASTExecutor) executeCallSubquery(call cyantlr.ICallSubqueryContext) error {
+ if call == nil {
+ return nil
+ }
+
+ body := call.SubqueryBody()
+ if body == nil {
+ return nil
+ }
+
+ // Save current state
+ savedVars := make(map[string]interface{})
+ for k, v := range e.variables {
+ savedVars[k] = v
+ }
+
+ // Execute subquery for each input row (or once if no input)
+ inputRows := e.matchedRows
+ if len(inputRows) == 0 {
+ inputRows = []map[string]interface{}{{}}
+ }
+
+ var allResults []map[string]interface{}
+ for _, inputRow := range inputRows {
+ // Set up context with input row variables
+ e.matchedRows = []map[string]interface{}{inputRow}
+ for k, v := range inputRow {
+ e.variables[k] = v
+ }
+
+ // Execute the subquery body statements
+ // SubqueryBody can contain WITH and statements
+ if withSt := body.WithSt(); withSt != nil {
+ if err := e.executeWith(withSt); err != nil {
+ return err
+ }
+ }
+
+ // Collect results
+ for _, row := range e.matchedRows {
+ // Merge input row with subquery results
+ merged := make(map[string]interface{})
+ for k, v := range inputRow {
+ merged[k] = v
+ }
+ for k, v := range row {
+ merged[k] = v
+ }
+ allResults = append(allResults, merged)
+ }
+ }
+
+ // Restore state with combined results
+ e.matchedRows = allResults
+ e.variables = savedVars
+
+ return nil
+}
+
+// executeWith handles WITH clause including aggregation, ORDER BY, SKIP, LIMIT
+func (e *ASTExecutor) executeWith(with cyantlr.IWithStContext) error {
+ if with == nil {
+ return nil
+ }
+
+ projBody := with.ProjectionBody()
+ if projBody == nil {
+ return nil
+ }
+
+ projItems := projBody.ProjectionItems()
+ if projItems == nil {
+ return nil
+ }
+
+ // Extract projection info using antlr package
+ var projections []cyantlr.ProjectionItemInfo
+ hasAggregation := false
+
+ for _, item := range projItems.AllProjectionItem() {
+ pi := cyantlr.ExtractProjectionItem(item)
+ if pi.IsAggregation {
+ hasAggregation = true
+ }
+ projections = append(projections, pi)
+ }
+
+ // Create expression evaluator
+ eval := cyantlr.NewExpressionEvaluator(e.params, e.variables)
+
+ var newRows []map[string]interface{}
+
+ if hasAggregation {
+ // Find grouping keys (non-aggregated columns)
+ var groupKeyExprs []cyantlr.IExpressionContext
+ for _, pi := range projections {
+ if !pi.IsAggregation && pi.Expression != nil {
+ groupKeyExprs = append(groupKeyExprs, pi.Expression)
+ }
+ }
+
+ // Group rows using antlr package
+ groups := cyantlr.GroupRows(e.matchedRows, groupKeyExprs, eval)
+
+ // Process each group
+ for _, group := range groups {
+ if len(group) == 0 {
+ continue
+ }
+ newRow := make(map[string]interface{})
+
+ for _, pi := range projections {
+ if pi.IsAggregation {
+ // Compute aggregation using antlr package
+ aggInfo := cyantlr.ExtractAggregation(pi.Expression)
+ newRow[pi.Alias] = cyantlr.ComputeAggregation(
+ aggInfo.FuncName,
+ aggInfo.Args,
+ aggInfo.IsCountAll,
+ group,
+ eval,
+ )
+ } else if pi.Expression != nil {
+ // Use value from first row in group
+ eval.SetRow(group[0])
+ newRow[pi.Alias] = eval.Evaluate(pi.Expression)
+ }
+ }
+ newRows = append(newRows, newRow)
+ }
+ } else {
+ // No aggregation - simple projection
+ for _, matchRow := range e.matchedRows {
+ eval.SetRow(matchRow)
+ newRow := make(map[string]interface{})
+ for _, pi := range projections {
+ if pi.Expression != nil {
+ newRow[pi.Alias] = eval.Evaluate(pi.Expression)
+ }
+ }
+ newRows = append(newRows, newRow)
+ }
+ }
+
+ e.matchedRows = newRows
+
+ // Apply WHERE if present (acts like HAVING for aggregation)
+ if where := with.Where(); where != nil {
+ filtered, err := e.filterByWhere(e.matchedRows, where)
+ if err != nil {
+ return err
+ }
+ e.matchedRows = filtered
+ }
+
+ // Apply ORDER BY if present - for WITH, operate on matchedRows
+ if orderBy := projBody.OrderSt(); orderBy != nil {
+ e.applyOrderByMatchedRows(orderBy)
+ }
+
+ // Apply SKIP if present - for WITH, operate on matchedRows
+ if skip := projBody.SkipSt(); skip != nil {
+ e.applySkipMatchedRows(skip)
+ }
+
+ // Apply LIMIT if present - for WITH, operate on matchedRows
+ if limit := projBody.LimitSt(); limit != nil {
+ e.applyLimitMatchedRows(limit)
+ }
+
+ return nil
+}
+
+// aggregationInfo holds info extracted from AST about an aggregation
+type aggregationInfo struct {
+ isAggregation bool
+ isCountAll bool // COUNT(*)
+ funcName string // COUNT, SUM, AVG, MIN, MAX, COLLECT
+ args []cyantlr.IExpressionContext // function arguments
+ isDistinct bool
+}
+
+// extractAggregationFromAST walks the expression AST to find aggregation functions
+// Returns aggregation info extracted purely from AST nodes - no string parsing
+func (e *ASTExecutor) extractAggregationFromAST(expr cyantlr.IExpressionContext) aggregationInfo {
+ result := aggregationInfo{}
+ if expr == nil {
+ return result
+ }
+
+ // Walk down the AST to find the Atom
+ atom := e.findAtomInExpression(expr)
+ if atom == nil {
+ return result
+ }
+
+ // Check for COUNT(*) - has its own AST node type
+ if countAll := atom.CountAll(); countAll != nil {
+ result.isAggregation = true
+ result.isCountAll = true
+ result.funcName = "COUNT"
+ return result
+ }
+
+ // Check for FunctionInvocation
+ funcInvoc := atom.FunctionInvocation()
+ if funcInvoc == nil {
+ return result
+ }
+
+ // Get function name from InvocationName AST node
+ invocName := funcInvoc.InvocationName()
+ if invocName == nil {
+ return result
+ }
+
+ // InvocationName contains Symbol nodes - get them from AST
+ symbols := invocName.AllSymbol()
+ if len(symbols) == 0 {
+ return result
+ }
+
+ // Get the function name by checking token type of first symbol
+ firstSym := symbols[0]
+
+ // Check if it's an aggregation function by examining the token type
+ // Aggregation functions: COUNT, SUM, AVG, MIN, MAX, COLLECT
+ // These are identified by checking if the Symbol contains specific tokens
+ if e.isAggregationToken(firstSym) {
+ result.isAggregation = true
+ result.funcName = e.getAggregationFuncName(firstSym)
+ result.isDistinct = funcInvoc.DISTINCT() != nil
+
+ // Get arguments from ExpressionChain
+ if exprChain := funcInvoc.ExpressionChain(); exprChain != nil {
+ result.args = exprChain.AllExpression()
+ }
+ }
+
+ return result
+}
+
+// findAtomInExpression walks down the expression tree to find the Atom node
+func (e *ASTExecutor) findAtomInExpression(expr cyantlr.IExpressionContext) cyantlr.IAtomContext {
+ if expr == nil {
+ return nil
+ }
+
+ xors := expr.AllXorExpression()
+ if len(xors) != 1 {
+ return nil
+ }
+
+ ands := xors[0].AllAndExpression()
+ if len(ands) != 1 {
+ return nil
+ }
+
+ nots := ands[0].AllNotExpression()
+ if len(nots) != 1 {
+ return nil
+ }
+
+ comp := nots[0].ComparisonExpression()
+ if comp == nil {
+ return nil
+ }
+
+ adds := comp.AllAddSubExpression()
+ if len(adds) != 1 {
+ return nil
+ }
+
+ mults := adds[0].AllMultDivExpression()
+ if len(mults) != 1 {
+ return nil
+ }
+
+ powers := mults[0].AllPowerExpression()
+ if len(powers) != 1 {
+ return nil
+ }
+
+ unarys := powers[0].AllUnaryAddSubExpression()
+ if len(unarys) != 1 {
+ return nil
+ }
+
+ atomic := unarys[0].AtomicExpression()
+ if atomic == nil {
+ return nil
+ }
+
+ propOrLabel := atomic.PropertyOrLabelExpression()
+ if propOrLabel == nil {
+ return nil
+ }
+
+ propExpr := propOrLabel.PropertyExpression()
+ if propExpr == nil {
+ return nil
+ }
+
+ return propExpr.Atom()
+}
+
+// isAggregationToken checks if a Symbol AST node represents an aggregation function
+// by checking the token types present in the node
+func (e *ASTExecutor) isAggregationToken(sym cyantlr.ISymbolContext) bool {
+ if sym == nil {
+ return false
+ }
+
+ // Check for COUNT token
+ if sym.COUNT() != nil {
+ return true
+ }
+
+ // Check for ID token and see if it matches aggregation function names
+ // SUM, AVG, MIN, MAX, COLLECT are parsed as ID tokens
+ if id := sym.ID(); id != nil {
+ text := id.GetText()
+ switch text {
+ case "SUM", "sum", "AVG", "avg", "MIN", "min", "MAX", "max", "COLLECT", "collect":
+ return true
+ }
+ }
+
+ return false
+}
+
+// getAggregationFuncName returns the normalized aggregation function name from a Symbol
+func (e *ASTExecutor) getAggregationFuncName(sym cyantlr.ISymbolContext) string {
+ if sym == nil {
+ return ""
+ }
+
+ // COUNT has its own token
+ if sym.COUNT() != nil {
+ return "COUNT"
+ }
+
+ // Others are ID tokens
+ if id := sym.ID(); id != nil {
+ text := id.GetText()
+ switch text {
+ case "SUM", "sum":
+ return "SUM"
+ case "AVG", "avg":
+ return "AVG"
+ case "MIN", "min":
+ return "MIN"
+ case "MAX", "max":
+ return "MAX"
+ case "COLLECT", "collect":
+ return "COLLECT"
+ }
+ }
+
+ return ""
+}
+
+// groupRows groups rows by the specified keys
+func (e *ASTExecutor) groupRows(rows []map[string]interface{}, keys []string) [][]map[string]interface{} {
+ if len(keys) == 0 {
+ // No grouping keys = all rows in one group
+ return [][]map[string]interface{}{rows}
+ }
+
+ // Use map to group by key values
+ groupMap := make(map[string][]map[string]interface{})
+ order := []string{} // Preserve order
+
+ for _, row := range rows {
+ // Build group key
+ var keyParts []string
+ for _, k := range keys {
+ val := e.resolveExpression(k, row)
+ keyParts = append(keyParts, fmt.Sprintf("%v", val))
+ }
+ groupKey := strings.Join(keyParts, "\x00")
+
+ if _, exists := groupMap[groupKey]; !exists {
+ order = append(order, groupKey)
+ }
+ groupMap[groupKey] = append(groupMap[groupKey], row)
+ }
+
+ // Return in order
+ var result [][]map[string]interface{}
+ for _, k := range order {
+ result = append(result, groupMap[k])
+ }
+ return result
+}
+
+// computeAggregation computes an aggregation function over a group
+func (e *ASTExecutor) computeAggregation(funcName, arg string, group []map[string]interface{}) interface{} {
+ switch funcName {
+ case "COUNT":
+ if arg == "*" {
+ return int64(len(group))
+ }
+ // COUNT non-null values
+ count := int64(0)
+ for _, row := range group {
+ val := e.resolveExpression(arg, row)
+ if val != nil {
+ count++
+ }
+ }
+ return count
+
+ case "SUM":
+ sum := float64(0)
+ for _, row := range group {
+ val := e.resolveExpression(arg, row)
+ sum += e.toFloat64(val)
+ }
+ // Return int64 if whole number
+ if sum == float64(int64(sum)) {
+ return int64(sum)
+ }
+ return sum
+
+ case "AVG":
+ if len(group) == 0 {
+ return nil
+ }
+ sum := float64(0)
+ count := 0
+ for _, row := range group {
+ val := e.resolveExpression(arg, row)
+ if val != nil {
+ sum += e.toFloat64(val)
+ count++
+ }
+ }
+ if count == 0 {
+ return nil
+ }
+ return sum / float64(count)
+
+ case "MIN":
+ var minVal interface{}
+ for _, row := range group {
+ val := e.resolveExpression(arg, row)
+ if val == nil {
+ continue
+ }
+ if minVal == nil || e.compareValues(val, minVal) < 0 {
+ minVal = val
+ }
+ }
+ return minVal
+
+ case "MAX":
+ var maxVal interface{}
+ for _, row := range group {
+ val := e.resolveExpression(arg, row)
+ if val == nil {
+ continue
+ }
+ if maxVal == nil || e.compareValues(val, maxVal) > 0 {
+ maxVal = val
+ }
+ }
+ return maxVal
+
+ case "COLLECT":
+ var result []interface{}
+ for _, row := range group {
+ val := e.resolveExpression(arg, row)
+ result = append(result, val)
+ }
+ return result
+ }
+
+ return nil
+}
+
+// toFloat64 converts a value to float64
+func (e *ASTExecutor) toFloat64(val interface{}) float64 {
+ switch v := val.(type) {
+ case int64:
+ return float64(v)
+ case int:
+ return float64(v)
+ case float64:
+ return v
+ case float32:
+ return float64(v)
+ case string:
+ if f, err := strconv.ParseFloat(v, 64); err == nil {
+ return f
+ }
+ }
+ return 0
+}
+
+// compareValues compares two values, returns -1, 0, or 1
+func (e *ASTExecutor) compareValues(a, b interface{}) int {
+ // Try numeric comparison
+ aNum, aIsNum := e.toNumeric(a)
+ bNum, bIsNum := e.toNumeric(b)
+ if aIsNum && bIsNum {
+ if aNum < bNum {
+ return -1
+ } else if aNum > bNum {
+ return 1
+ }
+ return 0
+ }
+
+ // String comparison
+ aStr := fmt.Sprintf("%v", a)
+ bStr := fmt.Sprintf("%v", b)
+ if aStr < bStr {
+ return -1
+ } else if aStr > bStr {
+ return 1
+ }
+ return 0
+}
+
+// toNumeric converts a value to float64 if possible
+func (e *ASTExecutor) toNumeric(val interface{}) (float64, bool) {
+ switch v := val.(type) {
+ case int64:
+ return float64(v), true
+ case int:
+ return float64(v), true
+ case float64:
+ return v, true
+ case float32:
+ return float64(v), true
+ }
+ return 0, false
+}
+
+// applySkip removes first N rows from result
+func (e *ASTExecutor) applySkip(skip cyantlr.ISkipStContext) {
+ if skip == nil {
+ return
+ }
+
+ expr := skip.Expression()
+ if expr == nil {
+ return
+ }
+
+ eval := cyantlr.NewExpressionEvaluator(e.params, e.variables)
+ skipVal := eval.Evaluate(expr)
+ n := int(cyantlr.ToFloat64(skipVal))
+
+ if n > 0 && n < len(e.result.Rows) {
+ e.result.Rows = e.result.Rows[n:]
+ } else if n >= len(e.result.Rows) {
+ e.result.Rows = nil
+ }
+}
+
+// applyLimit keeps only first N rows in result
+func (e *ASTExecutor) applyLimit(limit cyantlr.ILimitStContext) {
+ if limit == nil {
+ return
+ }
+
+ expr := limit.Expression()
+ if expr == nil {
+ return
+ }
+
+ eval := cyantlr.NewExpressionEvaluator(e.params, e.variables)
+ limitVal := eval.Evaluate(expr)
+ n := int(cyantlr.ToFloat64(limitVal))
+
+ if n >= 0 && n < len(e.result.Rows) {
+ e.result.Rows = e.result.Rows[:n]
+ }
+}
+
+// applyOrderByMatchedRows sorts matchedRows for WITH clause
+func (e *ASTExecutor) applyOrderByMatchedRows(order cyantlr.IOrderStContext) {
+ if order == nil || len(e.matchedRows) == 0 {
+ return
+ }
+
+ sortItems := cyantlr.ExtractSortItems(order)
+ if len(sortItems) == 0 {
+ return
+ }
+
+ eval := cyantlr.NewExpressionEvaluator(e.params, e.variables)
+
+ sort.SliceStable(e.matchedRows, func(i, j int) bool {
+ for _, item := range sortItems {
+ if item.Expression == nil {
+ continue
+ }
+
+ eval.SetRow(e.matchedRows[i])
+ valA := eval.Evaluate(item.Expression)
+
+ eval.SetRow(e.matchedRows[j])
+ valB := eval.Evaluate(item.Expression)
+
+ cmp := cyantlr.CompareValues(valA, valB)
+ if cmp != 0 {
+ if item.IsDesc {
+ return cmp > 0
+ }
+ return cmp < 0
+ }
+ }
+ return false
+ })
+}
+
+// applySkipMatchedRows removes first N rows from matchedRows for WITH clause
+func (e *ASTExecutor) applySkipMatchedRows(skip cyantlr.ISkipStContext) {
+ if skip == nil {
+ return
+ }
+
+ expr := skip.Expression()
+ if expr == nil {
+ return
+ }
+
+ eval := cyantlr.NewExpressionEvaluator(e.params, e.variables)
+ skipVal := eval.Evaluate(expr)
+ n := int(cyantlr.ToFloat64(skipVal))
+
+ if n > 0 && n < len(e.matchedRows) {
+ e.matchedRows = e.matchedRows[n:]
+ } else if n >= len(e.matchedRows) {
+ e.matchedRows = nil
+ }
+}
+
+// applyLimitMatchedRows keeps only first N rows in matchedRows for WITH clause
+func (e *ASTExecutor) applyLimitMatchedRows(limit cyantlr.ILimitStContext) {
+ if limit == nil {
+ return
+ }
+
+ expr := limit.Expression()
+ if expr == nil {
+ return
+ }
+
+ eval := cyantlr.NewExpressionEvaluator(e.params, e.variables)
+ limitVal := eval.Evaluate(expr)
+ n := int(cyantlr.ToFloat64(limitVal))
+
+ if n >= 0 && n < len(e.matchedRows) {
+ e.matchedRows = e.matchedRows[:n]
+ }
+}
+
+// executeStandaloneCall handles standalone CALL procedure
+func (e *ASTExecutor) executeStandaloneCall(call cyantlr.IStandaloneCallContext) error {
+ if call == nil {
+ return nil
+ }
+
+ invName := call.InvocationName()
+ if invName == nil {
+ return nil
+ }
+
+ return e.dispatchProcedure(invName.GetText())
+}
+
+// dispatchProcedure routes procedure calls to their implementations
+func (e *ASTExecutor) dispatchProcedure(procName string) error {
+ // Normalize - remove trailing ()
+ if len(procName) > 2 && procName[len(procName)-2:] == "()" {
+ procName = procName[:len(procName)-2]
+ }
+
+ switch procName {
+ case "db.labels":
+ return e.callDbLabels()
+ case "db.relationshipTypes":
+ return e.callDbRelationshipTypes()
+ case "db.propertyKeys":
+ return e.callDbPropertyKeys()
+ case "db.indexes":
+ return e.callDbIndexes()
+ case "db.constraints":
+ return e.callDbConstraints()
+ case "db.schema.nodeTypeProperties":
+ return e.callDbSchemaNodeTypeProperties()
+ case "db.schema.relTypeProperties":
+ return e.callDbSchemaRelTypeProperties()
+ default:
+ // Check for procedure prefix patterns
+ if len(procName) > 3 && procName[:3] == "db." {
+ // Unknown db.* procedure - return empty result
+ return nil
+ }
+ return fmt.Errorf("unknown procedure: %s", procName)
+ }
+}
+
+// callDbLabels implements CALL db.labels()
+func (e *ASTExecutor) callDbLabels() error {
+ labels := make(map[string]bool)
+ for _, node := range e.storage.GetAllNodes() {
+ for _, label := range node.Labels {
+ labels[label] = true
+ }
+ }
+
+ e.result.Columns = []string{"label"}
+ for label := range labels {
+ e.result.Rows = append(e.result.Rows, []interface{}{label})
+ }
+ return nil
+}
+
+// callDbRelationshipTypes implements CALL db.relationshipTypes()
+func (e *ASTExecutor) callDbRelationshipTypes() error {
+ types := make(map[string]bool)
+ // Get relationship types by iterating through all nodes' edges
+ for _, node := range e.storage.GetAllNodes() {
+ edges, _ := e.storage.GetOutgoingEdges(node.ID)
+ for _, edge := range edges {
+ types[edge.Type] = true
+ }
+ }
+
+ e.result.Columns = []string{"relationshipType"}
+ for t := range types {
+ e.result.Rows = append(e.result.Rows, []interface{}{t})
+ }
+ return nil
+}
+
+// callDbPropertyKeys implements CALL db.propertyKeys()
+func (e *ASTExecutor) callDbPropertyKeys() error {
+ keys := make(map[string]bool)
+ for _, node := range e.storage.GetAllNodes() {
+ for k := range node.Properties {
+ keys[k] = true
+ }
+ }
+
+ e.result.Columns = []string{"propertyKey"}
+ for k := range keys {
+ e.result.Rows = append(e.result.Rows, []interface{}{k})
+ }
+ return nil
+}
+
+// callDbIndexes implements CALL db.indexes()
+func (e *ASTExecutor) callDbIndexes() error {
+ e.result.Columns = []string{"name", "type", "labelsOrTypes", "properties", "state"}
+ // Get indexes from storage if available
+ if indexer, ok := e.storage.(interface {
+ GetIndexes() []map[string]interface{}
+ }); ok {
+ for _, idx := range indexer.GetIndexes() {
+ e.result.Rows = append(e.result.Rows, []interface{}{
+ idx["name"], idx["type"], idx["labelsOrTypes"], idx["properties"], idx["state"],
+ })
+ }
+ }
+ return nil
+}
+
+// callDbConstraints implements CALL db.constraints()
+func (e *ASTExecutor) callDbConstraints() error {
+ e.result.Columns = []string{"name", "type", "entityType", "labelsOrTypes", "properties"}
+ // Get constraints from storage if available
+ if constrainer, ok := e.storage.(interface {
+ GetConstraints() []map[string]interface{}
+ }); ok {
+ for _, c := range constrainer.GetConstraints() {
+ e.result.Rows = append(e.result.Rows, []interface{}{
+ c["name"], c["type"], c["entityType"], c["labelsOrTypes"], c["properties"],
+ })
+ }
+ }
+ return nil
+}
+
+// callDbSchemaNodeTypeProperties implements CALL db.schema.nodeTypeProperties()
+func (e *ASTExecutor) callDbSchemaNodeTypeProperties() error {
+ e.result.Columns = []string{"nodeType", "nodeLabels", "propertyName", "propertyTypes", "mandatory"}
+
+ // Collect property info per label
+ labelProps := make(map[string]map[string]bool)
+ for _, node := range e.storage.GetAllNodes() {
+ for _, label := range node.Labels {
+ if labelProps[label] == nil {
+ labelProps[label] = make(map[string]bool)
+ }
+ for prop := range node.Properties {
+ labelProps[label][prop] = true
+ }
+ }
+ }
+
+ for label, props := range labelProps {
+ for prop := range props {
+ e.result.Rows = append(e.result.Rows, []interface{}{
+ ":" + label,
+ []string{label},
+ prop,
+ []string{"Any"},
+ false,
+ })
+ }
+ }
+ return nil
+}
+
+// callDbSchemaRelTypeProperties implements CALL db.schema.relTypeProperties()
+func (e *ASTExecutor) callDbSchemaRelTypeProperties() error {
+ e.result.Columns = []string{"relType", "propertyName", "propertyTypes", "mandatory"}
+
+ // Collect property info per relationship type
+ typeProps := make(map[string]map[string]bool)
+ for _, node := range e.storage.GetAllNodes() {
+ edges, _ := e.storage.GetOutgoingEdges(node.ID)
+ for _, edge := range edges {
+ if typeProps[edge.Type] == nil {
+ typeProps[edge.Type] = make(map[string]bool)
+ }
+ for prop := range edge.Properties {
+ typeProps[edge.Type][prop] = true
+ }
+ }
+ }
+
+ for relType, props := range typeProps {
+ for prop := range props {
+ e.result.Rows = append(e.result.Rows, []interface{}{
+ ":" + relType,
+ prop,
+ []string{"Any"},
+ false,
+ })
+ }
+ }
+ return nil
+}
+
+// executeShowCommand handles SHOW commands
+func (e *ASTExecutor) executeShowCommand(show cyantlr.IShowCommandContext) error {
+ text := show.GetText()
+
+ if strings.Contains(strings.ToUpper(text), "INDEXES") {
+ e.result.Columns = []string{"name", "type", "labelsOrTypes", "properties"}
+ // Return empty - no indexes by default
+ return nil
+ }
+
+ if strings.Contains(strings.ToUpper(text), "CONSTRAINTS") {
+ e.result.Columns = []string{"name", "type", "entityType", "labelsOrTypes", "properties"}
+ return nil
+ }
+
+ return nil
+}
+
+// executeSchemaCommand handles schema commands
+func (e *ASTExecutor) executeSchemaCommand(schema cyantlr.ISchemaCommandContext) error {
+ // Schema commands are no-ops in memory mode
+ return nil
+}
+
+// filterByWhere filters rows using WHERE clause - delegates to antlr package
+func (e *ASTExecutor) filterByWhere(rows []map[string]interface{}, where cyantlr.IWhereContext) ([]map[string]interface{}, error) {
+ if where == nil {
+ return rows, nil
+ }
+
+ expr := where.Expression()
+ if expr == nil {
+ return rows, nil
+ }
+
+ eval := cyantlr.NewExpressionEvaluator(e.params, e.variables)
+
+ var result []map[string]interface{}
+ for _, row := range rows {
+ eval.SetRow(row)
+ if eval.EvaluateWhere(expr) {
+ result = append(result, row)
+ }
+ }
+
+ return result, nil
+}
+
+// evaluateAtomicExprInRow evaluates an AtomicExpression in row context
+func (e *ASTExecutor) evaluateAtomicExprInRow(atomic cyantlr.IAtomicExpressionContext, row map[string]interface{}) interface{} {
+ if atomic == nil {
+ return nil
+ }
+
+ propOrLabel := atomic.PropertyOrLabelExpression()
+ if propOrLabel == nil {
+ return nil
+ }
+
+ return e.evaluatePropertyOrLabelExprInRow(propOrLabel, row)
+}
+
+// evaluatePropertyOrLabelExprInRow evaluates property access from AST
+func (e *ASTExecutor) evaluatePropertyOrLabelExprInRow(propOrLabel cyantlr.IPropertyOrLabelExpressionContext, row map[string]interface{}) interface{} {
+ if propOrLabel == nil {
+ return nil
+ }
+
+ propExpr := propOrLabel.PropertyExpression()
+ if propExpr == nil {
+ return nil
+ }
+
+ // Get the atom (variable or literal)
+ atom := propExpr.Atom()
+ if atom == nil {
+ return nil
+ }
+
+ // Get base value
+ baseVal := e.evaluateAtomInRow(atom, row)
+
+ // Check for property access (DOT tokens in PropertyExpression)
+ dots := propExpr.AllDOT()
+ if len(dots) == 0 {
+ return baseVal
+ }
+
+ // Get property names from Name nodes after each DOT
+ names := propExpr.AllName()
+ currentVal := baseVal
+ for _, name := range names {
+ propName := name.GetText()
+ if nodeMap, ok := currentVal.(map[string]interface{}); ok {
+ currentVal = nodeMap[propName]
+ } else {
+ return nil
+ }
+ }
+
+ return currentVal
+}
+
+// evaluateAtomInRow evaluates an Atom in row context
+func (e *ASTExecutor) evaluateAtomInRow(atom cyantlr.IAtomContext, row map[string]interface{}) interface{} {
+ if atom == nil {
+ return nil
+ }
+
+ // Check for literal
+ if lit := atom.Literal(); lit != nil {
+ return e.evaluateLiteralAST(lit)
+ }
+
+ // Check for parameter
+ if param := atom.Parameter(); param != nil {
+ // Get parameter name from $ followed by symbol or numLit
+ if sym := param.Symbol(); sym != nil {
+ if val, ok := e.params[sym.GetText()]; ok {
+ return val
+ }
+ }
+ return nil
+ }
+
+ // Check for symbol (variable reference)
+ if sym := atom.Symbol(); sym != nil {
+ varName := sym.GetText()
+ if val, ok := row[varName]; ok {
+ return val
+ }
+ if val, ok := e.variables[varName]; ok {
+ return val
+ }
+ return nil
+ }
+
+ // Check for parenthesized expression
+ if paren := atom.ParenthesizedExpression(); paren != nil {
+ if innerExpr := paren.Expression(); innerExpr != nil {
+ // Recursively evaluate
+ return e.evaluateExpressionInRowFull(innerExpr, row)
+ }
+ }
+
+ return nil
+}
+
+// evaluateLiteralAST evaluates a literal from AST
+func (e *ASTExecutor) evaluateLiteralAST(lit cyantlr.ILiteralContext) interface{} {
+ if lit == nil {
+ return nil
+ }
+
+ // Boolean
+ if boolLit := lit.BoolLit(); boolLit != nil {
+ if boolLit.TRUE() != nil {
+ return true
+ }
+ return false
+ }
+
+ // Null
+ if lit.NULL_W() != nil {
+ return nil
+ }
+
+ // Number
+ if numLit := lit.NumLit(); numLit != nil {
+ if floatLit := numLit.FLOAT(); floatLit != nil {
+ if f, err := strconv.ParseFloat(floatLit.GetText(), 64); err == nil {
+ return f
+ }
+ }
+ if intLit := numLit.IntegerLit(); intLit != nil {
+ if i, err := strconv.ParseInt(intLit.GetText(), 10, 64); err == nil {
+ return i
+ }
+ }
+ }
+
+ // String
+ if strLit := lit.StringLit(); strLit != nil {
+ text := strLit.GetText()
+ // Remove quotes - the AST gives us the raw token with quotes
+ if len(text) >= 2 {
+ return text[1 : len(text)-1]
+ }
+ return text
+ }
+
+ // Char
+ if charLit := lit.CharLit(); charLit != nil {
+ text := charLit.GetText()
+ if len(text) >= 2 {
+ return text[1 : len(text)-1]
+ }
+ return text
+ }
+
+ // List
+ if listLit := lit.ListLit(); listLit != nil {
+ if exprChain := listLit.ExpressionChain(); exprChain != nil {
+ var result []interface{}
+ for _, expr := range exprChain.AllExpression() {
+ result = append(result, e.evaluateExpression(expr))
+ }
+ return result
+ }
+ return []interface{}{}
+ }
+
+ // Map
+ if mapLit := lit.MapLit(); mapLit != nil {
+ result := make(map[string]interface{})
+ for _, pair := range mapLit.AllMapPair() {
+ if name := pair.Name(); name != nil {
+ if expr := pair.Expression(); expr != nil {
+ result[name.GetText()] = e.evaluateExpression(expr)
+ }
+ }
+ }
+ return result
+ }
+
+ return nil
+}
+
+// evaluateExpressionInRowFull evaluates a full expression in row context - delegates to antlr package
+func (e *ASTExecutor) evaluateExpressionInRowFull(expr cyantlr.IExpressionContext, row map[string]interface{}) interface{} {
+ if expr == nil {
+ return nil
+ }
+
+ eval := cyantlr.NewExpressionEvaluator(e.params, e.variables)
+ eval.SetRow(row)
+ return eval.Evaluate(expr)
+}
+
+// isTruthy checks if a value is truthy
+func (e *ASTExecutor) isTruthy(val interface{}) bool {
+ if val == nil {
+ return false
+ }
+ switch v := val.(type) {
+ case bool:
+ return v
+ case int64:
+ return v != 0
+ case float64:
+ return v != 0
+ case string:
+ return v != ""
+ }
+ return true
+}
+
+// extendWithChain extends match results with relationship chain
+func (e *ASTExecutor) extendWithChain(rows []map[string]interface{}, chain cyantlr.IPatternElemChainContext) ([]map[string]interface{}, error) {
+ if chain == nil {
+ return rows, nil
+ }
+
+ relPattern := chain.RelationshipPattern()
+ nodePattern := chain.NodePattern()
+ if relPattern == nil || nodePattern == nil {
+ return rows, nil
+ }
+
+ // Extract relationship and node info
+ relVar, relType, _, isForward := e.extractRelationshipPattern(relPattern)
+ endVar, endLabels, endProps := e.extractNodePattern(nodePattern)
+
+ var newRows []map[string]interface{}
+
+ for _, row := range rows {
+ // Find the starting node from the row
+ var startNodeID string
+ for _, val := range row {
+ if nodeMap, ok := val.(map[string]interface{}); ok {
+ if id, ok := nodeMap["_nodeId"].(string); ok {
+ startNodeID = id
+ break
+ }
+ }
+ }
+
+ if startNodeID == "" {
+ continue
+ }
+
+ // Get edges from this node
+ var edges []*storage.Edge
+ if isForward {
+ edges, _ = e.storage.GetOutgoingEdges(storage.NodeID(startNodeID))
+ } else {
+ edges, _ = e.storage.GetIncomingEdges(storage.NodeID(startNodeID))
+ }
+
+ // Filter by type if specified
+ if relType != "" {
+ filtered := make([]*storage.Edge, 0)
+ for _, edge := range edges {
+ if edge.Type == relType {
+ filtered = append(filtered, edge)
+ }
+ }
+ edges = filtered
+ }
+
+ // For each matching edge, get the end node
+ for _, edge := range edges {
+ var endNodeID storage.NodeID
+ if isForward {
+ endNodeID = edge.EndNode
+ } else {
+ endNodeID = edge.StartNode
+ }
+
+ endNode, err := e.storage.GetNode(endNodeID)
+ if err != nil {
+ continue
+ }
+
+ // Check labels
+ if len(endLabels) > 0 {
+ hasLabel := false
+ for _, label := range endLabels {
+ for _, nodeLabel := range endNode.Labels {
+ if label == nodeLabel {
+ hasLabel = true
+ break
+ }
+ }
+ }
+ if !hasLabel {
+ continue
+ }
+ }
+
+ // Check properties
+ if len(endProps) > 0 && !e.nodeMatchesProps(endNode, endProps) {
+ continue
+ }
+
+ // Create new row with relationship and end node
+ newRow := make(map[string]interface{})
+ for k, v := range row {
+ newRow[k] = v
+ }
+
+ if relVar != "" {
+ newRow[relVar] = map[string]interface{}{
+ "_edgeId": string(edge.ID),
+ "_type": edge.Type,
+ }
+ }
+
+ if endVar != "" {
+ newRow[endVar] = e.nodeToMap(endNode)
+ }
+
+ newRows = append(newRows, newRow)
+ }
+ }
+
+ return newRows, nil
+}
+
+// joinMatches joins two match result sets
+func (e *ASTExecutor) joinMatches(a, b []map[string]interface{}) []map[string]interface{} {
+ var result []map[string]interface{}
+ for _, rowA := range a {
+ for _, rowB := range b {
+ merged := make(map[string]interface{})
+ for k, v := range rowA {
+ merged[k] = v
+ }
+ for k, v := range rowB {
+ merged[k] = v
+ }
+ result = append(result, merged)
+ }
+ }
+ return result
+}
diff --git a/nornicdb/pkg/cypher/executor_factory.go b/nornicdb/pkg/cypher/executor_factory.go
new file mode 100644
index 0000000..f1054ff
--- /dev/null
+++ b/nornicdb/pkg/cypher/executor_factory.go
@@ -0,0 +1,66 @@
+// Package cypher - Executor factory for creating the appropriate executor based on config.
+//
+// Usage:
+//
+// // Create executor based on NORNICDB_EXECUTOR_MODE env var
+// exec := cypher.NewExecutor(store)
+//
+// // Or explicitly specify mode
+// exec := cypher.NewExecutorWithMode(store, config.ExecutorModeHybrid)
+package cypher
+
+import (
+ "github.com/orneryd/nornicdb/pkg/config"
+ "github.com/orneryd/nornicdb/pkg/storage"
+)
+
+// NewCypherExecutor creates a new Cypher executor based on the configured mode.
+// The mode is determined by the NORNICDB_EXECUTOR_MODE environment variable:
+// - "nornic": Fast string-based parser
+// - "antlr": Full ANTLR AST-based parser
+// - "hybrid" (default): Fast execution + background AST building
+func NewCypherExecutor(store storage.Engine) CypherExecutor {
+ return NewCypherExecutorWithMode(store, config.GetExecutorMode())
+}
+
+// NewCypherExecutorWithMode creates a new Cypher executor with a specific mode.
+func NewCypherExecutorWithMode(store storage.Engine, mode config.ExecutorMode) CypherExecutor {
+ switch mode {
+ case config.ExecutorModeANTLR:
+ return NewASTExecutor(store)
+ case config.ExecutorModeHybrid:
+ return NewHybridExecutor(store, DefaultHybridConfig())
+ case config.ExecutorModeNornic:
+ fallthrough
+ default:
+ return NewStorageExecutor(store)
+ }
+}
+
+// ExecutorInfo contains information about the current executor
+type ExecutorInfo struct {
+ Mode string `json:"mode"`
+ Description string `json:"description"`
+}
+
+// GetExecutorInfo returns information about the current executor mode
+func GetExecutorInfo() ExecutorInfo {
+ mode := config.GetExecutorMode()
+ switch mode {
+ case config.ExecutorModeANTLR:
+ return ExecutorInfo{
+ Mode: string(mode),
+ Description: "ANTLR AST-based parser - full parse tree, slower execution",
+ }
+ case config.ExecutorModeHybrid:
+ return ExecutorInfo{
+ Mode: string(mode),
+ Description: "Hybrid executor - fast string execution + background AST building",
+ }
+ default:
+ return ExecutorInfo{
+ Mode: string(config.ExecutorModeNornic),
+ Description: "Nornic string-based parser - fastest execution",
+ }
+ }
+}
diff --git a/nornicdb/pkg/cypher/executor_factory_test.go b/nornicdb/pkg/cypher/executor_factory_test.go
new file mode 100644
index 0000000..0423344
--- /dev/null
+++ b/nornicdb/pkg/cypher/executor_factory_test.go
@@ -0,0 +1,151 @@
+// Package cypher - Tests for executor factory
+package cypher
+
+import (
+ "context"
+ "os"
+ "testing"
+
+ "github.com/orneryd/nornicdb/pkg/config"
+ "github.com/orneryd/nornicdb/pkg/storage"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func TestFactory_DefaultMode(t *testing.T) {
+ // Reset to default
+ os.Unsetenv(config.EnvExecutorMode)
+ config.SetExecutorMode(config.ExecutorModeHybrid)
+
+ store := storage.NewMemoryEngine()
+ exec := NewCypherExecutor(store)
+
+ // Should be hybrid by default
+ _, ok := exec.(*HybridExecutor)
+ assert.True(t, ok, "Default executor should be HybridExecutor")
+
+ // Cleanup if hybrid
+ if h, ok := exec.(*HybridExecutor); ok {
+ h.Close()
+ }
+}
+
+func TestFactory_NornicMode(t *testing.T) {
+ defer config.WithExecutorMode(config.ExecutorModeNornic)()
+
+ store := storage.NewMemoryEngine()
+ exec := NewCypherExecutor(store)
+
+ _, ok := exec.(*StorageExecutor)
+ assert.True(t, ok, "Nornic mode should use StorageExecutor")
+}
+
+func TestFactory_ANTLRMode(t *testing.T) {
+ defer config.WithExecutorMode(config.ExecutorModeANTLR)()
+
+ store := storage.NewMemoryEngine()
+ exec := NewCypherExecutor(store)
+
+ _, ok := exec.(*ASTExecutor)
+ assert.True(t, ok, "ANTLR mode should use ASTExecutor")
+}
+
+func TestFactory_HybridMode(t *testing.T) {
+ defer config.WithExecutorMode(config.ExecutorModeHybrid)()
+
+ store := storage.NewMemoryEngine()
+ exec := NewCypherExecutor(store)
+
+ h, ok := exec.(*HybridExecutor)
+ assert.True(t, ok, "Hybrid mode should use HybridExecutor")
+
+ if h != nil {
+ h.Close()
+ }
+}
+
+func TestFactory_AllModesExecute(t *testing.T) {
+ modes := []config.ExecutorMode{
+ config.ExecutorModeNornic,
+ config.ExecutorModeANTLR,
+ config.ExecutorModeHybrid,
+ }
+
+ for _, mode := range modes {
+ t.Run(string(mode), func(t *testing.T) {
+ defer config.WithExecutorMode(mode)()
+
+ store := storage.NewMemoryEngine()
+ exec := NewCypherExecutor(store)
+ ctx := context.Background()
+
+ // All executors should handle basic queries
+ _, err := exec.Execute(ctx, "CREATE (n:Test {name: 'test'})", nil)
+ require.NoError(t, err)
+
+ result, err := exec.Execute(ctx, "MATCH (n:Test) RETURN n.name", nil)
+ require.NoError(t, err)
+ assert.Equal(t, 1, len(result.Rows))
+ assert.Equal(t, "test", result.Rows[0][0])
+
+ // Cleanup
+ if h, ok := exec.(*HybridExecutor); ok {
+ h.Close()
+ }
+ })
+ }
+}
+
+func TestFactory_EnvVarLoading(t *testing.T) {
+ tests := []struct {
+ envValue string
+ expectedMode config.ExecutorMode
+ }{
+ {"nornic", config.ExecutorModeNornic},
+ {"NORNIC", config.ExecutorModeNornic},
+ {"antlr", config.ExecutorModeANTLR},
+ {"ANTLR", config.ExecutorModeANTLR},
+ {"hybrid", config.ExecutorModeHybrid},
+ {"HYBRID", config.ExecutorModeHybrid},
+ {" hybrid ", config.ExecutorModeHybrid}, // trimmed
+ }
+
+ for _, tc := range tests {
+ t.Run(tc.envValue, func(t *testing.T) {
+ os.Setenv(config.EnvExecutorMode, tc.envValue)
+ defer os.Unsetenv(config.EnvExecutorMode)
+
+ // Re-init config
+ config.SetExecutorMode(config.ExecutorModeHybrid) // reset
+ // Manually parse like init does
+ mode := config.ExecutorMode(tc.envValue)
+ if mode == "nornic" || mode == "NORNIC" {
+ config.SetExecutorMode(config.ExecutorModeNornic)
+ } else if mode == "antlr" || mode == "ANTLR" {
+ config.SetExecutorMode(config.ExecutorModeANTLR)
+ } else {
+ config.SetExecutorMode(config.ExecutorModeHybrid)
+ }
+
+ assert.Equal(t, tc.expectedMode, config.GetExecutorMode())
+ })
+ }
+}
+
+func TestFactory_GetExecutorInfo(t *testing.T) {
+ modes := []config.ExecutorMode{
+ config.ExecutorModeNornic,
+ config.ExecutorModeANTLR,
+ config.ExecutorModeHybrid,
+ }
+
+ for _, mode := range modes {
+ t.Run(string(mode), func(t *testing.T) {
+ defer config.WithExecutorMode(mode)()
+
+ info := GetExecutorInfo()
+ assert.NotEmpty(t, info.Mode)
+ assert.NotEmpty(t, info.Description)
+ })
+ }
+}
diff --git a/nornicdb/pkg/cypher/executor_interface.go b/nornicdb/pkg/cypher/executor_interface.go
new file mode 100644
index 0000000..bbd59b6
--- /dev/null
+++ b/nornicdb/pkg/cypher/executor_interface.go
@@ -0,0 +1,223 @@
+// Package cypher - Executor interface for A/B testing between implementations.
+package cypher
+
+import (
+ "context"
+ "sync/atomic"
+ "time"
+)
+
+// CypherExecutor is the interface that both StorageExecutor (string-based)
+// and ASTExecutor (ANTLR-based) implement.
+type CypherExecutor interface {
+ // Execute runs a Cypher query and returns results
+ Execute(ctx context.Context, cypher string, params map[string]interface{}) (*ExecuteResult, error)
+
+ // SetNodeCreatedCallback sets a callback for node creation events
+ SetNodeCreatedCallback(cb NodeCreatedCallback)
+
+ // SetEmbedder sets the query embedder for vector operations
+ SetEmbedder(embedder QueryEmbedder)
+}
+
+// ExecutorType identifies which executor implementation to use
+type ExecutorType int
+
+const (
+ ExecutorTypeString ExecutorType = iota // String-based StorageExecutor
+ ExecutorTypeAST // ANTLR AST-based ASTExecutor
+)
+
+// ABExecutor wraps both executor implementations for A/B testing.
+// It can run queries through either or both executors and compare results.
+type ABExecutor struct {
+ stringExecutor CypherExecutor // StorageExecutor
+ astExecutor CypherExecutor // ASTExecutor (may be nil if not available)
+
+ // Which executor to use for production queries
+ activeExecutor atomic.Int32
+
+ // Stats collection
+ stringStats ExecutorStats
+ astStats ExecutorStats
+
+ // Whether to run both and compare (for testing)
+ compareMode atomic.Bool
+}
+
+// ExecutorStats tracks performance metrics for an executor
+type ExecutorStats struct {
+ TotalQueries atomic.Int64
+ TotalErrors atomic.Int64
+ TotalDuration atomic.Int64 // nanoseconds
+ MinDuration atomic.Int64 // nanoseconds
+ MaxDuration atomic.Int64 // nanoseconds
+}
+
+// NewABExecutor creates a new A/B testing executor
+func NewABExecutor(stringExec, astExec CypherExecutor) *ABExecutor {
+ ab := &ABExecutor{
+ stringExecutor: stringExec,
+ astExecutor: astExec,
+ }
+ ab.activeExecutor.Store(int32(ExecutorTypeString)) // Default to string executor
+ ab.stringStats.MinDuration.Store(int64(^uint64(0) >> 1)) // Max int64
+ ab.astStats.MinDuration.Store(int64(^uint64(0) >> 1))
+ return ab
+}
+
+// SetActiveExecutor switches which executor handles production queries
+func (ab *ABExecutor) SetActiveExecutor(t ExecutorType) {
+ ab.activeExecutor.Store(int32(t))
+}
+
+// GetActiveExecutor returns the current active executor type
+func (ab *ABExecutor) GetActiveExecutor() ExecutorType {
+ return ExecutorType(ab.activeExecutor.Load())
+}
+
+// EnableCompareMode enables running both executors and comparing results
+func (ab *ABExecutor) EnableCompareMode(enabled bool) {
+ ab.compareMode.Store(enabled)
+}
+
+// Execute runs the query through the active executor
+func (ab *ABExecutor) Execute(ctx context.Context, cypher string, params map[string]interface{}) (*ExecuteResult, error) {
+ if ab.compareMode.Load() && ab.astExecutor != nil {
+ return ab.executeCompare(ctx, cypher, params)
+ }
+
+ // Normal execution through active executor
+ active := ExecutorType(ab.activeExecutor.Load())
+ if active == ExecutorTypeAST && ab.astExecutor != nil {
+ return ab.executeWithStats(ctx, cypher, params, ab.astExecutor, &ab.astStats)
+ }
+ return ab.executeWithStats(ctx, cypher, params, ab.stringExecutor, &ab.stringStats)
+}
+
+// executeWithStats runs query and collects timing stats
+func (ab *ABExecutor) executeWithStats(ctx context.Context, cypher string, params map[string]interface{}, exec CypherExecutor, stats *ExecutorStats) (*ExecuteResult, error) {
+ start := time.Now()
+ result, err := exec.Execute(ctx, cypher, params)
+ duration := time.Since(start).Nanoseconds()
+
+ stats.TotalQueries.Add(1)
+ stats.TotalDuration.Add(duration)
+
+ // Update min/max
+ for {
+ old := stats.MinDuration.Load()
+ if duration >= old || stats.MinDuration.CompareAndSwap(old, duration) {
+ break
+ }
+ }
+ for {
+ old := stats.MaxDuration.Load()
+ if duration <= old || stats.MaxDuration.CompareAndSwap(old, duration) {
+ break
+ }
+ }
+
+ if err != nil {
+ stats.TotalErrors.Add(1)
+ }
+
+ return result, err
+}
+
+// executeCompare runs both executors and compares results
+func (ab *ABExecutor) executeCompare(ctx context.Context, cypher string, params map[string]interface{}) (*ExecuteResult, error) {
+ // Run string executor
+ stringStart := time.Now()
+ stringResult, stringErr := ab.stringExecutor.Execute(ctx, cypher, params)
+ stringDuration := time.Since(stringStart)
+ ab.stringStats.TotalQueries.Add(1)
+ ab.stringStats.TotalDuration.Add(stringDuration.Nanoseconds())
+ if stringErr != nil {
+ ab.stringStats.TotalErrors.Add(1)
+ }
+
+ // Run AST executor
+ astStart := time.Now()
+ astResult, astErr := ab.astExecutor.Execute(ctx, cypher, params)
+ astDuration := time.Since(astStart)
+ ab.astStats.TotalQueries.Add(1)
+ ab.astStats.TotalDuration.Add(astDuration.Nanoseconds())
+ if astErr != nil {
+ ab.astStats.TotalErrors.Add(1)
+ }
+
+ // Log comparison (in production, you'd want more sophisticated comparison)
+ _ = stringResult
+ _ = astResult
+ _ = stringDuration
+ _ = astDuration
+
+ // Return result from active executor
+ if ExecutorType(ab.activeExecutor.Load()) == ExecutorTypeAST {
+ return astResult, astErr
+ }
+ return stringResult, stringErr
+}
+
+// SetNodeCreatedCallback sets callback on both executors
+func (ab *ABExecutor) SetNodeCreatedCallback(cb func(nodeID string)) {
+ if ab.stringExecutor != nil {
+ ab.stringExecutor.SetNodeCreatedCallback(cb)
+ }
+ if ab.astExecutor != nil {
+ ab.astExecutor.SetNodeCreatedCallback(cb)
+ }
+}
+
+// SetEmbedder sets embedder on both executors
+func (ab *ABExecutor) SetEmbedder(embedder QueryEmbedder) {
+ if ab.stringExecutor != nil {
+ ab.stringExecutor.SetEmbedder(embedder)
+ }
+ if ab.astExecutor != nil {
+ ab.astExecutor.SetEmbedder(embedder)
+ }
+}
+
+// GetStats returns performance stats for both executors
+func (ab *ABExecutor) GetStats() (stringStats, astStats ExecutorStats) {
+ return ab.stringStats, ab.astStats
+}
+
+// GetStatsReport returns a formatted stats comparison
+func (ab *ABExecutor) GetStatsReport() map[string]interface{} {
+ sTotal := ab.stringStats.TotalQueries.Load()
+ aTotal := ab.astStats.TotalQueries.Load()
+
+ var sAvg, aAvg float64
+ if sTotal > 0 {
+ sAvg = float64(ab.stringStats.TotalDuration.Load()) / float64(sTotal) / 1e6 // ms
+ }
+ if aTotal > 0 {
+ aAvg = float64(ab.astStats.TotalDuration.Load()) / float64(aTotal) / 1e6 // ms
+ }
+
+ return map[string]interface{}{
+ "string_executor": map[string]interface{}{
+ "total_queries": sTotal,
+ "total_errors": ab.stringStats.TotalErrors.Load(),
+ "avg_ms": sAvg,
+ "min_ms": float64(ab.stringStats.MinDuration.Load()) / 1e6,
+ "max_ms": float64(ab.stringStats.MaxDuration.Load()) / 1e6,
+ },
+ "ast_executor": map[string]interface{}{
+ "total_queries": aTotal,
+ "total_errors": ab.astStats.TotalErrors.Load(),
+ "avg_ms": aAvg,
+ "min_ms": float64(ab.astStats.MinDuration.Load()) / 1e6,
+ "max_ms": float64(ab.astStats.MaxDuration.Load()) / 1e6,
+ },
+ "speedup": func() float64 {
+ if aAvg == 0 {
+ return 0
+ }
+ return sAvg / aAvg // >1 means AST is faster
+ }(),
+ }
+}
diff --git a/nornicdb/pkg/cypher/executor_mode_test.go b/nornicdb/pkg/cypher/executor_mode_test.go
new file mode 100644
index 0000000..ab3bf34
--- /dev/null
+++ b/nornicdb/pkg/cypher/executor_mode_test.go
@@ -0,0 +1,526 @@
+// Package cypher - Comprehensive test coverage for all executor modes.
+//
+// Tests verify that nornic, antlr, and hybrid modes all produce identical results
+// for the same queries, ensuring compatibility across implementations.
+package cypher
+
+import (
+ "context"
+ "fmt"
+ "testing"
+ "time"
+
+ "github.com/orneryd/nornicdb/pkg/config"
+ "github.com/orneryd/nornicdb/pkg/storage"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+// testQuery represents a query to test across all modes
+type testQuery struct {
+ name string
+ setup []string // Setup queries to run first
+ query string
+ params map[string]interface{}
+ expectRows int
+ expectCols int
+ expectError bool
+ skipANTLR bool // Skip for ANTLR if not yet implemented
+}
+
+// coreQueries are queries that all modes must support identically
+var coreQueries = []testQuery{
+ // Basic RETURN
+ {
+ name: "literal_integer",
+ query: "RETURN 42",
+ expectRows: 1,
+ expectCols: 1,
+ },
+ {
+ name: "literal_string",
+ query: "RETURN 'hello'",
+ expectRows: 1,
+ expectCols: 1,
+ },
+ {
+ name: "literal_float",
+ query: "RETURN 3.14",
+ expectRows: 1,
+ expectCols: 1,
+ },
+ {
+ name: "literal_boolean_true",
+ query: "RETURN true",
+ expectRows: 1,
+ expectCols: 1,
+ },
+ {
+ name: "literal_boolean_false",
+ query: "RETURN false",
+ expectRows: 1,
+ expectCols: 1,
+ },
+ {
+ name: "literal_null",
+ query: "RETURN null",
+ expectRows: 1,
+ expectCols: 1,
+ },
+ {
+ name: "arithmetic_addition",
+ query: "RETURN 1 + 2",
+ expectRows: 1,
+ expectCols: 1,
+ },
+ {
+ name: "arithmetic_complex",
+ query: "RETURN 10 * 2 + 5 - 3",
+ expectRows: 1,
+ expectCols: 1,
+ },
+ {
+ name: "string_concatenation",
+ query: "RETURN 'hello' + ' ' + 'world'",
+ expectRows: 1,
+ expectCols: 1,
+ },
+
+ // CREATE and MATCH
+ {
+ name: "create_single_node",
+ query: "CREATE (n:TestNode {name: 'test'})",
+ expectRows: 0,
+ expectCols: 0,
+ },
+ {
+ name: "match_all_nodes",
+ setup: []string{"CREATE (n:Person {name: 'Alice'})", "CREATE (n:Person {name: 'Bob'})"},
+ query: "MATCH (n:Person) RETURN n.name ORDER BY n.name",
+ expectRows: 2,
+ expectCols: 1,
+ },
+ {
+ name: "match_with_property",
+ setup: []string{"CREATE (n:User {name: 'Charlie', age: 30})"},
+ query: "MATCH (n:User {name: 'Charlie'}) RETURN n.age",
+ expectRows: 1,
+ expectCols: 1,
+ },
+ {
+ name: "match_with_where",
+ setup: []string{"CREATE (n:Item {price: 10})", "CREATE (n:Item {price: 20})", "CREATE (n:Item {price: 30})"},
+ query: "MATCH (n:Item) WHERE n.price > 15 RETURN n.price ORDER BY n.price",
+ expectRows: 2,
+ expectCols: 1,
+ },
+
+ // Aggregations
+ {
+ name: "count_all",
+ setup: []string{"CREATE (n:Counter)", "CREATE (n:Counter)", "CREATE (n:Counter)"},
+ query: "MATCH (n:Counter) RETURN count(n)",
+ expectRows: 1,
+ expectCols: 1,
+ },
+ {
+ name: "sum_values",
+ setup: []string{"CREATE (n:Val {v: 10})", "CREATE (n:Val {v: 20})", "CREATE (n:Val {v: 30})"},
+ query: "MATCH (n:Val) RETURN sum(n.v)",
+ expectRows: 1,
+ expectCols: 1,
+ },
+ {
+ name: "avg_values",
+ setup: []string{"CREATE (n:Num {x: 10})", "CREATE (n:Num {x: 20})"},
+ query: "MATCH (n:Num) RETURN avg(n.x)",
+ expectRows: 1,
+ expectCols: 1,
+ },
+ {
+ name: "min_max",
+ setup: []string{"CREATE (n:Score {s: 5})", "CREATE (n:Score {s: 10})", "CREATE (n:Score {s: 15})"},
+ query: "MATCH (n:Score) RETURN min(n.s), max(n.s)",
+ expectRows: 1,
+ expectCols: 2,
+ },
+
+ // Parameters
+ {
+ name: "parameter_string",
+ setup: []string{"CREATE (n:Param {name: 'ParamTest'})"},
+ query: "MATCH (n:Param {name: $name}) RETURN n.name",
+ params: map[string]interface{}{"name": "ParamTest"},
+ expectRows: 1,
+ expectCols: 1,
+ },
+ {
+ name: "parameter_number",
+ setup: []string{"CREATE (n:NumParam {val: 100})"},
+ query: "MATCH (n:NumParam) WHERE n.val = $val RETURN n.val",
+ params: map[string]interface{}{"val": 100},
+ expectRows: 1,
+ expectCols: 1,
+ },
+
+ // LIMIT and SKIP
+ {
+ name: "limit",
+ setup: []string{"CREATE (n:Limited)", "CREATE (n:Limited)", "CREATE (n:Limited)", "CREATE (n:Limited)", "CREATE (n:Limited)"},
+ query: "MATCH (n:Limited) RETURN n LIMIT 3",
+ expectRows: 3,
+ expectCols: 1,
+ },
+ {
+ name: "skip",
+ setup: []string{"CREATE (n:Skipped {i: 1})", "CREATE (n:Skipped {i: 2})", "CREATE (n:Skipped {i: 3})"},
+ query: "MATCH (n:Skipped) RETURN n.i ORDER BY n.i SKIP 1",
+ expectRows: 2,
+ expectCols: 1,
+ },
+ {
+ name: "skip_and_limit",
+ setup: []string{"CREATE (n:SL {i: 1})", "CREATE (n:SL {i: 2})", "CREATE (n:SL {i: 3})", "CREATE (n:SL {i: 4})", "CREATE (n:SL {i: 5})"},
+ query: "MATCH (n:SL) RETURN n.i ORDER BY n.i SKIP 1 LIMIT 2",
+ expectRows: 2,
+ expectCols: 1,
+ },
+
+ // Relationships
+ {
+ name: "create_relationship",
+ setup: []string{"CREATE (a:RelA {name: 'A'})", "CREATE (b:RelB {name: 'B'})"},
+ query: "MATCH (a:RelA), (b:RelB) CREATE (a)-[:KNOWS]->(b)",
+ expectRows: 0,
+ expectCols: 0,
+ },
+ {
+ name: "match_relationship",
+ setup: []string{"CREATE (a:Friend {name: 'X'})-[:FRIENDS_WITH]->(b:Friend {name: 'Y'})"},
+ query: "MATCH (a:Friend)-[:FRIENDS_WITH]->(b:Friend) RETURN a.name, b.name",
+ expectRows: 1,
+ expectCols: 2,
+ },
+
+ // DELETE
+ {
+ name: "delete_node",
+ setup: []string{"CREATE (n:ToDelete {name: 'delete_me'})"},
+ query: "MATCH (n:ToDelete) DELETE n",
+ expectRows: 0,
+ expectCols: 0,
+ },
+
+ // SET
+ {
+ name: "set_property",
+ setup: []string{"CREATE (n:Settable {name: 'original'})"},
+ query: "MATCH (n:Settable) SET n.name = 'updated' RETURN n.name",
+ expectRows: 1,
+ expectCols: 1,
+ },
+
+ // DISTINCT
+ {
+ name: "distinct_values",
+ setup: []string{"CREATE (n:Dup {v: 'a'})", "CREATE (n:Dup {v: 'a'})", "CREATE (n:Dup {v: 'b'})"},
+ query: "MATCH (n:Dup) RETURN DISTINCT n.v ORDER BY n.v",
+ expectRows: 2,
+ expectCols: 1,
+ },
+
+ // Aliasing
+ {
+ name: "alias",
+ query: "RETURN 42 AS answer",
+ expectRows: 1,
+ expectCols: 1,
+ },
+
+ // Multiple RETURN items
+ {
+ name: "multiple_returns",
+ setup: []string{"CREATE (n:Multi {a: 1, b: 2, c: 3})"},
+ query: "MATCH (n:Multi) RETURN n.a, n.b, n.c",
+ expectRows: 1,
+ expectCols: 3,
+ },
+
+ // No results
+ {
+ name: "no_matches",
+ query: "MATCH (n:NonExistent) RETURN n",
+ expectRows: 0,
+ expectCols: 1,
+ },
+}
+
+func TestExecutorModes_CoreQueries(t *testing.T) {
+ modes := []config.ExecutorMode{
+ config.ExecutorModeNornic,
+ config.ExecutorModeANTLR,
+ config.ExecutorModeHybrid,
+ }
+
+ for _, tc := range coreQueries {
+ t.Run(tc.name, func(t *testing.T) {
+ results := make(map[config.ExecutorMode]*ExecuteResult)
+
+ for _, mode := range modes {
+ if tc.skipANTLR && mode == config.ExecutorModeANTLR {
+ continue
+ }
+
+ t.Run(string(mode), func(t *testing.T) {
+ defer config.WithExecutorMode(mode)()
+
+ store := storage.NewMemoryEngine()
+ exec := NewCypherExecutor(store)
+ ctx := context.Background()
+
+ // Cleanup hybrid executor
+ defer func() {
+ if h, ok := exec.(*HybridExecutor); ok {
+ h.Close()
+ }
+ }()
+
+ // Run setup queries
+ for _, setup := range tc.setup {
+ _, err := exec.Execute(ctx, setup, nil)
+ require.NoError(t, err, "Setup failed: %s", setup)
+ }
+
+ // Run test query
+ result, err := exec.Execute(ctx, tc.query, tc.params)
+
+ if tc.expectError {
+ assert.Error(t, err, "Expected error for query: %s", tc.query)
+ return
+ }
+
+ require.NoError(t, err, "Query failed: %s", tc.query)
+ assert.Equal(t, tc.expectRows, len(result.Rows), "Row count mismatch")
+ if tc.expectCols > 0 && len(result.Rows) > 0 {
+ assert.Equal(t, tc.expectCols, len(result.Rows[0]), "Column count mismatch")
+ }
+
+ results[mode] = result
+ })
+ }
+
+ // Compare results across modes (if we have multiple)
+ if len(results) > 1 {
+ var baseline *ExecuteResult
+ var baselineMode config.ExecutorMode
+ for mode, result := range results {
+ if baseline == nil {
+ baseline = result
+ baselineMode = mode
+ continue
+ }
+
+ // Compare row counts
+ assert.Equal(t, len(baseline.Rows), len(result.Rows),
+ "Row count differs between %s and %s", baselineMode, mode)
+ }
+ }
+ })
+ }
+}
+
+func TestExecutorModes_Performance(t *testing.T) {
+ if testing.Short() {
+ t.Skip("Skipping performance test in short mode")
+ }
+
+ modes := []config.ExecutorMode{
+ config.ExecutorModeNornic,
+ config.ExecutorModeHybrid,
+ // Skip ANTLR for performance - known to be slower
+ }
+
+ query := "MATCH (n:Perf) RETURN count(n)"
+ iterations := 100
+
+ results := make(map[config.ExecutorMode]time.Duration)
+
+ for _, mode := range modes {
+ t.Run(string(mode), func(t *testing.T) {
+ defer config.WithExecutorMode(mode)()
+
+ store := storage.NewMemoryEngine()
+ exec := NewCypherExecutor(store)
+ ctx := context.Background()
+
+ defer func() {
+ if h, ok := exec.(*HybridExecutor); ok {
+ h.Close()
+ }
+ }()
+
+ // Setup data
+ for i := 0; i < 100; i++ {
+ exec.Execute(ctx, fmt.Sprintf("CREATE (n:Perf {i: %d})", i), nil)
+ }
+
+ // Warmup
+ for i := 0; i < 10; i++ {
+ exec.Execute(ctx, query, nil)
+ }
+ time.Sleep(20 * time.Millisecond) // Let hybrid cache warm
+
+ // Benchmark
+ start := time.Now()
+ for i := 0; i < iterations; i++ {
+ _, err := exec.Execute(ctx, query, nil)
+ require.NoError(t, err)
+ }
+ duration := time.Since(start)
+ results[mode] = duration
+
+ avgUs := float64(duration.Microseconds()) / float64(iterations)
+ t.Logf("%s: %.2f Β΅s/op", mode, avgUs)
+ })
+ }
+
+ // Nornic should be similar or faster than hybrid
+ if nornic, ok := results[config.ExecutorModeNornic]; ok {
+ if hybrid, ok := results[config.ExecutorModeHybrid]; ok {
+ // Hybrid should be within 50% of nornic
+ ratio := float64(hybrid) / float64(nornic)
+ t.Logf("Hybrid/Nornic ratio: %.2f", ratio)
+ assert.Less(t, ratio, 1.5, "Hybrid should not be more than 50%% slower than Nornic")
+ }
+ }
+}
+
+func TestExecutorModes_Callbacks(t *testing.T) {
+ modes := []config.ExecutorMode{
+ config.ExecutorModeNornic,
+ config.ExecutorModeHybrid,
+ }
+
+ for _, mode := range modes {
+ t.Run(string(mode), func(t *testing.T) {
+ defer config.WithExecutorMode(mode)()
+
+ store := storage.NewMemoryEngine()
+ exec := NewCypherExecutor(store)
+ ctx := context.Background()
+
+ defer func() {
+ if h, ok := exec.(*HybridExecutor); ok {
+ h.Close()
+ }
+ }()
+
+ // Test SetNodeCreatedCallback
+ var createdNodes []string
+ exec.SetNodeCreatedCallback(func(nodeID string) {
+ createdNodes = append(createdNodes, nodeID)
+ })
+
+ // Create a node
+ _, err := exec.Execute(ctx, "CREATE (n:Callback {name: 'test'})", nil)
+ require.NoError(t, err)
+
+ // Callback should have been called
+ assert.GreaterOrEqual(t, len(createdNodes), 1, "Callback should be called on node creation")
+ })
+ }
+}
+
+func TestExecutorModes_ErrorHandling(t *testing.T) {
+ modes := []config.ExecutorMode{
+ config.ExecutorModeNornic,
+ config.ExecutorModeHybrid,
+ }
+
+ errorQueries := []struct {
+ name string
+ query string
+ }{
+ {"invalid_syntax", "MATC (n) RETURN n"}, // typo
+ {"unclosed_string", "RETURN 'hello"},
+ {"invalid_property_access", "RETURN n.name"}, // n not defined
+ }
+
+ for _, mode := range modes {
+ for _, eq := range errorQueries {
+ t.Run(fmt.Sprintf("%s/%s", mode, eq.name), func(t *testing.T) {
+ defer config.WithExecutorMode(mode)()
+
+ store := storage.NewMemoryEngine()
+ exec := NewCypherExecutor(store)
+ ctx := context.Background()
+
+ defer func() {
+ if h, ok := exec.(*HybridExecutor); ok {
+ h.Close()
+ }
+ }()
+
+ _, err := exec.Execute(ctx, eq.query, nil)
+ // We expect some form of error (either parse or execution)
+ // The specific error may differ between modes, but both should handle gracefully
+ t.Logf("%s error for '%s': %v", mode, eq.name, err)
+ })
+ }
+ }
+}
+
+func TestExecutorModes_Concurrency(t *testing.T) {
+ modes := []config.ExecutorMode{
+ config.ExecutorModeNornic,
+ config.ExecutorModeHybrid,
+ }
+
+ for _, mode := range modes {
+ t.Run(string(mode), func(t *testing.T) {
+ defer config.WithExecutorMode(mode)()
+
+ store := storage.NewMemoryEngine()
+ exec := NewCypherExecutor(store)
+ ctx := context.Background()
+
+ defer func() {
+ if h, ok := exec.(*HybridExecutor); ok {
+ h.Close()
+ }
+ }()
+
+ // Setup data
+ for i := 0; i < 10; i++ {
+ exec.Execute(ctx, fmt.Sprintf("CREATE (n:Concurrent {i: %d})", i), nil)
+ }
+
+ // Run concurrent reads
+ done := make(chan bool)
+ errors := make(chan error, 10)
+
+ for i := 0; i < 10; i++ {
+ go func() {
+ for j := 0; j < 100; j++ {
+ _, err := exec.Execute(ctx, "MATCH (n:Concurrent) RETURN count(n)", nil)
+ if err != nil {
+ errors <- err
+ }
+ }
+ done <- true
+ }()
+ }
+
+ // Wait for all goroutines
+ for i := 0; i < 10; i++ {
+ <-done
+ }
+
+ // Check for errors
+ close(errors)
+ for err := range errors {
+ t.Errorf("Concurrent execution error: %v", err)
+ }
+ })
+ }
+}
diff --git a/nornicdb/pkg/cypher/hybrid_executor.go b/nornicdb/pkg/cypher/hybrid_executor.go
new file mode 100644
index 0000000..ff21f96
--- /dev/null
+++ b/nornicdb/pkg/cypher/hybrid_executor.go
@@ -0,0 +1,316 @@
+// Package cypher - HybridExecutor combines fast string execution with background AST building.
+//
+// Architecture:
+// - Query arrives β String executor handles immediately (fast path)
+// - Background goroutine builds AST and caches it (warm cache)
+// - LLM features use cached AST when available
+// - Best of both: fast execution + rich AST for manipulation
+package cypher
+
+import (
+ "context"
+ "sync"
+ "sync/atomic"
+ "time"
+
+ cyantlr "github.com/orneryd/nornicdb/pkg/cypher/antlr"
+ "github.com/orneryd/nornicdb/pkg/storage"
+)
+
+// HybridExecutor combines fast string-based execution with background AST building.
+// Queries execute immediately via the string parser while AST is built asynchronously.
+type HybridExecutor struct {
+ stringExec *StorageExecutor
+ storage storage.Engine
+
+ // Result cache: query string -> *ExecuteResult
+ resultCache sync.Map
+ resultCacheOn atomic.Bool
+
+ // AST cache: query string -> *cyantlr.ParseResult
+ astCache sync.Map
+
+ // Background AST builder
+ astQueue chan astBuildRequest
+ astQueueSize int
+ workers int
+ shutdown chan struct{}
+ wg sync.WaitGroup
+
+ // Stats
+ stats HybridStats
+
+ // Callbacks
+ nodeCreatedCallback NodeCreatedCallback
+ embedder QueryEmbedder
+}
+
+// astBuildRequest is a request to build AST in background
+type astBuildRequest struct {
+ query string
+}
+
+// HybridStats tracks performance metrics
+type HybridStats struct {
+ StringExecutions atomic.Int64
+ ASTCacheHits atomic.Int64
+ ASTCacheMisses atomic.Int64
+ ASTBuildsQueued atomic.Int64
+ ASTBuildsComplete atomic.Int64
+ ResultCacheHits atomic.Int64
+}
+
+// HybridConfig configures the hybrid executor
+type HybridConfig struct {
+ // Number of background workers for AST building
+ Workers int
+ // Size of the AST build queue
+ QueueSize int
+ // Enable result caching
+ EnableResultCache bool
+}
+
+// DefaultHybridConfig returns sensible defaults
+func DefaultHybridConfig() HybridConfig {
+ return HybridConfig{
+ Workers: 2,
+ QueueSize: 1000,
+ EnableResultCache: false, // Disabled by default (write queries invalidate)
+ }
+}
+
+// NewHybridExecutor creates a new hybrid executor
+func NewHybridExecutor(store storage.Engine, cfg HybridConfig) *HybridExecutor {
+ if cfg.Workers <= 0 {
+ cfg.Workers = 2
+ }
+ if cfg.QueueSize <= 0 {
+ cfg.QueueSize = 1000
+ }
+
+ h := &HybridExecutor{
+ stringExec: NewStorageExecutor(store),
+ storage: store,
+ astQueue: make(chan astBuildRequest, cfg.QueueSize),
+ astQueueSize: cfg.QueueSize,
+ workers: cfg.Workers,
+ shutdown: make(chan struct{}),
+ }
+ h.resultCacheOn.Store(cfg.EnableResultCache)
+
+ // Start background AST workers
+ for i := 0; i < cfg.Workers; i++ {
+ h.wg.Add(1)
+ go h.astWorker()
+ }
+
+ return h
+}
+
+// astWorker processes AST build requests in the background
+func (h *HybridExecutor) astWorker() {
+ defer h.wg.Done()
+
+ for {
+ select {
+ case <-h.shutdown:
+ return
+ case req := <-h.astQueue:
+ // Check if already cached
+ if _, ok := h.astCache.Load(req.query); ok {
+ continue
+ }
+
+ // Build AST (this is the slow part, but we're in background)
+ result, err := cyantlr.Parse(req.query)
+ if err == nil && result != nil {
+ h.astCache.Store(req.query, result)
+ h.stats.ASTBuildsComplete.Add(1)
+ }
+ }
+ }
+}
+
+// Execute runs a query using fast string execution while queueing AST build
+func (h *HybridExecutor) Execute(ctx context.Context, query string, params map[string]interface{}) (*ExecuteResult, error) {
+ // 1. Check result cache first (if enabled)
+ if h.resultCacheOn.Load() {
+ if cached, ok := h.resultCache.Load(query); ok {
+ h.stats.ResultCacheHits.Add(1)
+ return cached.(*ExecuteResult), nil
+ }
+ }
+
+ // 2. Execute via fast string parser
+ h.stats.StringExecutions.Add(1)
+ result, err := h.stringExec.Execute(ctx, query, params)
+
+ // 3. Queue AST build in background (non-blocking)
+ if err == nil {
+ h.queueASTBuild(query)
+ }
+
+ // 4. Optionally cache result
+ if err == nil && h.resultCacheOn.Load() && isReadOnlyQuery(query) {
+ h.resultCache.Store(query, result)
+ }
+
+ return result, err
+}
+
+// queueASTBuild queues an AST build request (non-blocking)
+func (h *HybridExecutor) queueASTBuild(query string) {
+ // Skip if already cached
+ if _, ok := h.astCache.Load(query); ok {
+ h.stats.ASTCacheHits.Add(1)
+ return
+ }
+ h.stats.ASTCacheMisses.Add(1)
+
+ // Non-blocking send to queue
+ select {
+ case h.astQueue <- astBuildRequest{query: query}:
+ h.stats.ASTBuildsQueued.Add(1)
+ default:
+ // Queue full, skip (AST will be built on next occurrence or on-demand)
+ }
+}
+
+// GetAST returns the cached AST for a query, building synchronously if needed
+func (h *HybridExecutor) GetAST(query string) (*cyantlr.ParseResult, error) {
+ // Check cache first
+ if cached, ok := h.astCache.Load(query); ok {
+ h.stats.ASTCacheHits.Add(1)
+ return cached.(*cyantlr.ParseResult), nil
+ }
+
+ // Build synchronously (for LLM features that need it now)
+ result, err := cyantlr.Parse(query)
+ if err == nil && result != nil {
+ h.astCache.Store(query, result)
+ }
+ return result, err
+}
+
+// GetASTIfCached returns the cached AST or nil (never blocks)
+func (h *HybridExecutor) GetASTIfCached(query string) *cyantlr.ParseResult {
+ if cached, ok := h.astCache.Load(query); ok {
+ return cached.(*cyantlr.ParseResult)
+ }
+ return nil
+}
+
+// WaitForAST waits for the AST to be built (with timeout)
+func (h *HybridExecutor) WaitForAST(query string, timeout time.Duration) (*cyantlr.ParseResult, bool) {
+ deadline := time.Now().Add(timeout)
+
+ for time.Now().Before(deadline) {
+ if cached, ok := h.astCache.Load(query); ok {
+ return cached.(*cyantlr.ParseResult), true
+ }
+ time.Sleep(1 * time.Millisecond)
+ }
+
+ return nil, false
+}
+
+// SetNodeCreatedCallback sets the callback for node creation events
+func (h *HybridExecutor) SetNodeCreatedCallback(cb NodeCreatedCallback) {
+ h.nodeCreatedCallback = cb
+ h.stringExec.SetNodeCreatedCallback(cb)
+}
+
+// SetEmbedder sets the query embedder
+func (h *HybridExecutor) SetEmbedder(embedder QueryEmbedder) {
+ h.embedder = embedder
+ h.stringExec.SetEmbedder(embedder)
+}
+
+// InvalidateCache invalidates caches for queries affecting given labels
+func (h *HybridExecutor) InvalidateCache(labels []string) {
+ // For now, just clear all caches on write
+ // TODO: More sophisticated label-based invalidation
+ h.resultCache = sync.Map{}
+}
+
+// ClearCaches clears all caches
+func (h *HybridExecutor) ClearCaches() {
+ h.resultCache = sync.Map{}
+ h.astCache = sync.Map{}
+ cyantlr.ClearCache()
+}
+
+// GetStats returns performance statistics
+func (h *HybridExecutor) GetStats() map[string]interface{} {
+ return map[string]interface{}{
+ "string_executions": h.stats.StringExecutions.Load(),
+ "ast_cache_hits": h.stats.ASTCacheHits.Load(),
+ "ast_cache_misses": h.stats.ASTCacheMisses.Load(),
+ "ast_builds_queued": h.stats.ASTBuildsQueued.Load(),
+ "ast_builds_complete": h.stats.ASTBuildsComplete.Load(),
+ "result_cache_hits": h.stats.ResultCacheHits.Load(),
+ "result_cache_enabled": h.resultCacheOn.Load(),
+ }
+}
+
+// Close shuts down the hybrid executor
+func (h *HybridExecutor) Close() {
+ close(h.shutdown)
+ h.wg.Wait()
+}
+
+// isReadOnlyQuery checks if a query is read-only (safe to cache results)
+func isReadOnlyQuery(query string) bool {
+ // Quick check for write operations
+ upper := toUpperASCII(query)
+ writeKeywords := []string{"CREATE", "DELETE", "SET", "REMOVE", "MERGE", "DETACH"}
+ for _, kw := range writeKeywords {
+ if containsKeyword(upper, kw) {
+ return false
+ }
+ }
+ return true
+}
+
+// toUpperASCII converts to uppercase (ASCII only, fast)
+func toUpperASCII(s string) string {
+ b := make([]byte, len(s))
+ for i := 0; i < len(s); i++ {
+ c := s[i]
+ if c >= 'a' && c <= 'z' {
+ c -= 'a' - 'A'
+ }
+ b[i] = c
+ }
+ return string(b)
+}
+
+// containsKeyword checks if string contains a keyword (word boundary aware)
+func containsKeyword(s, keyword string) bool {
+ idx := 0
+ for {
+ pos := indexAt(s, keyword, idx)
+ if pos < 0 {
+ return false
+ }
+ // Check word boundaries
+ before := pos == 0 || !isAlphaNumericByte(s[pos-1])
+ after := pos+len(keyword) >= len(s) || !isAlphaNumericByte(s[pos+len(keyword)])
+ if before && after {
+ return true
+ }
+ idx = pos + 1
+ }
+}
+
+func indexAt(s, substr string, start int) int {
+ if start >= len(s) {
+ return -1
+ }
+ for i := start; i <= len(s)-len(substr); i++ {
+ if s[i:i+len(substr)] == substr {
+ return i
+ }
+ }
+ return -1
+}
diff --git a/nornicdb/pkg/cypher/hybrid_executor_test.go b/nornicdb/pkg/cypher/hybrid_executor_test.go
new file mode 100644
index 0000000..d9a2ec0
--- /dev/null
+++ b/nornicdb/pkg/cypher/hybrid_executor_test.go
@@ -0,0 +1,248 @@
+// Package cypher - Tests for HybridExecutor
+package cypher
+
+import (
+ "context"
+ "fmt"
+ "testing"
+ "time"
+
+ "github.com/orneryd/nornicdb/pkg/storage"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func setupHybridExecutor(t *testing.T) (*HybridExecutor, context.Context) {
+ store := storage.NewMemoryEngine()
+ exec := NewHybridExecutor(store, DefaultHybridConfig())
+ t.Cleanup(func() { exec.Close() })
+ return exec, context.Background()
+}
+
+func TestHybrid_BasicExecution(t *testing.T) {
+ exec, ctx := setupHybridExecutor(t)
+
+ // Create some data
+ _, err := exec.Execute(ctx, "CREATE (n:Person {name: 'Alice', age: 30})", nil)
+ require.NoError(t, err)
+
+ // Query it
+ result, err := exec.Execute(ctx, "MATCH (n:Person) RETURN n.name", nil)
+ require.NoError(t, err)
+ assert.Equal(t, 1, len(result.Rows))
+ assert.Equal(t, "Alice", result.Rows[0][0])
+}
+
+func TestHybrid_ASTBuildsInBackground(t *testing.T) {
+ exec, ctx := setupHybridExecutor(t)
+
+ query := "MATCH (n:Person) WHERE n.age > 25 RETURN n.name"
+
+ // Execute query - should be fast (string executor)
+ start := time.Now()
+ _, err := exec.Execute(ctx, query, nil)
+ execTime := time.Since(start)
+ require.NoError(t, err)
+
+ t.Logf("Execution time: %v", execTime)
+
+ // AST should NOT be available immediately (building in background)
+ ast := exec.GetASTIfCached(query)
+ // Might or might not be cached yet depending on timing
+
+ // Wait for AST to be built
+ ast, ok := exec.WaitForAST(query, 100*time.Millisecond)
+ assert.True(t, ok, "AST should be built within 100ms")
+ assert.NotNil(t, ast, "AST should not be nil")
+}
+
+func TestHybrid_ASTCacheHit(t *testing.T) {
+ exec, ctx := setupHybridExecutor(t)
+
+ query := "MATCH (n:Test) RETURN count(n)"
+
+ // First execution - queues AST build
+ _, err := exec.Execute(ctx, query, nil)
+ require.NoError(t, err)
+
+ // Wait for AST to be built
+ time.Sleep(50 * time.Millisecond)
+
+ // Second execution - AST should be cached
+ _, err = exec.Execute(ctx, query, nil)
+ require.NoError(t, err)
+ stats2 := exec.GetStats()
+
+ // Check that we got a cache hit on second execution
+ t.Logf("Stats after 2 executions: %+v", stats2)
+ assert.Equal(t, int64(2), stats2["string_executions"])
+}
+
+func TestHybrid_GetASTSynchronous(t *testing.T) {
+ exec, _ := setupHybridExecutor(t)
+
+ query := "RETURN 1 + 2 + 3"
+
+ // GetAST should work even without prior execution
+ ast, err := exec.GetAST(query)
+ require.NoError(t, err)
+ assert.NotNil(t, ast)
+ assert.NotNil(t, ast.Tree)
+}
+
+func TestHybrid_PerformanceComparison(t *testing.T) {
+ if testing.Short() {
+ t.Skip("Skipping performance test in short mode")
+ }
+
+ store := storage.NewMemoryEngine()
+ hybridExec := NewHybridExecutor(store, DefaultHybridConfig())
+ defer hybridExec.Close()
+
+ stringExec := NewStorageExecutor(store)
+ ctx := context.Background()
+
+ // Setup data
+ for i := 0; i < 50; i++ {
+ query := fmt.Sprintf("CREATE (p:Person {name: 'Person%d', age: %d})", i, 20+i)
+ hybridExec.Execute(ctx, query, nil)
+ }
+
+ query := "MATCH (n:Person) RETURN count(n)"
+ iterations := 100
+
+ // Warmup hybrid (builds AST in background)
+ for i := 0; i < 10; i++ {
+ hybridExec.Execute(ctx, query, nil)
+ }
+ time.Sleep(50 * time.Millisecond) // Let AST build complete
+
+ // Benchmark string executor
+ start := time.Now()
+ for i := 0; i < iterations; i++ {
+ stringExec.Execute(ctx, query, nil)
+ }
+ stringTime := time.Since(start)
+
+ // Benchmark hybrid executor
+ start = time.Now()
+ for i := 0; i < iterations; i++ {
+ hybridExec.Execute(ctx, query, nil)
+ }
+ hybridTime := time.Since(start)
+
+ stringAvg := float64(stringTime.Microseconds()) / float64(iterations)
+ hybridAvg := float64(hybridTime.Microseconds()) / float64(iterations)
+
+ t.Logf("String executor: %.2f Β΅s/op", stringAvg)
+ t.Logf("Hybrid executor: %.2f Β΅s/op", hybridAvg)
+ t.Logf("Overhead: %.1f%%", (hybridAvg-stringAvg)/stringAvg*100)
+
+ // Hybrid should have minimal overhead (<20%)
+ assert.Less(t, hybridAvg, stringAvg*1.5, "Hybrid overhead should be less than 50%%")
+}
+
+func TestHybrid_Stats(t *testing.T) {
+ exec, ctx := setupHybridExecutor(t)
+
+ // Execute some queries
+ exec.Execute(ctx, "RETURN 1", nil)
+ exec.Execute(ctx, "RETURN 2", nil)
+ exec.Execute(ctx, "RETURN 1", nil) // Same query again
+
+ time.Sleep(50 * time.Millisecond) // Let AST builds complete
+
+ stats := exec.GetStats()
+ t.Logf("Stats: %+v", stats)
+
+ assert.Equal(t, int64(3), stats["string_executions"])
+ assert.GreaterOrEqual(t, stats["ast_builds_queued"].(int64), int64(2))
+}
+
+func TestHybrid_ReadOnlyDetection(t *testing.T) {
+ tests := []struct {
+ query string
+ readOnly bool
+ }{
+ {"MATCH (n) RETURN n", true},
+ {"RETURN 1 + 2", true},
+ {"CREATE (n:Test)", false},
+ {"MATCH (n) DELETE n", false},
+ {"MATCH (n) SET n.x = 1", false},
+ {"MERGE (n:Test)", false},
+ {"MATCH (n) DETACH DELETE n", false},
+ {"MATCH (n) REMOVE n.x", false},
+ }
+
+ for _, tc := range tests {
+ t.Run(tc.query, func(t *testing.T) {
+ result := isReadOnlyQuery(tc.query)
+ assert.Equal(t, tc.readOnly, result, "Query: %s", tc.query)
+ })
+ }
+}
+
+func TestHybrid_ClearCaches(t *testing.T) {
+ exec, ctx := setupHybridExecutor(t)
+
+ query := "RETURN 42"
+ exec.Execute(ctx, query, nil)
+ time.Sleep(50 * time.Millisecond)
+
+ // Should have cached AST
+ assert.NotNil(t, exec.GetASTIfCached(query))
+
+ // Clear caches
+ exec.ClearCaches()
+
+ // Should be gone
+ assert.Nil(t, exec.GetASTIfCached(query))
+}
+
+func BenchmarkHybrid_Execute(b *testing.B) {
+ store := storage.NewMemoryEngine()
+ exec := NewHybridExecutor(store, DefaultHybridConfig())
+ defer exec.Close()
+ ctx := context.Background()
+
+ // Setup data
+ for i := 0; i < 100; i++ {
+ exec.Execute(ctx, fmt.Sprintf("CREATE (p:Person {name: 'Person%d'})", i), nil)
+ }
+
+ query := "MATCH (n:Person) RETURN count(n)"
+
+ // Warmup
+ for i := 0; i < 10; i++ {
+ exec.Execute(ctx, query, nil)
+ }
+ time.Sleep(50 * time.Millisecond)
+
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ exec.Execute(ctx, query, nil)
+ }
+}
+
+func BenchmarkString_Execute(b *testing.B) {
+ store := storage.NewMemoryEngine()
+ exec := NewStorageExecutor(store)
+ ctx := context.Background()
+
+ // Setup data
+ for i := 0; i < 100; i++ {
+ exec.Execute(ctx, fmt.Sprintf("CREATE (p:Person {name: 'Person%d'})", i), nil)
+ }
+
+ query := "MATCH (n:Person) RETURN count(n)"
+
+ // Warmup
+ for i := 0; i < 10; i++ {
+ exec.Execute(ctx, query, nil)
+ }
+
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ exec.Execute(ctx, query, nil)
+ }
+}
diff --git a/nornicdb/pkg/nornicdb/db.go b/nornicdb/pkg/nornicdb/db.go
index e8b8be6..5d0208a 100644
--- a/nornicdb/pkg/nornicdb/db.go
+++ b/nornicdb/pkg/nornicdb/db.go
@@ -428,8 +428,8 @@ type DB struct {
wal *storage.WAL // Write-ahead log for durability
decay *decay.Manager
inference *inference.Engine
- cypherExecutor *cypher.StorageExecutor
- gpuManager interface{} // *gpu.Manager - interface to avoid circular import
+ cypherExecutor cypher.CypherExecutor // Interface for flexible executor selection
+ gpuManager interface{} // *gpu.Manager - interface to avoid circular import
// Search service (uses pre-computed embeddings from Mimir)
searchService *search.Service
@@ -789,8 +789,17 @@ func Open(dataDir string, config *Config) (*DB, error) {
fmt.Println("β οΈ Using in-memory storage (data will not persist)")
}
- // Initialize Cypher executor
- db.cypherExecutor = cypher.NewStorageExecutor(db.storage)
+ // Initialize Cypher executor based on NORNICDB_EXECUTOR_MODE
+ db.cypherExecutor = cypher.NewCypherExecutor(db.storage)
+ execInfo := cypher.GetExecutorInfo()
+ fmt.Println("")
+ fmt.Println("βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ")
+ fmt.Printf("β π§ CYPHER EXECUTOR MODE: %-45sβ\n", execInfo.Mode)
+ fmt.Printf("β %-64sβ\n", execInfo.Description)
+ fmt.Println("β β")
+ fmt.Println("β Set NORNICDB_EXECUTOR_MODE to: nornic | antlr | hybrid β")
+ fmt.Println("βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ")
+ fmt.Println("")
// Load plugins from configured directory (NORNICDB_PLUGINS_DIR)
pluginsDir := os.Getenv("NORNICDB_PLUGINS_DIR")