Cypher Parser Modes

April 3, 2026 Β· View on GitHub

Environment Variable: NORNICDB_PARSER
Options: nornic (default) | antlr

NornicDB supports two Cypher parser implementations that can be switched at runtime.

Architecture

%%{init: {'theme': 'dark', 'themeVariables': { 'primaryColor': '#1f6feb', 'primaryTextColor': '#c9d1d9', 'primaryBorderColor': '#30363d', 'lineColor': '#8b949e', 'secondaryColor': '#238636', 'tertiaryColor': '#21262d', 'background': '#0d1117', 'mainBkg': '#161b22'}}}%%

flowchart TB
    subgraph ENV["πŸ”§ Configuration"]
        direction LR
        E1["NORNICDB_PARSER"]
        E2["nornic | antlr"]
    end

    Q[/"Cypher Query"/]
    
    Q --> VALIDATE["validateSyntax()"]
    
    VALIDATE --> |"NORNICDB_PARSER=nornic"| NORNIC
    VALIDATE --> |"NORNICDB_PARSER=antlr"| ANTLR
    
    subgraph NORNIC["⚑ Nornic Parser (Default)"]
        direction TB
        N1["String-based validation"]
        N2["Regex + indexOf"]
        N3["Direct execution"]
        N1 --> N2 --> N3
    end
    
    subgraph ANTLR["🌳 ANTLR Parser"]
        direction TB
        A1["ANTLR Lexer"]
        A2["ANTLR Parser"]
        A3["Full Parse Tree"]
        A4["Syntax Validation"]
        A1 --> A2 --> A3 --> A4
    end
    
    NORNIC --> EXEC["Execute Query"]
    ANTLR --> EXEC
    EXEC --> RESULT[("Result")]
    
    style ENV fill:#21262d,stroke:#30363d
    style NORNIC fill:#161b22,stroke:#238636
    style ANTLR fill:#161b22,stroke:#a371f7
    style RESULT fill:#238636,stroke:#3fb950

Real-World Benchmarks (Northwind Database)

Query⚑ Nornic🌳 ANTLRSlowdown
Count all nodes3,272 hz45 hz73x
Count all relationships3,693 hz50 hz74x
Find customer by ID4,213 hz2,153 hz2x
Products supplied by supplier4,023 hz53 hz76x
Supplier→Category traversal3,225 hz22 hz147x
Products with/without orders3,881 hz0.82 hz4,753x
Create/delete relationship3,974 hz62 hz64x

Total test suite time:

ModeTime
⚑ Nornic17.5s
🌳 ANTLR35.3s (2x slower)

Mode Comparison

Feature⚑ Nornic (Default)🌳 ANTLR
Throughput3,000-4,200 ops/sec0.8-2,100 ops/sec
Worst Case-4,753x slower
Error MessagesBasicDetailed (line/column)
Syntax ValidationLenientStrict OpenCypher
Memory UsageLowestHigher
Best ForProductionDevelopment/Debugging

Configuration

# Production (default) - fastest
export NORNICDB_PARSER=nornic

# Development/Debugging - strict validation, better errors
export NORNICDB_PARSER=antlr

Programmatic Switching

import "github.com/orneryd/nornicdb/pkg/config"

// Check current parser
if config.IsNornicParser() {
    // Using fast Nornic parser
}

// Switch to ANTLR temporarily
cleanup := config.WithANTLRParser()
defer cleanup()
// ... queries use ANTLR parser here

// Direct set
config.SetParserType(config.ParserTypeANTLR)
config.SetParserType(config.ParserTypeNornic)

When to Use Each Parser

⚑ Nornic Parser (NORNICDB_PARSER=nornic) β€” Default

Use when:

  • Production deployments
  • Maximum performance is critical
  • Simple, well-tested query patterns
  • High-throughput workloads

Pros:

  • Fastest execution β€” 3,000-4,200 ops/sec
  • πŸ’Ύ Lowest memory β€” No parse tree allocation
  • πŸ”§ Battle-tested β€” Original implementation
  • ⚑ Zero parsing overhead

Cons:

  • πŸ” Basic error messages β€” No line/column info
  • πŸ“ Lenient validation β€” May accept some invalid syntax
  • πŸ› Harder to debug β€” No structured parse tree

🌳 ANTLR Parser (NORNICDB_PARSER=antlr)

Use when:

  • Development and debugging
  • Need detailed syntax error messages
  • Strict OpenCypher compliance required
  • Building query analysis tools

Pros:

  • βœ… Strict validation β€” Full OpenCypher grammar
  • πŸ“ Detailed errors β€” Line and column numbers
  • 🌳 Full parse tree β€” For analysis/tooling
  • πŸ› οΈ Extensible β€” Easy to add new features

Cons:

  • 🐒 Much slower β€” 50-5000x slower than Nornic
  • πŸ’Ύ Higher memory β€” Full parse tree allocation
  • ⏱️ Not for production β€” Too slow for high-throughput

Error Message Comparison

Invalid query: MATCH (n RETURN n (missing closing paren)

ParserError Message
Nornicsyntax error: unbalanced parentheses
ANTLRsyntax error: line 1:9 no viable alternative at input 'MATCH (n RETURN'

Make Targets

# Run entire test suite with ANTLR parser
make antlr-test

# Run cypher tests with both parsers
make test-parsers

# Regenerate ANTLR parser from grammar
make antlr-generate

Files

FileDescription
pkg/config/feature_flags.goParser type configuration
pkg/cypher/executor.govalidateSyntax() dispatcher
pkg/cypher/antlr/ANTLR parser implementation
pkg/cypher/antlr/*.g4ANTLR grammar files

TL;DR: Use nornic (default) for production. Use antlr only for development/debugging when you need detailed error messages.