Skip to content

Commit

Permalink
Merge pull request #528 from pchampin/fix-issue-381
Browse files Browse the repository at this point in the history
SPARQL parser can deal with spurious ";", fixes #381
  • Loading branch information
joernhees committed Sep 28, 2015
2 parents 12596d8 + f4bcab1 commit 9dac484
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 3 deletions.
7 changes: 4 additions & 3 deletions rdflib/plugins/sparql/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,11 @@ def expandTriples(terms):
l = len(terms)
for i, t in enumerate(terms):
if t == ',':
res.append(res[i - 3])
res.append(res[i - 2])
res.extend([res[-3], res[-2]])
elif t == ';':
res.append(res[i - 3])
if i+1 == len(terms) or terms[i+1] == ";" or terms[i+1] == ".":
continue # this semicolon is spurious
res.append(res[-3])
elif isinstance(t, list):
# BlankNodePropertyList
# is this bnode the object of previous triples?
Expand Down
119 changes: 119 additions & 0 deletions test/test_issue381.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
from rdflib import BNode, Graph, Namespace
from rdflib.compare import isomorphic

NS = Namespace("http://example.org/")

def test_no_spurious_semicolon():
sparql = """
PREFIX : <http://example.org/>
CONSTRUCT {
:a :b :c ; :d :e .
} WHERE {}
"""
expected = Graph()
expected.addN( t+(expected,) for t in [
(NS.a, NS.b, NS.c),
(NS.a, NS.d, NS.e),
])
got = Graph().query(sparql).graph
assert isomorphic(got, expected), got.serialize(format="turtle")

def test_one_spurious_semicolon():
sparql = """
PREFIX : <http://example.org/>
CONSTRUCT {
:a :b :c ; :d :e ; .
} WHERE {}
"""
expected = Graph()
expected.addN( t+(expected,) for t in [
(NS.a, NS.b, NS.c),
(NS.a, NS.d, NS.e),
])
got = Graph().query(sparql).graph
assert isomorphic(got, expected), got.serialize(format="turtle")

def test_one_spurious_semicolon_no_perdiod():
sparql = """
PREFIX : <http://example.org/>
CONSTRUCT {
:a :b :c ; :d :e ;
} WHERE {}
"""
expected = Graph()
expected.addN( t+(expected,) for t in [
(NS.a, NS.b, NS.c),
(NS.a, NS.d, NS.e),
])
got = Graph().query(sparql).graph
assert isomorphic(got, expected), got.serialize(format="turtle")

def test_two_spurious_semicolons_no_period():
sparql = """
PREFIX : <http://example.org/>
CONSTRUCT {
:a :b :c ; :d :e ; ;
} WHERE {}
"""
expected = Graph()
expected.addN( t+(expected,) for t in [
(NS.a, NS.b, NS.c),
(NS.a, NS.d, NS.e),
])
got = Graph().query(sparql).graph
assert isomorphic(got, expected), got.serialize(format="turtle")

def test_one_spurious_semicolons_bnode():
sparql = """
PREFIX : <http://example.org/>
CONSTRUCT {
[ :b :c ; :d :e ; ]
} WHERE {}
"""
expected = Graph()
expected.addN( t+(expected,) for t in [
(BNode("a"), NS.b, NS.c),
(BNode("a"), NS.d, NS.e),
])
got = Graph().query(sparql).graph
assert isomorphic(got, expected), got.serialize(format="turtle")

def test_pathological():
"""
This test did not raise an exception,
but generated a graph completely different from the expected one.
"""
sparql = """
PREFIX : <http://example.org/>
CONSTRUCT {
:a :b :c ; ;
:d :e ; ;
:f :g ;
} WHERE {}
"""
expected = Graph()
expected.addN( t+(expected,) for t in [
(NS.a, NS.b, NS.c),
(NS.a, NS.d, NS.e),
(NS.a, NS.f, NS.g),
])
got = Graph().query(sparql).graph
assert isomorphic(got, expected), got.serialize(format="turtle")

def test_mixing_spurious_semicolons_and_commas():
sparql = """
PREFIX : <http://example.org/>
CONSTRUCT {
:a :b :c ; ;
:d :e, :f
} WHERE {}
"""
expected = Graph()
expected.addN( t+(expected,) for t in [
(NS.a, NS.b, NS.c),
(NS.a, NS.d, NS.e),
(NS.a, NS.d, NS.f),
])
got = Graph().query(sparql).graph
assert isomorphic(got, expected), got.serialize(format="turtle")

0 comments on commit 9dac484

Please sign in to comment.