Skip to content

Commit

Permalink
FEAT: query generator (#13)
Browse files Browse the repository at this point in the history
* can generate sparql query

* parses constructs

* generate each queryUnit

* sparqlRule all rules

* implement generatorBuilder

* working basic generator

* generation seperated by newlines

* fix readme
  • Loading branch information
jitsedesmet authored Feb 6, 2025
1 parent 693f315 commit b062a6d
Show file tree
Hide file tree
Showing 67 changed files with 1,583 additions and 454 deletions.
39 changes: 39 additions & 0 deletions engines/generator-sparql-1-1/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# TRAQULA SPARQL 1.1 generator

TRAQULA Generator Sparql 1.1 is a [SPARQL 1.1](https://www.w3.org/TR/sparql11-query/#grammar) query generator for TypeScript.
It can generate SPARQL given the AST created by [TRAQULA parser SPARQL 1-1](https://github.com/comunica/traqula/tree/main/engines/parser-sparql-1-1).

## Installation

```bash
npm install @traqula/generator-sparql-1-1
```

or

```bash
yarn add @traqula/generator-sparql-1-1
```

## Import

Either through ESM import:

```javascript
import {Parser} from 'engines/generator-sparql-1-1';
```

_or_ CJS require:

```javascript
const Parser = require('engines/generator-sparql-1-1').Parser;
```

## Usage

This package contains a `Generator` that is able to generate SPARQL 1.1 queries:

```typescript
const generator = new Generator();
const abstractSyntaxTree = generator.generate(abstractSyntaxTree);
```
86 changes: 86 additions & 0 deletions engines/generator-sparql-1-1/lib/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { GeneratorBuilder } from '@traqula/core';
import { gram } from '@traqula/rules-sparql-1-1';
import type * as T11 from '@traqula/rules-sparql-1-1';

const sparql11GeneratorBuilder = GeneratorBuilder.createBuilder(<const> [
gram.query,
gram.selectQuery,
gram.constructQuery,
gram.describeQuery,
gram.askQuery,
gram.valuesClause,
gram.selectClause,
gram.constructTemplate,
])
.addMany(
gram.update,
gram.update1,
gram.load,
gram.clear,
gram.drop,
gram.create,
gram.copy,
gram.move,
gram.add,
gram.insertData,
gram.deleteData,
gram.deleteWhere,
gram.modify,
gram.graphOrDefault,
gram.graphRef,
gram.graphRefAll,
gram.quadData,
gram.quads,
gram.quadsNotTriples,
)
.addRule(gram.aggregate)
.addRule(gram.datasetClause)
.addMany(
gram.argList,
gram.expression,
gram.iriOrFunction,
)
.addMany(
gram.prologue,
gram.varOrTerm,
gram.var_,
gram.graphTerm,
)
.addMany(
gram.rdfLiteral,
gram.string,
gram.iri,
gram.blankNode,
)
.addRule(gram.path)
.addMany(
gram.solutionModifier,
gram.groupClause,
gram.groupCondition,
gram.havingClause,
gram.orderClause,
gram.orderCondition,
gram.limitOffsetClauses,
)
.addRule(gram.triplesBlock)
.addMany(
gram.groupGraphPattern,
gram.graphPatternNotTriples,
gram.optionalGraphPattern,
gram.graphGraphPattern,
gram.serviceGraphPattern,
gram.bind,
gram.inlineDataFull,
gram.dataBlockValue,
gram.minusGraphPattern,
gram.groupOrUnionGraphPattern,
gram.filter,
);

export class Generator {
private readonly generator = sparql11GeneratorBuilder.build();

public generate(ast: T11.Query): string {
return this.generator.query(ast, undefined, undefined);
}
}
48 changes: 48 additions & 0 deletions engines/generator-sparql-1-1/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"name": "@traqula/generator-sparql-1-1",
"type": "module",
"version": "0.0.0",
"description": "SPARQL 1.1 generator",
"lsd:module": true,
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/comunica/traqula.git",
"directory": "engines/generator-sparql-1-1"
},
"bugs": {
"url": "https://github.com/comunica/traqula/issues"
},
"sideEffects": false,
"exports": {
"import": "./lib/index.js",
"require": "./lib/index.cjs"
},
"main": "lib/index.js",
"publishConfig": {
"access": "public"
},
"files": [
"lib/**/*.cjs",
"lib/**/*.d.ts",
"lib/**/*.js",
"lib/**/*.js.map"
],
"engines": {
"node": ">=18.0"
},
"typings": "lib/index",
"scripts": {
"build": "yarn build:ts && yarn build:transpile",
"build:ts": "node \"../../node_modules/typescript/bin/tsc\"",
"build:transpile": " node \"../../node_modules/esbuild/bin/esbuild\" --format=cjs --bundle --log-level=error --outfile=lib/index.cjs lib/index.ts"
},
"dependencies": {
"@traqula/core": "^0.0.0",
"@traqula/rules-sparql-1-1": "^0.0.0"
},
"devDependencies": {
"@traqula/parser-sparql-1-1": "^0.0.0",
"@traqula/rules-sparql-1-1": "^0.0.0"
}
}
16 changes: 16 additions & 0 deletions engines/generator-sparql-1-1/test/integration.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Parser } from '@traqula/parser-sparql-1-1';
import type * as T11 from '@traqula/rules-sparql-1-1';
import { describe, it } from 'vitest';
import { Generator } from '../lib';

describe('a SPARQL 1.1 generator', () => {
const generator = new Generator();
const parser = new Parser();

it ('should generate a simple query', ({ expect }) => {
const query = 'SELECT * WHERE { ?s ?p ?o }';
const ast = <T11.Query> parser.parse(query);
const result = generator.generate(ast);
expect(result.replaceAll(/\s+/gu, ' ')).toBe(query);
});
});
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
# TRAQULA parser engine for SPARQL 1.1 + Adjust

TRAQULA Sparql 1.1 Adjust is a [SPARQL 1.1](https://www.w3.org/TR/sparql11-query/#grammar) query parser that also parses the [builtin function ADJUST](https://github.com/w3c/sparql-dev/blob/main/SEP/SEP-0002/sep-0002.md) for TypeScript.
Simple grammar extension of [TRAQULA engine-sparql-1-1](https://github.com/comunica/traqula/tree/main/engines/engine-sparql-1-1)
Simple grammar extension of [TRAQULA engine-sparql-1-1](https://github.com/comunica/traqula/tree/main/engines/parser-sparql-1-1)

## Installation

```bash
npm install @traqula/engine-sparql-1-1
npm install @traqula/parser-sparql-1-1-adjust
```

or

```bash
yarn add @traqula/engine-sparql-1-1
yarn add @traqula/parser-sparql-1-1-adjust
```

## Import

Either through ESM import:

```typescript
import { Parser } from '@traqula/engine-sparql-1-1-adjust';
import { Parser } from '@traqula/parser-sparql-1-1-adjust';
```

_or_ CJS require:

```typescript
const Sparql11AdjustParser = require('@traqula/engine-sparql-1-1-adjust').Parser;
const Sparql11AdjustParser = require('@traqula/parser-sparql-1-1-adjust').Parser;
```

## Usage
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Builder, LexerBuilder } from '@traqula/core';
import { sparql11ParserBuilder } from '@traqula/engine-sparql-1-1';
import { sparql11ParserBuilder } from '@traqula/parser-sparql-1-1';
import type { Expression, gram as g11, SparqlQuery } from '@traqula/rules-sparql-1-1';
import { lex as l11, SparqlParser } from '@traqula/rules-sparql-1-1';
import { gram, lex } from '@traqula/rules-sparql-1-1-adjust';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"name": "@traqula/engine-sparql-1-1-adjust",
"name": "@traqula/parser-sparql-1-1-adjust",
"version": "0.0.0",
"description": "SPARQL 1.1 + ADJUST parser",
"lsd:module": true,
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/comunica/traqula.git",
"directory": "engines/engine-sparql-1-1-adjust"
"directory": "engines/parser-sparql-1-1-adjust"
},
"bugs": {
"url": "https://github.com/comunica/traqula/issues"
Expand Down Expand Up @@ -43,7 +43,7 @@
},
"dependencies": {
"@traqula/core": "^0.0.0",
"@traqula/engine-sparql-1-1": "^0.0.0",
"@traqula/parser-sparql-1-1": "^0.0.0",
"@traqula/rules-sparql-1-1": "^0.0.0",
"@traqula/rules-sparql-1-1-adjust": "^0.0.0"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,27 @@ TRAQULA Sparql 1.1 is a [SPARQL 1.1](https://www.w3.org/TR/sparql11-query/#gramm
## Installation

```bash
npm install @traqula/engine-sparql-1-1
npm install @traqula/parser-sparql-1-1
```

or

```bash
yarn add @traqula/engine-sparql-1-1
yarn add @traqula/parser-sparql-1-1
```

## Import

Either through ESM import:

```javascript
import { Parser } from '@traqula/engine-sparql-1-1';
import {Parser} from 'engines/parser-sparql-1-1';
```

_or_ CJS require:

```javascript
const Parser = require('@traqula/engine-sparql-1-1').Parser;
const Parser = require('engines/parser-sparql-1-1').Parser;
```

## Usage
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Builder } from '@traqula/core';
import type { Query, SparqlQuery, Update, SparqlRuleDef } from '@traqula/rules-sparql-1-1';
import type { Query, SparqlQuery, Update, SparqlGrammarRule } from '@traqula/rules-sparql-1-1';
import { gram, lex as l, SparqlParser } from '@traqula/rules-sparql-1-1';
import { queryUnitParserBuilder } from './queryUnitParser';
import { updateParserBuilder } from './updateUnitParser';
Expand All @@ -14,7 +14,7 @@ import { updateParserBuilder } from './updateUnitParser';
// ```
// Prologue ( Update1 ( ';' Update )? )?
// ```
const queryOrUpdate: SparqlRuleDef<'queryOrUpdate', Query | Update | Pick<Update, 'base' | 'prefixes'>> = {
const queryOrUpdate: SparqlGrammarRule<'queryOrUpdate', Query | Update | Pick<Update, 'base' | 'prefixes'>> = {
name: 'queryOrUpdate',
impl: ({ ACTION, SUBRULE, SUBRULE2, OR1, OR2, CONSUME, OPTION1, MANY }) => () => {
const prologueValues = SUBRULE(gram.prologue, undefined);
Expand All @@ -38,16 +38,16 @@ const queryOrUpdate: SparqlRuleDef<'queryOrUpdate', Query | Update | Pick<Update
// Prologue ( Update1 ( ';' Update )? )?
// Is equivalent to:

let parsedPrologue = true;
let parsedSemi = true;
const updateResult: Update = {
...prologueValues,
type: 'update',
updates: [],
};
MANY({
GATE: () => parsedPrologue,
GATE: () => parsedSemi,
DEF: () => {
parsedPrologue = false;
parsedSemi = false;
const updateOperation = SUBRULE(gram.update1, undefined);

updateResult.updates.push(updateOperation);
Expand All @@ -63,7 +63,7 @@ const queryOrUpdate: SparqlRuleDef<'queryOrUpdate', Query | Update | Pick<Update
updateResult.prefixes;
});

parsedPrologue = true;
parsedSemi = true;
});
},
});
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Builder } from '@traqula/core';
import type { UpdateOperation } from '@traqula/rules-sparql-1-1';
import { gram } from '@traqula/rules-sparql-1-1';
import { triplesTemplateParserBuilder } from './triplesTemplateParserBuilder';

const update1Patch: typeof gram.update1 = {
name: 'update1',
impl: ({ SUBRULE, OR }) => () => OR([
impl: ({ SUBRULE, OR }) => () => OR<UpdateOperation>([
{ ALT: () => SUBRULE(gram.load, undefined) },
{ ALT: () => SUBRULE(gram.clear, undefined) },
{ ALT: () => SUBRULE(gram.drop, undefined) },
Expand All @@ -16,6 +17,7 @@ const update1Patch: typeof gram.update1 = {
{ ALT: () => SUBRULE(gram.deleteData, undefined) },
{ ALT: () => SUBRULE(gram.deleteWhere, undefined) },
]),
gImpl: gram.update1.gImpl,
};

const rulesNoUpdate1 = <const>[
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "@traqula/engine-sparql-1-1",
"name": "@traqula/parser-sparql-1-1",
"type": "module",
"version": "0.0.0",
"description": "SPARQL 1.1 parser",
Expand All @@ -8,7 +8,7 @@
"repository": {
"type": "git",
"url": "git+https://github.com/comunica/traqula.git",
"directory": "engines/engine-sparql-1-1"
"directory": "engines/parser-sparql-1-1"
},
"bugs": {
"url": "https://github.com/comunica/traqula/issues"
Expand Down
File renamed without changes.
Loading

0 comments on commit b062a6d

Please sign in to comment.