Skip to content

Commit

Permalink
Query Hints (#27)
Browse files Browse the repository at this point in the history
* removed version 1.0

* added rules for hinting the variable ordering

* query hints for cardinality estimation

* comment

* fixed typos
  • Loading branch information
nkaralis authored and liss-h committed Dec 5, 2024
1 parent 1d50cc0 commit 8e19887
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 639 deletions.
6 changes: 4 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ venv/

# project specific
/sparql-grammer/generated/
SparqlParser.g4
SparqlLexer.g4
Sparql.g4

# ANTLR tool
gen/
SparqlLexer.tokens
100 changes: 32 additions & 68 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.21)

project(sparql-parser-base VERSION 0.3.4)
project(sparql-parser-base VERSION 0.3.5)

include(cmake/boilerplate_init.cmake)
boilerplate_init()
Expand All @@ -19,10 +19,6 @@ endif ()

find_package(antlr4-runtime REQUIRED)

set(SPARQL_VERSION "1.1" CACHE STRING "SPARQL version" FORCE)
mark_as_advanced(SPARQL_VERSION)


set(ANTLR4_TAG "4.13.1" CACHE STRING "Antlr4 version" FORCE)
mark_as_advanced(ANTLR4_TAG)
set(ANTLR4_JAR_LOCATION "${PROJECT_BINARY_DIR}/antlr-${ANTLR4_TAG}-complete.jar")
Expand All @@ -36,81 +32,49 @@ include(${CMAKE_CURRENT_BINARY_DIR}/antlr4cmake/antlr4-generator.cmake)

message("antlr4-runtime_DIR ${antlr4-runtime_DIR}")


if (${SPARQL_VERSION} STREQUAL "1.1")
file(CREATE_LINK ${CMAKE_CURRENT_SOURCE_DIR}/SparqlLexer_${SPARQL_VERSION}.g4
${CMAKE_CURRENT_BINARY_DIR}/SparqlLexer.g4)
file(CREATE_LINK ${CMAKE_CURRENT_SOURCE_DIR}/SparqlParser_${SPARQL_VERSION}.g4
${CMAKE_CURRENT_BINARY_DIR}/SparqlParser.g4)
else ()
file(CREATE_LINK ${CMAKE_CURRENT_SOURCE_DIR}/SparqlParser_${SPARQL_VERSION}.g4
${CMAKE_CURRENT_BINARY_DIR}/Sparql.g4
)
endif ()


if (${SPARQL_VERSION} STREQUAL "1.1")
message("Generating SPARQL 1.1 Parser. If you want to generate the legacy SPARQL 1.0 parser, use -SPARQL_VERSION=1.0 or the conan package option sparql-parser-base:sparql_version=1.0 .")
antlr4_generate(
SparqlLexer
"${CMAKE_CURRENT_BINARY_DIR}/SparqlLexer.g4"
LEXER
FALSE # don't generate listener for lexer (not possible)
FALSE # don't generate visitor for lexer (not possible)
"dice::sparql_parser::base"
)
file(CREATE_LINK ${ANTLR4_GENERATED_SRC_DIR}/SparqlLexer/SparqlLexer.tokens
${CMAKE_CURRENT_BINARY_DIR}/SparqlLexer.tokens)
file(CREATE_LINK ${ANTLR4_GENERATED_SRC_DIR}/SparqlLexer/SparqlLexer.interp
${CMAKE_CURRENT_BINARY_DIR}/SparqlLexer.interp)
antlr4_generate(
SparqlParser
"${CMAKE_CURRENT_BINARY_DIR}/SparqlParser.g4"
PARSER
TRUE # generate listener
TRUE # generate visitor
"dice::sparql_parser::base"
)
else () # SPARQL 1.1
message("Generating SPARQL 1.0 Parser. This is a legacy version and will not receive any more updates.")
antlr4_generate(
Sparql
"${CMAKE_CURRENT_BINARY_DIR}/Sparql.g4"
BOTH
TRUE # generate listener
TRUE # generate visitor
"dice::sparql_parser::base"
)
endif ()

if (${SPARQL_VERSION} STREQUAL "1.1")
add_library("${PROJECT_NAME}"
${ANTLR4_SRC_FILES_SparqlLexer}
${ANTLR4_SRC_FILES_SparqlParser})
target_include_directories(sparql-parser-base PUBLIC
"$<BUILD_INTERFACE:${ANTLR4_INCLUDE_DIR_SparqlLexer}>"
"$<BUILD_INTERFACE:${ANTLR4_INCLUDE_DIR_SparqlParser}>")

else ()
add_library("${PROJECT_NAME}"
${ANTLR4_SRC_FILES_Sparql})
target_include_directories(sparql-parser-base PUBLIC
"$<BUILD_INTERFACE:${ANTLR4_INCLUDE_DIR_Sparql}>")
endif ()
message("Generating SPARQL 1.1 Parser")
antlr4_generate(
SparqlLexer
"${CMAKE_CURRENT_SOURCE_DIR}/SparqlLexer.g4"
LEXER
FALSE # don't generate listener for lexer (not possible)
FALSE # don't generate visitor for lexer (not possible)
"dice::sparql_parser::base"
)
file(CREATE_LINK ${ANTLR4_GENERATED_SRC_DIR}/SparqlLexer/SparqlLexer.tokens
${CMAKE_CURRENT_BINARY_DIR}/SparqlLexer.tokens)
file(CREATE_LINK ${ANTLR4_GENERATED_SRC_DIR}/SparqlLexer/SparqlLexer.interp
${CMAKE_CURRENT_BINARY_DIR}/SparqlLexer.interp)
antlr4_generate(
SparqlParser
"${CMAKE_CURRENT_SOURCE_DIR}/SparqlParser.g4"
PARSER
TRUE # generate listener
TRUE # generate visitor
"dice::sparql_parser::base"
)

add_library("${PROJECT_NAME}"
${ANTLR4_SRC_FILES_SparqlLexer}
${ANTLR4_SRC_FILES_SparqlParser})
target_include_directories(sparql-parser-base PUBLIC
"$<BUILD_INTERFACE:${ANTLR4_INCLUDE_DIR_SparqlLexer}>"
"$<BUILD_INTERFACE:${ANTLR4_INCLUDE_DIR_SparqlParser}>")

add_library("${PROJECT_NAME}::${PROJECT_NAME}" ALIAS "${PROJECT_NAME}")

target_link_libraries(sparql-parser-base PUBLIC
$<IF:$<BOOL:${BUILD_SHARED_LIBS}>,antlr4_shared,antlr4_static>
)
)


set_target_properties(${PROJECT_NAME} PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}
CXX_STANDARD 17
CXX_EXTENSIONS OFF
CXX_STANDARD_REQUIRED ON)
CXX_STANDARD_REQUIRED ON
)

if (PROJECT_IS_TOP_LEVEL)
include(cmake/install_library.cmake)
Expand Down
File renamed without changes.
34 changes: 0 additions & 34 deletions LICENSE-GRAMMAR-1.0

This file was deleted.

12 changes: 4 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# SPARQL-parser-base

[ANTLR-v4-based](https://github.com/antlr/antlr4)-based C++17 parser
for [SPARQL 1.0](https://www.w3.org/TR/rdf-sparql-query/) and [SPARQL 1.1](https://www.w3.org/TR/sparql11-overview/)
[ANTLR-v4-based](https://github.com/antlr/antlr4)-based C++17 parser for [SPARQL 1.1](https://www.w3.org/TR/sparql11-overview/)
with visitors and listeners. During CMake configuration, the ANTLR v4 code generator is called.

## Requirements
Expand All @@ -27,12 +26,9 @@ To use sparql-parser-base, add it to your `conanfile.txt`:

```
[requires]
sparql-parser-base/0.3.4
sparql-parser-base/0.3.5
```

If you want to use SPARQL 1.0 instead, add `sparql-parser-base:sparql_version=1.0` to the `[options]` section of your
conan file.

### With FetchContent

Use
Expand All @@ -42,7 +38,7 @@ include(FetchContent)
FetchContent_Declare(
sparql-parser-base
GIT_REPOSITORY "${CMAKE_CURRENT_SOURCE_DIR}/../"
GIT_TAG 0.3.4
GIT_TAG 0.3.5
GIT_SHALLOW TRUE
)
FetchContent_MakeAvailable(sparql-parser-base)
Expand Down Expand Up @@ -70,7 +66,7 @@ make -j sparql-parser-base

`-DBUILD_EXAMPLES=ON/OFF [default: OFF]`: Build the examples.

`-DSPARQL_VERSION="1.0"/"1.1" [default: "1.1"]`: SPARQL version of the generated parser.


`-DANTLR4_TAG=... [default: "4.13.1"]`: ANTLR4 version to be used.

Expand Down
11 changes: 11 additions & 0 deletions SparqlLexer_1.1.g4 → SparqlLexer.g4
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@ lexer grammar SparqlLexer;

WS : (' '| '\t'| EOL)+ -> channel(99);

Q_HINT_VAR_ORD: ('Q'|'q')'_'('H'|'h')('I'|'i')('N'|'n')('T'|'t')'_'('V'|'v')('A'|'a')('R'|'r')'_'('O'|'o')('R'|'r')('D'|'d');

Q_HINT_CARD_EST: ('Q'|'q')'_'('H'|'h')('I'|'i')('N'|'n')('T'|'t')'_'('C'|'c')('A'|'a')('R'|'r')('D'|'d')'_'('E'|'e')('S'|'s')('T'|'t');

CARD_EST_REDUCTION_FACTOR: ('C'|'c')('A'|'a')('R'|'r')('D'|'d')'_'('E'|'e')('S'|'s')('T'|'t')'_'
('R'|'r')('E'|'e')('D'|'d')('U'|'u')('C'|'c')('T'|'t')('I'|'i')('O'|'o')('N'|'n')'_'
('F'|'f')('A'|'a')('C'|'c')('T'|'t')('O'|'o')('R'|'r');

CARD_EST_MIN_CARDINALITY: ('C'|'c')('A'|'a')('R'|'r')('D'|'d')'_'('E'|'e')('S'|'s')('T'|'t')'_'('M'|'m')('I'|'i')('N'|'n')'_'
('C'|'c')('A'|'a')('R'|'r')('D'|'d')('I'|'i')('N'|'n')('A'|'a')('L'|'l')('I'|'i')('T'|'t')('Y'|'y');

BASE : ('B'|'b')('A'|'a')('S'|'s')('E'|'e');

PREFIX : ('P'|'p')('R'|'r')('E'|'e')('F'|'f')('I'|'i')('X'|'x');
Expand Down
27 changes: 24 additions & 3 deletions SparqlParser_1.1.g4 → SparqlParser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ subSelect
;

selectClause
: SELECT selectModifier? (selectVariables+ | '*')
: hintsClause SELECT selectModifier? (selectVariables+ | '*')
;

selectModifier
Expand All @@ -68,15 +68,36 @@ selectVariables
;

constructQuery
: CONSTRUCT (constructTemplate datasetClause* whereClause solutionModifier | datasetClause* WHERE '{' triplesTemplate? '}' solutionModifier)
: hintsClause CONSTRUCT (constructTemplate datasetClause* whereClause solutionModifier | datasetClause* WHERE '{' triplesTemplate? '}' solutionModifier)
;

describeQuery
: DESCRIBE (varOrIRI+ | '*') datasetClause* whereClause? solutionModifier
;

askQuery
: ASK datasetClause* whereClause solutionModifier
: hintsClause ASK datasetClause* whereClause solutionModifier
;

// NOT PART OF THE OFFICIAL GRAMMAR (tentris specific)
// NOTE: The order matters (if there is a variableOrdering hint, it must be provided before the cardinalityEstimation hint)
hintsClause
: variableOrdering? cardinalityEstimation?
;

// NOT PART OF THE OFFICIAL GRAMMAR (tentris specific)
variableOrdering
: Q_HINT_VAR_ORD varOrBlankNode+
;

// NOT PART OF THE OFFICIAL GRAMMAR (tentris specific)
cardinalityEstimation
: Q_HINT_CARD_EST (CARD_EST_REDUCTION_FACTOR|CARD_EST_MIN_CARDINALITY)
;


varOrBlankNode
: var | blankNode
;

datasetClause
Expand Down
Loading

0 comments on commit 8e19887

Please sign in to comment.