GithubHelp home page GithubHelp logo

rubenverborgh / sparql.js Goto Github PK

View Code? Open in Web Editor NEW
335.0 28.0 62.0 916 KB

A parser for the SPARQL query language in JavaScript

License: Other

JavaScript 52.66% Yacc 47.34%
sparql rdf parser serializer

sparql.js's Introduction

SPARQL.js – A SPARQL 1.1 parser for JavaScript

Build Status npm version DOI

The SPARQL 1.1 Query Language allows to query datasources of RDF triples. SPARQL.js translates SPARQL into JSON and back, so you can parse and build SPARQL queries in your JavaScript applications. It also contains support for the SPARQL* extension under the sparqlStar option.

It fully supports the SPARQL 1.1 specification, including property paths, federation, and updates.

Usage

Library

// Parse a SPARQL query to a JSON object
var SparqlParser = require('sparqljs').Parser;
var parser = new SparqlParser();
var parsedQuery = parser.parse(
  'PREFIX foaf: <http://xmlns.com/foaf/0.1/> ' +
  'SELECT * { ?mickey foaf:name "Mickey Mouse"@en; foaf:knows ?other. }');

// Regenerate a SPARQL query from a JSON object
var SparqlGenerator = require('sparqljs').Generator;
var generator = new SparqlGenerator({ /* prefixes, baseIRI, factory, sparqlStar */ });
parsedQuery.variables = ['?mickey'];
var generatedQuery = generator.stringify(parsedQuery);

Set sparqlStar to true to allow SPARQL* syntax.

Set pathOnly to true to parse SPARQL paths such as foaf:name/foaf:knows rather than the full SPARQL Algebra.

Validation

By default SPARQL.js throws on queries that are syntactically correct, but not allowed by the spec. Set skipValidation to true to skip validation.

// Parse a SPARQL query without validation.
var SparqlParser = require('sparqljs').Parser;
var parser = new SparqlParser({ skipValidation: true });
var parsedQuery = parser.parse(
  'select (?x as ?xString)' +
  '(count(?y) as ?count)' +
  '{ ?x ?y ?z }');

Standalone

$ sparql-to-json --strict query.sparql

Parse SPARQL* syntax by default. For pure SPARQL 1.1, use the --strict flag.

Representation

Queries are represented in a JSON structure. The most easy way to get acquainted with this structure is to try the examples in the queries folder through sparql-to-json. All examples of the SPARQL 1.1 specification have been included, in case you wonder how a specific syntactical construct is represented.

Here is a simple query in SPARQL:

PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>
SELECT ?p ?c WHERE {
    ?p a dbpedia-owl:Artist.
    ?p dbpedia-owl:birthPlace ?c.
    ?c <http://xmlns.com/foaf/0.1/name> "York"@en.
}

And here is the same query in JSON:

{
  "queryType": "SELECT",
  "variables": [
    {
      "termType": "Variable",
      "value": "p"
    },
    {
      "termType": "Variable",
      "value": "c"
    }
  ],
  "where": [
    {
      "type": "bgp",
      "triples": [
        {
          "subject": {
            "termType": "Variable",
            "value": "p"
          },
          "predicate": {
            "termType": "NamedNode",
            "value": "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
          },
          "object": {
            "termType": "NamedNode",
            "value": "http://dbpedia.org/ontology/Artist"
          }
        },
        {
          "subject": {
            "termType": "Variable",
            "value": "p"
          },
          "predicate": {
            "termType": "NamedNode",
            "value": "http://dbpedia.org/ontology/birthPlace"
          },
          "object": {
            "termType": "Variable",
            "value": "c"
          }
        },
        {
          "subject": {
            "termType": "Variable",
            "value": "c"
          },
          "predicate": {
            "termType": "NamedNode",
            "value": "http://xmlns.com/foaf/0.1/name"
          },
          "object": {
            "termType": "Literal",
            "value": "York",
            "language": "en",
            "datatype": {
              "termType": "NamedNode",
              "value": "http://www.w3.org/1999/02/22-rdf-syntax-ns#langString"
            }
          }
        }
      ]
    }
  ],
  "type": "query",
  "prefixes": {
    "dbpedia-owl": "http://dbpedia.org/ontology/"
  }
}

The representation of triples uses the RDF/JS representation.

Installation

$ [sudo] npm [-g] install sparqljs

License, status and contributions

The SPARQL.js library is copyrighted by Ruben Verborgh and released under the MIT License.

Contributions are welcome, and bug reports or pull requests are always helpful.

Contributors

sparql.js's People

Contributors

alexeymz avatar danielbeeke avatar edgarrd avatar florianfv avatar h4ck3rm1k3 avatar iddan avatar jacoscaz avatar jeswr avatar joachimvh avatar laurensrietveld avatar lucaswerkmeister avatar maxdebayser avatar namedgraph avatar quarkstoquasars avatar rubensworks avatar rubenverborgh avatar shad avatar simonvbrae avatar tpt avatar white-gecko avatar yamalight avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sparql.js's Issues

Parsing of prefixes

Sorry to bother you again : )
Is there a reason why the prefixes are resolved within the triples when parsing a SPARQL query?
I think it unnecessary bloats the SPARQL Object and it would be very easy to look them up when needed.

Kind regards,
Jonas

DAWG TestCases basic/term-7 fails

The query below, part of dawg TestCases, fails at least in version 2.2.3. It should consider the first dot as a decimal point, according to test description :)

PREFIX :     <http://example.org/ns#>
PREFIX xsd:  <http://www.w3.org/2001/XMLSchema#>

# DOT is part of the decimal.
SELECT * { :x ?p 456. . }

Does not parse VALUES blocks with an empty variable list

Currently the parser throws an error on queries that contain clauses like the following one:

VALUES () { () }

With the error message:

Expecting 'VAR', '(' got 'NIL'

But the SPARQL 1.1 grammar states that this valid syntax in section: InlineDataFull:

[64] InlineDataFull ::= ( NIL | '(' Var* ')' ) '{' ( '(' DataBlockValue* ')' | NIL )* '}'

Since it uses * instead of + both where variables should go, and where data block values should go.

Parsing sparql-10-2-2b.sparql produces results that do not match with sparql-10-2-2b.json

So, parser for some reason omits UNDEF fields for VALUES.

Expected output:

"type": "values",
"values": [
  {
    "?title": "\"SPARQL Tutorial\"",
    "?book": "{undefined}"
  },
  {
    "?title": "{undefined}",
    "?book": "http://example.org/book/book2"
  }
]

Actual output:

"type": "values",
"values": [
  {
    "?title": "\"SPARQL Tutorial\"",
  },
  {
    "?book": "http://example.org/book/book2"
  }
]

errors executing a SPARQL query from command line

Hi in order to be able to do some testing on the SPARQL parser from an angularjs app, I'm trying to regenerate the library on a ubuntu virtual machine.

Before executing browserify, I'm trying the command line version.
Basically I'm following the steps:

git clone https://github.com/RubenVerborgh/SPARQL.js.git
cd SPARQL.js/
sudo npm -g install

and everything compiles fine, but trying to execute a query locally I've got the following error:

$ bin/sparql-to-json queries/artists-ghent.sparql
module.js:442
    throw err;
    ^

Error: Cannot find module './lib/SparqlParser'
    at Function.Module._resolveFilename (module.js:440:15)
    at Function.Module._load (module.js:388:25)
    at Module.require (module.js:468:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/vagrant/dev_src/SPARQL.js/sparql.js:1:76)
    at Module._compile (module.js:541:32)
    at Object.Module._extensions..js (module.js:550:10)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)
    at Function.Module._load (module.js:409:3)

any suggestions?

Add LICENSE & CONTRIBUTE files

Do you have any idea about the license you'll use for this project? I was starting a parser by my own just a few days ago, basically on the same idea of what you're doing (see https://github.com/edgarRd/sparqler), just now I found yours and I figure two heads are better than one.
I would like to contribute.
Cheers.

Add a linter

I just opened this #55 to remove irregular white spaces, and noticed that this repo currently does not have any linting rules. I might be useful to add to avoid future white space issues, but also help guide contributors with adopting your js style.

Update SPARQL.js to use the RDF/JS representation

I try to create an INSERT DATA query based on an array of triples.
Motivated by the README text:

The representation of triples is the same as that of the N3.js library.

I came up with the following code, where I just put the triplesArray in at the triples key:

import {Generator} from 'sparqljs'
import { DataFactory } from 'n3'
const { namedNode, triple } = DataFactory

var tripleArray = [triple(
  namedNode('http://example.org/some'),
  namedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'),
  namedNode('http://example.org/Something')
)]
var generator = new Generator()
var updateStructure = {
  'type': 'update',
  'updates': [
    {
      'updateType': 'insert',
      'insert': [
        {
          'type': 'bgp',
          'triples': tripleArray
        }
      ]
    }
  ]
}
var updateString = generator.stringify(updateStructure)

but I end upp receiving the following error:

node_modules/sparqljs/lib/SparqlGenerator.js:278
    var items = value.items.map(this.toEntity, this), path = value.pathType;
                            ^

TypeError: Cannot read property 'map' of undefined
    at Generator.toEntity (node_modules/sparqljs/lib/SparqlGenerator.js:278:29)
    at Generator.encodeTriples (node_modules/sparqljs/lib/SparqlGenerator.js:122:23)
    at Generator.bgp (node_modules/sparqljs/lib/SparqlGenerator.js:105:15)
    at Generator.toPattern (node_modules/sparqljs/lib/SparqlGenerator.js:93:20)
    at Array.map (<anonymous>)
    at mapJoin (node_modules/sparqljs/lib/SparqlGenerator.js:351:16)
    at Generator.array (node_modules/sparqljs/lib/SparqlGenerator.js:101:10)
    at Generator.toPattern (node_modules/sparqljs/lib/SparqlGenerator.js:93:20)
    at Generator.group (node_modules/sparqljs/lib/SparqlGenerator.js:146:34)
    at Generator.toUpdate (node_modules/sparqljs/lib/SparqlGenerator.js:318:35)

How can I convert my triples to the correct format, which is accepted by sparql.js?

Build query from scratch

I just need some clarification. I'm trying to use this library to build a query dynamically, starting from a JavaScript object and then parsing it to obtain corresponding SPARQL query. I do not know if I'm using it correctly, I'll post an example below:

const query = {};
query.prefixes = {foaf: 'http://xmlns.com/foaf/0.1/'};
query.type = 'query';
query.queryType = 'SELECT';
query.variables = ['*'];
query.where = [{
  type: 'bgp',
  triples: [{
    subject: '?mickey',
    predicate: 'foaf:name',
    object: 'Mickey Mouse',
  }],
}];

var generatedQuery = new SparqlGenerator().stringify(query);
console.log(generatedQuery);

// Output
// SELECT * WHERE { ?mickey <foaf:name> <Mickey Mouse>. }

var generatedQuery2 = new SparqlGenerator({allPrefixes: true}).stringify(query);
console.log(generatedQuery2)

// Output
// PREFIX foaf: <http://xmlns.com/foaf/0.1/> 
// SELECT * WHERE { ?mickey <foaf:name> <Mickey Mouse>. }

The queries are generated with < ... > .
Am I doing something wrong?

version 2.2.0 is broken

Npm version is broken.

Error:
ENOENT: no such file or directory, chmod '[pathtofolder]/node_modules/sparqljs/bin/sparql-to-json'

Versions: node v10.15.0 (npm v6.4.1)

Perhaps a problem with the "files" property of your package.json.
Possible workaround: Including bin/*.js will maybe solve the problem.

Update Queries with trailing semicolon should be allowed

Sorry to bother you again, but this is one where the grammar does not make sense:

[29] Update     ::=  Prologue ( Update1 ( ';' Update )? )?

which theoretically means that

INSERT DATA { <http://example/book1> <urn:label> "A new book" .} ;

and even

INSERT DATA { <http://example/book1> <urn:label> "A new book" .} ; PREFIX a: <urn:a>

should be allowed.

While the second case seems not the useful, the first case is even mentioned in the spec document:

Multiple operations are separated by a ';' (semicolon) character. A semicolon after the last operation in a request is optional.

Version 2.2.2 breaks with webpack

It looks like since version 2.2.2, webpack builds are failing, possibly because of this commit: f211398

ERROR in /home/travis/build/comunica/comunica/node_modules/fetch-sparql-endpoint/node_modules/sparqljs/lib/SparqlParser.js
Module not found: Error: Can't resolve 'fs' in '/home/travis/build/comunica/comunica/node_modules/fetch-sparql-endpoint/node_modules/sparqljs/lib'
 @ /home/travis/build/comunica/comunica/node_modules/fetch-sparql-endpoint/node_modules/sparqljs/lib/SparqlParser.js 4887:17-30
 @ /home/travis/build/comunica/comunica/node_modules/fetch-sparql-endpoint/node_modules/sparqljs/sparql.js
 @ /home/travis/build/comunica/comunica/node_modules/fetch-sparql-endpoint/lib/SparqlEndpointFetcher.js
 @ /home/travis/build/comunica/comunica/node_modules/fetch-sparql-endpoint/index.js
 @ ../actor-query-operation-sparql-endpoint/lib/ActorQueryOperationSparqlEndpoint.js
 @ ../actor-query-operation-sparql-endpoint/index.js
 @ ./engine-default.js
 @ ./index-browser.js
 @ multi @babel/polyfill ./index-browser.js

Full log: https://travis-ci.org/comunica/comunica/jobs/505234208

Support for BIND CONCAT

Is there support for BIND CONCAT? I couldn't find any tests that illustrate how to do a bind concat with variables.

Format long values on a single line

Continuing from #68

Per issue reported for Wikidata Query Service, please format multiple VALUES on a single line when they can fit. Examples:

Original text

SELECT * WHERE {
  VALUES ?a { wd:Q1 wd:Q2 ... }
}

Desired results

# short list
SELECT * WHERE {
  VALUES ?a { wd:Q1 wd:Q2 }
}
# long list
SELECT * WHERE {
  VALUES ?a {
    wd:Q1 wd:Q2 wd:Q1 wd:Q2 wd:Q1 wd:Q2 wd:Q1 wd:Q2 wd:Q1 wd:Q2 wd:Q1 wd:Q2
    wd:Q1 wd:Q2 wd:Q1 wd:Q2 wd:Q1 wd:Q2 wd:Q1 wd:Q2 wd:Q1 wd:Q2 wd:Q1 wd:Q2
  }
}

Current result

SELECT * WHERE {
  VALUES ?a {
    wd:Q1
    wd:Q2
  }
}

Generator.stringify() is broken in 3.0.0-beta.0

So far I was using the sparqljs Generator to create SPARQL Update strings in the following way:

var sparqljs = require("[email protected]")
var updateStructure = {"type":"update","updates":[{"updateType":"insert","insert":[{"triples":[{"subject":"http://aksw.org/NatanaelArndt","predicate":"http://xmlns.com/foaf/0.1/name","object":"\"Natanael Arndt\"","graph":""}],"type":"graph","name":"http://aksw.org/"}]}]}
var generator = new sparqljs.Generator()
var updateString = generator.stringify(updateStructure)
console.log(updateString)

The actual and expected output was (can be reproduced on https://npm.runkit.com/sparqljs):

INSERT DATA { GRAPH <http://aksw.org/> { <http://aksw.org/NatanaelArndt> <http://xmlns.com/foaf/0.1/name> "Natanael Arndt". } }

Since the update to 3.0.0-beta.0 I get the error value.items is undefined in this line:

var items = value.items.map(this.toEntity, this), path = value.pathType;

This can be reproduced with the following code on https://npm.runkit.com/sparqljs

var sparqljs = require("[email protected]")
var updateStructure = {"type":"update","updates":[{"updateType":"insert","insert":[{"triples":[{"subject":"http://aksw.org/NatanaelArndt","predicate":"http://xmlns.com/foaf/0.1/name","object":"\"Natanael Arndt\"","graph":""}],"type":"graph","name":"http://aksw.org/"}]}]}
var generator = new sparqljs.Generator()
var updateString = generator.stringify(updateStructure)
console.log(updateString)

This issue/new behavior must have been introduced with #80

Parsing simple erroneous queries can take exponential time

@JonasKress noticed that if you simply type ddddddddddddddddddddddddddddddddd (or any other letter) on query.wikidata.org, the tab hangs. It seems that SPARQL.js takes exponential time (twice as long for each letter) to parse such a “query” (before reporting a parse error):

$ for i in {20..30}; do start=$SECONDS; printf '%*s' $i | tr ' ' 'x' | sparqljs &>/dev/null; end=$SECONDS; printf '%2d: %d s\n' $i $((end-start)); done
20: 0 s
21: 0 s
22: 1 s
23: 1 s
24: 2 s
25: 3 s
26: 7 s
27: 14 s
28: 28 s
29: 56 s
30: 112 s

Do you think it’s possible to improve this?

Remove parens and multi-line when formatting VALUES

Per issue reported for Wikidata Query Service, please do not add parenthesis to a single value VALUES list. Examples:

Original text

SELECT * WHERE {
  VALUES ?a { wd:Q1 wd:Q2 ... }
}

Desired results

# short list
SELECT * WHERE {   VALUES ?a { wd:Q1 wd:Q2 } }
# long list
SELECT * WHERE {
  VALUES ?a {
    wd:Q1 wd:Q2 wd:Q1 wd:Q2 wd:Q1 wd:Q2 wd:Q1 wd:Q2 wd:Q1 wd:Q2 wd:Q1 wd:Q2
    wd:Q1 wd:Q2 wd:Q1 wd:Q2 wd:Q1 wd:Q2 wd:Q1 wd:Q2 wd:Q1 wd:Q2 wd:Q1 wd:Q2
  }
}

Current result

SELECT * WHERE {
  VALUES (?a) {
    (wd:Q1)
    (wd:Q2)
  }
}

When generating SPARQL use prefixes

I think it would be nice to use prefixes when generating entities of a SPARQL query and maybe also delete prefixes from the list that are not actually in use.

So in case of Wikidata this:
http://www.wikidata.org/prop/direct/P31

would be rendered as:
wdt:P31

What do you think?
It could also be an option in the generator.

Cheers,
Jonas

Use semicolon separator for multiple statements with same subject

When formatting, I think it would be better to preserve semicolon, or even to always use it when possible. E.g. if two consequent statements have the same subject, use semicolon and indent the second statement. If statements have the same subject and predicate, use comma and put all objects on the same line. I think this makes SPARQL much more readable, and highlights the fact that the subject is the same.

Original:

SELECT * WHERE {
?osmid osmt:place "city";
osmt:wikidata ?wd.
}

Expected formatting:

SELECT * WHERE {
  ?osmid osmt:place "city";
         osmt:wikidata ?wd.
}

Current result:

SELECT * WHERE {
  ?osmid osmt:place "city".
  ?osmid osmt:wikidata ?wd.
}

Disable (minor) query rewrites by default

Let's say we have a simple query like:

SELECT * WHERE {
  { ?s ?p ?o. }
  ?a ?b ?c .
}

With the last SPARQL.js it is parsed to:

{
  "queryType": "SELECT",
  "variables": [
    "*"
  ],
  "where": [
    {
      "type": "bgp",
      "triples": [
        {
          "subject": "?s",
          "predicate": "?p",
          "object": "?o"
        },
        {
          "subject": "?a",
          "predicate": "?b",
          "object": "?c"
        }
      ]
    }
  ],
  "type": "query",
  "prefixes": {}
}

Which doesn't correspond to the original query, if I serialize it, the result will be:

SELECT * WHERE {
  ?s ?p ?o.
  ?a ?b ?c .
}

This missing group sometimes can be significant, e.g. in my use-case I'm trying to apply blazegraph(https://wiki.blazegraph.com/wiki/index.php/QueryHints) query hint to the subgroup.

SPARQL comments

Would there be a way to preserve comments within a SPARQL query?

"as" expression: (?s as ?subject)

Is it possible to perform an "as" expression with SPARQL.js ? Something like this:

select (?s as ?subject) (?p as ?predicate) (?o as ?object) where {
   ?s ?p ?o .
}

This is a dummy example but it illustrate well what I mean.

PS: this lib is awesome ! Thanks for building it 🍻

Variables in `IN` expressions are not parsed

Either it's me missing something obvious, or in.sparql query is parsed wrongly.
String query has this parts:
FILTER (?a IN (1, 2, 3))
FILTER (?c NOT IN (1, 2, 3))

JSON representation looks like this:

{
  "type": "filter",
  "expression": {
    "type": "operation",
    "operator": "in",
    "args": [
      "\"1\"^^http://www.w3.org/2001/XMLSchema#integer",
      "\"2\"^^http://www.w3.org/2001/XMLSchema#integer",
      "\"3\"^^http://www.w3.org/2001/XMLSchema#integer"
    ]
  }
}

And second one:

{
  "type": "filter",
  "expression": {
    "type": "operation",
    "operator": "notin",
    "args": [
      "\"1\"^^http://www.w3.org/2001/XMLSchema#integer",
      "\"2\"^^http://www.w3.org/2001/XMLSchema#integer",
      "\"3\"^^http://www.w3.org/2001/XMLSchema#integer"
    ]
  }
}

Is it me, or is the variables (?a in case 1, ?c in case 2) are really missing from args?

Update Queries with multiple operations are not parsed correctly

Update Queries with multiple operations are not parsed correctly, if any update operation after the first contains prefixes:

This is parseable:

PREFIX dc: <http://purl.org/dc/elements/1.1/>
INSERT DATA { <http://example/book1> dc:title "A new book" .} ;
INSERT DATA { <urn:a> <urn:a> <urn:a> .}

While this throws an Error:

PREFIX dc: <http://purl.org/dc/elements/1.1/>
INSERT DATA { <http://example/book1> dc:title "A new book" .} ;
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
INSERT DATA { <http://example/book2> rdfs:label "A second book" .}

According to the SPARQL Grammar # UpdateUnit, the second query is valid:

[3]  UpdateUnit ::=  Update
[4]  Prologue   ::=  ( BaseDecl \| PrefixDecl )*
[29] Update     ::=  Prologue ( Update1 ( ';' Update )? )?

Unable to create browser version

When following

$ cd SPARQL.js
$ npm install
$ browserify sparql.js --standalone -u fs -u path -u _process sparqljs > sparqljs-browser.js
$ uglifyjs sparqljs-browser.js -c -m > sparqljs-browser-min.js

The third command gives the following error

Error: --standalone requires an export name argument
    at error (/usr/lib/node_modules/browserify/bin/args.js:116:17)
    at module.exports (/usr/lib/node_modules/browserify/bin/args.js:248:9)
    at Object.<anonymous> (/usr/lib/node_modules/browserify/bin/cmd.js:6:26)
    at Module._compile (module.js:410:26)
    at Object.Module._extensions..js (module.js:417:10)
    at Module.load (module.js:344:32)
    at Function.Module._load (module.js:301:12)
    at Function.Module.runMain (module.js:442:10)
    at startup (node.js:136:18)
    at node.js:966:3

FROM (NAMED) not allowed in SERVICE

While this is a valid query as far as I know, it is not accepted by the parser:

SELECT * WHERE {
  SERVICE <http://dbpedia.org/sparql> {
    SELECT *
	FROM <http://dbpedia.org>
	WHERE {
	  ?s ?p ?o
    }
  }
}

Error:

Parse error on line 16:
...ql> {    SELECT *	FROM <http://dbpedia
---------------------^
Expecting 'WHERE', '{', got 'FROM'

Also for FROM NAMED:

SELECT * WHERE {
  SERVICE <http://dbpedia.org/sparql> {
    SELECT *
	FROM NAMED <http://dbpedia.org>
	WHERE {
	  ?s ?p ?o
    }
  }
}

Add space between integer literals and periods

Consider the following example query:

SELECT * WHERE {
  ?s1 ?p1 1 .
  ?s2 ?p2 2 .
}
LIMIT 1

When parsing and then regenerating it, SPARQL.js will remove the spaces between the integer literals and the periods:

SELECT * WHERE {
  ?s1 ?p1 1.
  ?s2 ?p2 2.
}
LIMIT 1

However, this query will fail to parse in SPARQL.js, as well as in several SPARQL servers (at least Virtuoso and Blazegraph, but not in Fuseki), because they parse 1. as a decimal literal (with no decimal digits).

The SPARQL production for DECIMAL requires one or more digits after the decimal point, so I think implementations failing to parse the second query are technically not compliant with the standard – but still, for compatibility with both itself and several major SPARQL servers, it would nevertheless be nice if SPARQL.js could resolve this ambiguity at the point of SPARQL generation, by separating integer literals and periods with spaces.

(See T206910 for the corresponding issue on our own bug tracker.)

sparql-17-4-2-5 query parsed output malformed?

Not sure here, but maybe there's an issue.

Query looks like this:

FILTER regex(str(?mbox), "@work\\.example$")

Output looks like this

{
  "type": "filter",
  "expression": {
    "type": "operation",
    "operator": "regex",
    "args": [
      {
        "type": "operation",
        "operator": "str",
        "args": [
          "?mbox"
        ]
      },
      "\"@work\\.example$\""
    ]
  }
}

Decoding "\"@work\\.example$\"" turns it into "@work\.example$" which is wrong.
Am I right here? That's a bug?

Allow custom functions

Is there any way to augment the parser to allow for custom function names? For example imagine I'd like to do something like:

SELECT ?reversed
WHERE
{ 
  ?s ?p ?o . 
  BIND(REVERSE(?o) as ?reversed
}

Where REVERSE will be supplied by myself in a runtime evaluator (sparql-engine). Any help would be appreciated. Thanks!

DAWG TestCases basic/list-2 fails

Sorry to be posting another issue. Can someone help me understand why the parsing is like that in the case below?

DAWG list-2 data:

@prefix : <http://example.org/ns#> .
@prefix xsd:        <http://www.w3.org/2001/XMLSchema#> .


:x :list0 () .
:x :list1 ("1"^^xsd:integer) .
:x :list2 ("11"^^xsd:integer "22"^^xsd:integer) .
:x :list3 ("111"^^xsd:integer "222"^^xsd:integer "333"^^xsd:integer) .

DAWG list-2 query:

PREFIX : <http://example.org/ns#>

SELECT ?p
{ :x ?p (1) . }

The result BGPs generated by parsing:

[ { subject: 'http://example.org/ns#x',
    predicate: '?p',
    object: '_:b0' },
  { subject: '_:b0',
    predicate: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#first',
    object: '"1"^^http://www.w3.org/2001/XMLSchema#integer' },
  { subject: '_:b0',
    predicate: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest',
    object: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil' } ]

Should not that _:b0 be a var? The parser can't know at parsing time, the id of the bnode that will be created. Right?

Best regards.

Add type to all nodes

Suggestion by @AlexeyMz at #80 (comment):

May I also suggest to add type constants to other node types as well?

Here are the current typings: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/d2d3a685fe949a4e938fe2913597e49d1e703ef5/types/sparqljs/index.d.ts

It would be great to make these changes:

  1. add type equal to grouping for Grouping, ordering for Ordering, variable for VariableExpression;
  2. change updateType property to type in InsertDeleteOperation (currently half operations use updateType and the other one just type).

Preserve token positions?

This might be out of scope, but preserving token positions (when possible) would broaden the usefulness of this library to include IDE-like projects (with autocomplete, advanced error reporting, contextual hover info, etc).
I understand that there is some interpretation logic that's tightly coupled to the parser rules, but even partial info can go a long way.
Awesome work Ruben, I love how straightforward this library is ;)

Improve stringification of queries

On query.wikidata.org we use SPARQL.js to edit queries, which includes converting the parsed form back to SPARQL after editing it. This means that if the user starts with a query like

SELECT ?person WHERE {
  ?person wdt:P31 wd:Q5;
          wdt:P1412 wd:Q1860, wd:Q188;
          wdt:P22 [ wdt:P27 wd:Q142 ].
}

and edits it, the result they get will be

SELECT ?person WHERE {
  ?person wdt:P31 wd:Q5.
  ?person wdt:P1412 wd:Q1860.
  ?person wdt:P1412 wd:Q188.
  ?person wdt:P22 _:b1.
  _:b1 wdt:P27 wd:Q142.
}

which is significantly less readable.

It would be awesome if the conversion to string would automatically use the following abbreviations when possible:

  • use ; when the subject is repeated
  • use , when the subject and predicate are repeated
  • use [ ] when the object is a blank node that is only used as subject of immediately subsequent triples

Switch to RDF/JS representation

Currently RDFTerms (Literals, IRIs and prefixed IRIs) are represented as strings.
I suggest to use the RDF/JSON representation for RDF values.
Also, prefixed IRIs should be distinguished from IRIs.

import { Parser } from 'sparqljs';
const parser = new Parser();
parser.parse(`
PREFIX foaf:  <http://xmlns.com/foaf/0.1/>
SELECT *
WHERE {
    ?person foaf:name ?name .
    ?person foaf:mbox ?email .
}
`)

Should return

{
  "queryType": "SELECT",
  "variables": [
    "*"
  ],
  "where": [
    {
      "type": "bgp",
      "triples": [
        {
          "subject": {
              "type": "variable",
              "identifier": "person"
          },
          "predicate": {
              "type": "prefixed-iri",
              "prefix": "foaf",
              "value": "name"
          },
          "object": {
              "type": "variable",
              "identifier": "name"
          }
        },
        {
          "subject": {
              "type": "variable",
              "identifier": "person"
          },
          "predicate": {
              "type": "iri",
              "value": "http://xmlns.com/foaf/0.1/mbox"
          },
          "object": {
              "type": "variable",
              "identifier": "email"
          }
        }
      ]
    }
  ],
  "type": "query",
  "prefixes": {
    "foaf": "http://xmlns.com/foaf/0.1/"
  }
}

We'd be happy to offer a PR

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.