Skip to content

Latest commit

 

History

History
201 lines (155 loc) · 7.56 KB

File metadata and controls

201 lines (155 loc) · 7.56 KB

GQL C++ Parser Library

This library is a C++ parser, AST (Abstract Syntax Tree) and syntax analyzer implementation for the GQL graph database language (ISO/IEC 39075:2024). It requires C++17 or later and is distributed under the Apache License 2.0.

Contents

GQL Parser and AST

The library is designed to map GQL syntax to C++ types, enabling full static type checking and type safety. The AST does not use virtual functions.

Below are examples demonstrating how GQL expressions are represented in C++ types.

GQL Specification:

<graph pattern> ::=
  [ <match mode> ] <path pattern list>
    [ <keep clause> ]
    [ <graph pattern where clause> ]

<path pattern list> ::=
  <path pattern> [ { <comma> <path pattern> }... ]    

gql C++ Library:

using PathPatternList = std::vector<PathPattern>;

struct GraphPattern {
  std::optional<MatchMode> matchMode;
  PathPatternList patterns;
  std::optional<KeepClause> keep;
  std::optional<GraphPatternWhereClause> where;
};

GQL Specification:

<primitive data-modifying statement> ::=
    <insert statement>
  | <set statement>
  | <remove statement>
  | <delete statement>

gql C++ Library:

using PrimitiveDataModifyingStatement =
    std::variant<InsertStatement, SetStatement, RemoveStatement, DeleteStatement>;

Parser Usage

To parse a GQL query from a string:

#include <gql/parser/parser.h>

void load_query(const char* query) {
  try {
    gql::ast::GQLProgram program = gql::parser::ParseProgram(query);
  } catch (const gql::parser::ParserError& e) {
    std::cerr << "Error: " << e.what() << std::endl;
  }
}

The AST provided by the library follows these principles:

  • Simple structs
  • std::optional for optional child nodes
  • std::variant for alternative child nodes
  • std::vector for sequences of child nodes

The root node of the AST is gql::ast::GQLProgram. All AST nodes are defined in include/gql/ast/nodes/.

Thanks to static typing, traversing the AST should work seamlessly with full IDE support. Handling variants can be somewhat cumbersome, so here’s a recommended approach:

void process(const gql::ast::LinearDataModifyingStatementBody& body) {
  for (const auto& stmt : body.statements) {
    gql::ast::variant_switch(
        stmt,
        [&](const gql::ast::SimpleQueryStatement& value) {
          // Execute simple data-accessing statement
          ...
        },
        [&](const gql::ast::PrimitiveDataModifyingStatement& value) {
          // Execute primitive data-modifying statement
          ...
        },
        [&](const gql::ast::CallProcedureStatement& value) {
          // Execute call procedure statement
          ...
        });
  }
}

In certain cases, the library employs the value_ptr smart pointer class (with type aliases ending in Ptr) to manage recursive types. The parser ensures these pointers are always initialized, allowing safe access without additional checks.

AST Extensibility

The AST data structures are intentionally simple, but you may need to store additional information in the AST beyond the parsing stage.

To facilitate this, you can provide a custom base class for AST nodes. If you define GQL_AST_CUSTOM_NODE_BASE_INCLUDE as a preprocessor macro with a header filename, the specified file will be included before the AST node class definitions. This file can define a custom gql::ast::NodeBase<T> template, allowing you to override the default base class for specific or all AST node types.

Refer to include/gql/ast/nodes/base.h for further details.

GQL Syntax Analyzer

The Syntax Analyzer component performs the following functions:

  • Applies the Syntax Rules of the ISO/IEC 39075:2024 standard to the GQL program code.
  • Reports errors in the GQL program.
  • Checks the fulfillment of Conformance Rules, reporting an error if the GQL program uses an optional GQL feature not supported by this GQL implementation. The list of unsupported features is specified in the client code.
  • Performs transformations of the GQL program as provided by the Syntax Rules.
  • Complements some AST nodes with information (called auxData in the code) that simplifies the execution of the GQL program.

Although the Syntax Analyzer makes relatively few changes to the AST, its use greatly simplifies the code that directly executes the GQL program, removing the need for many checks.

Syntax Analyzer Usage

#include <gql/parser/parser.h>
#include <gql/syntax_analyzer/syntax_analyzer.h>

void analyze_query(const char* query) {
  try {
    gql::ast::GQLProgram program = gql::parser::ParseProgram(query);
    gql::SyntaxAnalyzerConfig config;
    gql::AnalyzeSyntax(program, config);
  } catch (const gql::ParserError& e) {
    std::cerr << "Error: " << e.what() << std::endl;
  }
}

Build

The library uses CMake as its build system. Client code should link against the gql_parser static library for parser component and gql_syntax_analyzer for syntax analyzer.

To build the library:

mkdir build
cd build
cmake ..
make

If your project does not use CMake, you can manually include the library sources in your build system with minimal effort.

GQL Demo Application

The GQL Demo application (located in src/demo) demonstrates how to use the AST and Syntax Analyzer components to build a GQL server implementation. While the AST and Syntax Analyzer components aim for full standard compliance, the set of features implemented in GQL Demo is limited. The GQL Demo code prioritizes readability and brevity over performance - it is not intended for production use and is not optimized. GQL Demo serves as the backend for GQLLab.com.

GQLLab.com Interactive Environment

The GQLLab.com website (currently in active development) utilizes this library as its backend component. The website provides an interactive environment for learning GQL language capabilities and experimenting with queries on small-scale databases. While the GQL implementation on this site is not intended for production use or processing large data volumes, it is being developed to achieve maximum compliance with the ISO/IEC 39075:2024 standard.

The Sample Queries section on the website aims to progressively demonstrate all GQL language features.

Current Status

Parser and AST

The AST and parser components are production-ready with no known bugs. They provide complete coverage of the GQL language syntax as defined in ISO/IEC 39075:2024.

Syntax Analyzer

The Syntax Analyzer is under active development. Current status:

  • Well-supported: Query statements and graph patterns
  • In progress: Value expressions and value handling
  • Ongoing: Reliability improvements and comprehensive testing

The goal is to implement 100% of the Syntax Rules specified in the ISO/IEC 39075:2024 standard.

Demo application and GQLLab.com Backend

Demo application is in active development. This implementation prioritizes:

  • Standards compliance: Full adherence to ISO/IEC 39075:2024
  • Maintainability: Clear, readable code over optimization
  • Educational value: Demonstrating language features comprehensively

Note that this implementation intentionally trades some optional features and performance for simplicity and standard compliance.

License

This library is distributed under the Apache License 2.0.