RubenVerborgh / SPARQL.js

A parser for the SPARQL query language in JavaScript
Other
342 stars 66 forks source link

SPARQL comments #19

Open JonasKress opened 8 years ago

JonasKress commented 8 years ago

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

RubenVerborgh commented 8 years ago

You mean, preserving them in the syntax tree? That would be possible, but it's undesired in general. What is your use case?

JonasKress commented 8 years ago

I would like to build something like a visual editor for SPARQL that can import and export queries. It should preserve the original query as far as it is possible (comments, formatting, ...).

RubenVerborgh commented 8 years ago

In that case, it seems most appropriate to just store the original query text then, right? There's no need to store a parsed version, which is designed to abstract away formatting and comments.

JonasKress commented 8 years ago

I would it like to parse a SPARQL query, make modifications to the SPARQL object via UI and then generate the SPARQL query from that object while keeping all the comments. So basically I'd like to preserve the comments during the roundtrip of SPARQL -> Object -> SPARQL.

RubenVerborgh commented 8 years ago

That's a difficult thing to do in general, the combination of manual and auto-generated code in one file. I don't immediately see how SPARQL.js could support this, because comments can appear literally everywhere (inside a BGP, inside a triple, …).

arb commented 7 years ago

@JonasKress did you ever find a solution to this? I'm actually trying to do something similar. @RubenVerborgh would you reconsider exposing comments?

RubenVerborgh commented 7 years ago

@arb If there is a suggestion of how to this. I'm particularly worried about things like:

SELECT *  WHERE {
   ?s # comment
   ?p # comment
   ?o # comment
}

A purely lexical tree might contain them, but a syntax tree wouldn't.

arb commented 7 years ago

I really don't have an suggestions here... This is way outside my realm of expertise. I just know that trying to format a language with infinite depth {}s with regular expressions is impossible and you pretty much need a parser.

This is the only lib in JS that parses sparql so I came here seeing if I could leverage it.

RubenVerborgh commented 7 years ago

The problem is not with the parser, but rather with the output format. What would a meaningful output of the above query be, given that it splits a triple pattern in three pieces?

arb commented 7 years ago
variables: [
  {name:"?s", comment:'comment'}, 
  {name:"?p", comment:'comment'}, 
  {name:"?o", comment:'comment'}, 
]

For just a thought. I mean we'd have to discuss adding comments in general beyond just this case, but my thought would be adding a comment prop if something has a comment. If it's inline, associate it with the construct on the same line, if it's inside something, make it a property of the thing it's inside.

RubenVerborgh commented 7 years ago

That doesn't work; it needs to be a triple pattern.

RubenVerborgh commented 7 years ago

Also, not every "something" has an object associated with it:

SELECT # comment
* #comment
WHERE #comment
{ #comment
 ?s ?p ?o
 #comment
 . #comment
} #comment
arb commented 7 years ago
SELECT # comment (goes in a global query comment bucket)
* #comment (goes with the select object)
WHERE #comment (goes with the where object
{ #comment goes with the where object
 ?s ?p ?o
 #comment goes with the where object
 .
} #comment (goes in a global query comment bucket)

Like I said, this is not my area of expertise so I'm just throwing out ideas without knowledge of limitations and the full scope of SPARQL language. If it can't be done, that's ok and I'll muddle on with string manipulations.

As you said this isn't really an AST parser so I don't know what the LOE would be or if you're interested in adding these features.

RubenVerborgh commented 7 years ago

Depending on what people want to use the comments for, this might or might not work indeed.

At the moment, these features are not a priority for me, but I am open to additions by others.

tfrancart commented 3 years ago

Hi @RubenVerborgh I actually have a similar use-case where I would like to generate some comments in a SPARQL query (actually, for Sparnatural) (not parse them, only generate them, so no need to preserve comments in a round-trip) What about a limited support for only some comments at some places, e.g. for example only comments related to BGPs (inside, above, below) ? or maybe attached to the select clause, or at the top of the query ? from a pragmatic standpoint, this is where most of the comments are inserted.

# comment
SELECT *
WHERE
{ #comment
 ?s ?p ?o . 
}

Of course this will not allow to do a roundtrip of all comments from an original query.

RubenVerborgh commented 3 years ago

@tfrancart Thanks. I have marked this as a bounty issue; perhaps people like @danielbeeke want to jump in.

rubensworks commented 3 years ago

@RubenVerborgh Is someone willing to fund the issue via the Comunica Association? If so, then that person should contact me to determine a bounty amount via here: https://comunica.dev/association/bounties/ (If not, might be better to remove the bounty label until someone can fund it)

RubenVerborgh commented 3 years ago

Oops, understood: I'll wait for funding.

kclejeune commented 2 years ago

I'm trying to toss together an opinionated sparql formatter using this. If nobody else wants to take this on, at some point I'll take a stab at implementing limited comment preservation (probably just comments that exist on their own lines).

tpluscode commented 2 months ago

I recently needed something like this to be able to output #pragma comments in Stargod. They basically appear as line comments and I hacked it simply as a type of "pattern".

diff --git a/node_modules/sparqljs/lib/SparqlGenerator.js b/node_modules/sparqljs/lib/SparqlGenerator.js
index 527f0e9..ca03f98 100644
--- a/node_modules/sparqljs/lib/SparqlGenerator.js
+++ b/node_modules/sparqljs/lib/SparqlGenerator.js
@@ -110,6 +110,10 @@ Generator.prototype.bgp = function (bgp) {
   return this.encodeTriples(bgp.triples);
 };

+Generator.prototype.lineComment = function(comment) {
+  return comment.text.split('\n').map((line) => `# ${line}`).join(this._newline);
+}
+
 Generator.prototype.encodeTriples = function (triples) {
   if (!triples.length)
     return '';