Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace ParamList with Group #2142

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 63 additions & 54 deletions rdflib/plugins/sparql/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
from rdflib.compat import decodeUnicodeEscape

from . import operators as op
from .parserutils import Comp, Param, ParamList
from .parserutils import Comp, Param

# from pyparsing import Keyword as CaseSensitiveKeyword

Expand Down Expand Up @@ -427,9 +427,9 @@ def expandCollection(terms):
)

# [45] GraphOrDefault ::= 'DEFAULT' | 'GRAPH'? iri
GraphOrDefault = ParamList("graph", Keyword("DEFAULT")) | Optional(
GraphOrDefault = Group(Param("graph", Keyword("DEFAULT"))) | Optional(
Keyword("GRAPH")
) + ParamList("graph", iri)
) + Group(Param("graph", iri))

# [65] DataBlockValue ::= iri | RDFLiteral | NumericLiteral | BooleanLiteral | 'UNDEF'
DataBlockValue = iri | RDFLiteral | NumericLiteral | BooleanLiteral | Keyword("UNDEF")
Expand Down Expand Up @@ -466,11 +466,11 @@ def expandCollection(terms):
# [95] PathNegatedPropertySet ::= PathOneInPropertySet | '(' ( PathOneInPropertySet ( '|' PathOneInPropertySet )* )? ')'
PathNegatedPropertySet = Comp(
"PathNegatedPropertySet",
ParamList("part", PathOneInPropertySet)
Group(Param("part", PathOneInPropertySet))
| "("
+ Optional(
ParamList("part", PathOneInPropertySet)
+ ZeroOrMore("|" + ParamList("part", PathOneInPropertySet))
Group(Param("part", PathOneInPropertySet))
+ ZeroOrMore("|" + Group(Param("part", PathOneInPropertySet)))
)
+ ")",
)
Expand Down Expand Up @@ -498,15 +498,16 @@ def expandCollection(terms):
# [90] PathSequence ::= PathEltOrInverse ( '/' PathEltOrInverse )*
PathSequence = Comp(
"PathSequence",
ParamList("part", PathEltOrInverse)
+ ZeroOrMore("/" + ParamList("part", PathEltOrInverse)),
Group(Param("part", PathEltOrInverse))
+ ZeroOrMore("/" + Group(Param("part", PathEltOrInverse))),
)


# [89] PathAlternative ::= PathSequence ( '|' PathSequence )*
PathAlternative = Comp(
"PathAlternative",
ParamList("part", PathSequence) + ZeroOrMore("|" + ParamList("part", PathSequence)),
Group(Param("part", PathSequence))
+ ZeroOrMore("|" + Group(Param("part", PathSequence))),
)

# [88] Path ::= PathAlternative
Expand Down Expand Up @@ -583,8 +584,8 @@ def expandCollection(terms):
# To accommodate arbitrary amounts of triples this rule is rewritten to not be
# recursive:
# [52*] TriplesTemplate ::= TriplesSameSubject ( '.' TriplesSameSubject? )*
TriplesTemplate = ParamList("triples", TriplesSameSubject) + ZeroOrMore(
Suppress(".") + Optional(ParamList("triples", TriplesSameSubject))
TriplesTemplate = Group(Param("triples", TriplesSameSubject)) + ZeroOrMore(
Suppress(".") + Optional(Group(Param("triples", TriplesSameSubject)))
)

# [51] QuadsNotTriples ::= 'GRAPH' VarOrIri '{' Optional(TriplesTemplate) '}'
Expand All @@ -598,7 +599,7 @@ def expandCollection(terms):
"Quads",
Optional(TriplesTemplate)
+ ZeroOrMore(
ParamList("quadsNotTriples", QuadsNotTriples)
Group(Param("quadsNotTriples", QuadsNotTriples))
+ Optional(Suppress("."))
+ Optional(TriplesTemplate)
),
Expand All @@ -618,7 +619,7 @@ def expandCollection(terms):

# [55] TriplesBlock ::= TriplesSameSubjectPath ( '.' Optional(TriplesBlock) )?
TriplesBlock = Forward()
TriplesBlock <<= ParamList("triples", TriplesSameSubjectPath) + Optional(
TriplesBlock <<= Group(Param("triples", TriplesSameSubjectPath)) + Optional(
Suppress(".") + Optional(TriplesBlock)
)

Expand All @@ -631,8 +632,8 @@ def expandCollection(terms):
# [67] GroupOrUnionGraphPattern ::= GroupGraphPattern ( 'UNION' GroupGraphPattern )*
GroupOrUnionGraphPattern = Comp(
"GroupOrUnionGraphPattern",
ParamList("graph", GroupGraphPattern)
+ ZeroOrMore(Keyword("UNION") + ParamList("graph", GroupGraphPattern)),
Group(Param("graph", GroupGraphPattern))
+ ZeroOrMore(Keyword("UNION") + Group(Param("graph", GroupGraphPattern))),
)


Expand Down Expand Up @@ -1000,7 +1001,7 @@ def expandCollection(terms):
NIL
| "("
+ Param("distinct", _Distinct)
+ delimitedList(ParamList("expr", Expression))
+ delimitedList(Group(Param("expr", Expression)))
+ ")"
)

Expand Down Expand Up @@ -1045,8 +1046,8 @@ def expandCollection(terms):
"MultiplicativeExpression",
Param("expr", UnaryExpression)
+ ZeroOrMore(
ParamList("op", "*") + ParamList("other", UnaryExpression)
| ParamList("op", "/") + ParamList("other", UnaryExpression)
Group(Param("op", "*")) + Group(Param("other", UnaryExpression))
| Group(Param("op", "/")) + Group(Param("other", UnaryExpression))
),
).setEvalFn(op.MultiplicativeExpression)

Expand All @@ -1063,8 +1064,8 @@ def expandCollection(terms):
"AdditiveExpression",
Param("expr", MultiplicativeExpression)
+ ZeroOrMore(
ParamList("op", "+") + ParamList("other", MultiplicativeExpression)
| ParamList("op", "-") + ParamList("other", MultiplicativeExpression)
Group(Param("op", "+")) + Group(Param("other", MultiplicativeExpression))
| Group(Param("op", "-")) + Group(Param("other", MultiplicativeExpression))
),
).setEvalFn(op.AdditiveExpression)

Expand Down Expand Up @@ -1099,14 +1100,15 @@ def expandCollection(terms):
# [112] ConditionalAndExpression ::= ValueLogical ( '&&' ValueLogical )*
ConditionalAndExpression = Comp(
"ConditionalAndExpression",
Param("expr", ValueLogical) + ZeroOrMore("&&" + ParamList("other", ValueLogical)),
Param("expr", ValueLogical)
+ ZeroOrMore("&&" + Group(Param("other", ValueLogical))),
).setEvalFn(op.ConditionalAndExpression)

# [111] ConditionalOrExpression ::= ConditionalAndExpression ( '||' ConditionalAndExpression )*
ConditionalOrExpression = Comp(
"ConditionalOrExpression",
Param("expr", ConditionalAndExpression)
+ ZeroOrMore("||" + ParamList("other", ConditionalAndExpression)),
+ ZeroOrMore("||" + Group(Param("other", ConditionalAndExpression))),
).setEvalFn(op.ConditionalOrExpression)

# [110] Expression ::= ConditionalOrExpression
Expand Down Expand Up @@ -1154,7 +1156,7 @@ def expandCollection(terms):
"GroupClause",
Keyword("GROUP")
+ Keyword("BY")
+ OneOrMore(ParamList("condition", GroupCondition)),
+ OneOrMore(Group(Param("condition", GroupCondition))),
)


Expand Down Expand Up @@ -1222,7 +1224,7 @@ def expandCollection(terms):
Param("delete", DeleteClause) + Optional(Param("insert", InsertClause))
| Param("insert", InsertClause)
)
+ ZeroOrMore(ParamList("using", UsingClause))
+ ZeroOrMore(Group(Param("using", UsingClause)))
+ Keyword("WHERE")
+ Param("where", GroupGraphPattern),
)
Expand All @@ -1246,17 +1248,22 @@ def expandCollection(terms):

# [63] InlineDataOneVar ::= Var '{' ZeroOrMore(DataBlockValue) '}'
InlineDataOneVar = (
ParamList("var", Var) + "{" + ZeroOrMore(ParamList("value", DataBlockValue)) + "}"
Group(Param("var", Var))
+ "{"
+ ZeroOrMore(Group(Param("value", DataBlockValue)))
+ "}"
)

# [64] InlineDataFull ::= ( NIL | '(' ZeroOrMore(Var) ')' ) '{' ( '(' ZeroOrMore(DataBlockValue) ')' | NIL )* '}'
InlineDataFull = (
(NIL | "(" + ZeroOrMore(ParamList("var", Var)) + ")")
(NIL | "(" + ZeroOrMore(Group(Param("var", Var))) + ")")
+ "{"
+ ZeroOrMore(
ParamList(
"value",
Group(Suppress("(") + ZeroOrMore(DataBlockValue) + Suppress(")") | NIL),
Group(
Param(
"value",
Group(Suppress("(") + ZeroOrMore(DataBlockValue) + Suppress(")") | NIL),
)
)
)
+ "}"
Expand All @@ -1274,7 +1281,7 @@ def expandCollection(terms):

# [74] ConstructTriples ::= TriplesSameSubject ( '.' Optional(ConstructTriples) )?
ConstructTriples = Forward()
ConstructTriples <<= ParamList("template", TriplesSameSubject) + Optional(
ConstructTriples <<= Group(Param("template", TriplesSameSubject)) + Optional(
Suppress(".") + Optional(ConstructTriples)
)

Expand Down Expand Up @@ -1331,11 +1338,11 @@ def expandCollection(terms):
# [54] GroupGraphPatternSub ::= Optional(TriplesBlock) ( GraphPatternNotTriples '.'? Optional(TriplesBlock) )*
GroupGraphPatternSub = Comp(
"GroupGraphPatternSub",
Optional(ParamList("part", Comp("TriplesBlock", TriplesBlock)))
Optional(Group(Param("part", Comp("TriplesBlock", TriplesBlock))))
+ ZeroOrMore(
ParamList("part", GraphPatternNotTriples)
Group(Param("part", GraphPatternNotTriples))
+ Optional(".")
+ Optional(ParamList("part", Comp("TriplesBlock", TriplesBlock)))
+ Optional(Group(Param("part", Comp("TriplesBlock", TriplesBlock))))
),
)

Expand All @@ -1347,7 +1354,7 @@ def expandCollection(terms):
# [21] HavingClause ::= 'HAVING' HavingCondition+
HavingClause = Comp(
"HavingClause",
Keyword("HAVING") + OneOrMore(ParamList("condition", HavingCondition)),
Keyword("HAVING") + OneOrMore(Group(Param("condition", HavingCondition))),
)

# [24] OrderCondition ::= ( ( 'ASC' | 'DESC' ) BrackettedExpression )
Expand All @@ -1364,7 +1371,7 @@ def expandCollection(terms):
"OrderClause",
Keyword("ORDER")
+ Keyword("BY")
+ OneOrMore(ParamList("condition", OrderCondition)),
+ OneOrMore(Group(Param("condition", OrderCondition))),
)

# [26] LimitClause ::= 'LIMIT' INTEGER
Expand Down Expand Up @@ -1394,19 +1401,21 @@ def expandCollection(terms):
+ Optional(Param("modifier", Keyword("DISTINCT") | Keyword("REDUCED")))
+ (
OneOrMore(
ParamList(
"projection",
Comp(
"vars",
Param("var", Var)
| (
Literal("(")
+ Param("expr", Expression)
+ Keyword("AS")
+ Param("evar", Var)
+ ")"
Group(
Param(
"projection",
Comp(
"vars",
Param("var", Var)
| (
Literal("(")
+ Param("expr", Expression)
+ Keyword("AS")
+ Param("evar", Var)
+ ")"
),
),
),
)
)
)
| "*"
Expand All @@ -1428,7 +1437,7 @@ def expandCollection(terms):
SelectQuery = Comp(
"SelectQuery",
SelectClause
+ ZeroOrMore(ParamList("datasetClause", DatasetClause))
+ ZeroOrMore(Group(Param("datasetClause", DatasetClause)))
+ WhereClause
+ SolutionModifier
+ ValuesClause,
Expand All @@ -1442,19 +1451,19 @@ def expandCollection(terms):
Keyword("CONSTRUCT")
+ (
ConstructTemplate
+ ZeroOrMore(ParamList("datasetClause", DatasetClause))
+ ZeroOrMore(Group(Param("datasetClause", DatasetClause)))
+ WhereClause
+ SolutionModifier
+ ValuesClause
| ZeroOrMore(ParamList("datasetClause", DatasetClause))
| ZeroOrMore(Group(Param("datasetClause", DatasetClause)))
+ Keyword("WHERE")
+ "{"
+ Optional(
Param(
"where",
Comp(
"FakeGroupGraphPatten",
ParamList("part", Comp("TriplesBlock", TriplesTemplate)),
Group(Param("part", Comp("TriplesBlock", TriplesTemplate))),
),
)
)
Expand All @@ -1478,7 +1487,7 @@ def expandCollection(terms):
DescribeQuery = Comp(
"DescribeQuery",
Keyword("DESCRIBE")
+ (OneOrMore(ParamList("var", VarOrIri)) | "*")
+ (OneOrMore(Group(Param("var", VarOrIri))) | "*")
+ Param("datasetClause", ZeroOrMore(DatasetClause))
+ Optional(WhereClause)
+ SolutionModifier
Expand All @@ -1487,8 +1496,8 @@ def expandCollection(terms):

# [29] Update ::= Prologue ( Update1 ( ';' Update )? )?
Update = Forward()
Update <<= ParamList("prologue", Prologue) + Optional(
ParamList("request", Update1) + Optional(";" + Update)
Update <<= Group(Param("prologue", Prologue)) + Optional(
Group(Param("request", Update1)) + Optional(";" + Update)
)


Expand Down
37 changes: 11 additions & 26 deletions rdflib/plugins/sparql/parserutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,7 @@ class ParamValue(object):
All cleverness is in the CompValue
"""

def __init__(self, name, tokenList, isList):
self.isList = isList
def __init__(self, name, tokenList):
self.name = name
if isinstance(tokenList, (list, ParseResults)) and len(tokenList) == 1:
tokenList = tokenList[0]
Expand All @@ -109,27 +108,15 @@ def __str__(self):
class Param(TokenConverter):
"""
A pyparsing token for labelling a part of the parse-tree
if isList is true repeat occurrences of ParamList have
their values merged in a list
"""

def __init__(self, name, expr, isList=False):
self.isList = isList
def __init__(self, name, expr):
TokenConverter.__init__(self, expr)
self.setName(name)
self.addParseAction(self.postParse2)

def postParse2(self, tokenList):
return ParamValue(self.name, tokenList, self.isList)


class ParamList(Param):
"""
A shortcut for a Param with isList=True
"""

def __init__(self, name, expr):
Param.__init__(self, name, expr, True)
return ParamValue(self.name, tokenList)


class CompValue(OrderedDict):
Expand Down Expand Up @@ -235,16 +222,14 @@ def postParse(self, instring, loc, tokenList):
res["service_string"] = service_string

for t in tokenList:
if isinstance(t, ParamValue):
if t.isList:
if t.name not in res:
res[t.name] = []
res[t.name].append(t.tokenList)
else:
res[t.name] = t.tokenList
# res.append(t.tokenList)
# if isinstance(t,CompValue):
# res.update(t)
if isinstance(t, ParseResults):
for i in t:
if isinstance(i, ParamValue):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could it make sense to raise an exception if this condition does not match?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I think that's a lot clearer, as otherwise it looks like we're filtering our for ParamValues, but they should all be ParamValues. Fixed in latest commit.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Raising a TypeError here conflicts with this line in the docstring: "Any sub-tokens that are not Params will be ignored." So raising TypeError here may start breaking some existing code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I completely missed that! I'm not sure how true that line in the docstring is, but I think it's worth an investigation in a separate PR.

if i.name not in res:
res[i.name] = []
res[i.name].append(i.tokenList)
elif isinstance(t, ParamValue):
res[t.name] = t.tokenList
return res

def setEvalFn(self, evalfn):
Expand Down