sparql 3.1.0 → 3.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +188 -73
- data/UNLICENSE +1 -1
- data/VERSION +1 -1
- data/bin/sparql +37 -17
- data/lib/rack/sparql/conneg.rb +2 -2
- data/lib/sinatra/sparql.rb +4 -4
- data/lib/sparql.rb +13 -12
- data/lib/sparql/algebra.rb +11 -19
- data/lib/sparql/algebra/aggregate.rb +2 -2
- data/lib/sparql/algebra/expression.rb +67 -38
- data/lib/sparql/algebra/extensions.rb +182 -23
- data/lib/sparql/algebra/operator.rb +55 -22
- data/lib/sparql/algebra/operator/abs.rb +2 -2
- data/lib/sparql/algebra/operator/add.rb +2 -2
- data/lib/sparql/algebra/operator/alt.rb +2 -2
- data/lib/sparql/algebra/operator/and.rb +3 -3
- data/lib/sparql/algebra/operator/asc.rb +1 -1
- data/lib/sparql/algebra/operator/ask.rb +2 -12
- data/lib/sparql/algebra/operator/avg.rb +8 -1
- data/lib/sparql/algebra/operator/base.rb +8 -8
- data/lib/sparql/algebra/operator/bgp.rb +2 -2
- data/lib/sparql/algebra/operator/bnode.rb +2 -2
- data/lib/sparql/algebra/operator/bound.rb +1 -1
- data/lib/sparql/algebra/operator/ceil.rb +2 -2
- data/lib/sparql/algebra/operator/clear.rb +2 -2
- data/lib/sparql/algebra/operator/coalesce.rb +1 -11
- data/lib/sparql/algebra/operator/compare.rb +15 -8
- data/lib/sparql/algebra/operator/concat.rb +2 -2
- data/lib/sparql/algebra/operator/construct.rb +4 -13
- data/lib/sparql/algebra/operator/contains.rb +2 -2
- data/lib/sparql/algebra/operator/copy.rb +2 -2
- data/lib/sparql/algebra/operator/count.rb +1 -1
- data/lib/sparql/algebra/operator/create.rb +2 -2
- data/lib/sparql/algebra/operator/dataset.rb +3 -14
- data/lib/sparql/algebra/operator/datatype.rb +1 -1
- data/lib/sparql/algebra/operator/day.rb +1 -1
- data/lib/sparql/algebra/operator/delete.rb +6 -6
- data/lib/sparql/algebra/operator/delete_data.rb +2 -2
- data/lib/sparql/algebra/operator/delete_where.rb +3 -3
- data/lib/sparql/algebra/operator/desc.rb +1 -1
- data/lib/sparql/algebra/operator/describe.rb +2 -12
- data/lib/sparql/algebra/operator/distinct.rb +2 -12
- data/lib/sparql/algebra/operator/divide.rb +1 -1
- data/lib/sparql/algebra/operator/drop.rb +2 -2
- data/lib/sparql/algebra/operator/encode_for_uri.rb +2 -2
- data/lib/sparql/algebra/operator/equal.rb +2 -2
- data/lib/sparql/algebra/operator/exists.rb +1 -1
- data/lib/sparql/algebra/operator/exprlist.rb +1 -11
- data/lib/sparql/algebra/operator/extend.rb +3 -12
- data/lib/sparql/algebra/operator/filter.rb +3 -13
- data/lib/sparql/algebra/operator/floor.rb +2 -2
- data/lib/sparql/algebra/operator/graph.rb +4 -15
- data/lib/sparql/algebra/operator/greater_than.rb +5 -5
- data/lib/sparql/algebra/operator/greater_than_or_equal.rb +5 -5
- data/lib/sparql/algebra/operator/group.rb +14 -14
- data/lib/sparql/algebra/operator/group_concat.rb +1 -1
- data/lib/sparql/algebra/operator/hours.rb +1 -1
- data/lib/sparql/algebra/operator/if.rb +1 -11
- data/lib/sparql/algebra/operator/in.rb +1 -11
- data/lib/sparql/algebra/operator/insert.rb +4 -4
- data/lib/sparql/algebra/operator/insert_data.rb +2 -2
- data/lib/sparql/algebra/operator/iri.rb +1 -1
- data/lib/sparql/algebra/operator/is_blank.rb +1 -1
- data/lib/sparql/algebra/operator/is_iri.rb +1 -1
- data/lib/sparql/algebra/operator/is_literal.rb +1 -1
- data/lib/sparql/algebra/operator/is_numeric.rb +1 -1
- data/lib/sparql/algebra/operator/is_triple.rb +30 -0
- data/lib/sparql/algebra/operator/join.rb +9 -7
- data/lib/sparql/algebra/operator/lang.rb +1 -1
- data/lib/sparql/algebra/operator/lang_matches.rb +3 -3
- data/lib/sparql/algebra/operator/lcase.rb +2 -2
- data/lib/sparql/algebra/operator/left_join.rb +16 -9
- data/lib/sparql/algebra/operator/less_than.rb +5 -5
- data/lib/sparql/algebra/operator/less_than_or_equal.rb +5 -5
- data/lib/sparql/algebra/operator/load.rb +2 -2
- data/lib/sparql/algebra/operator/max.rb +8 -1
- data/lib/sparql/algebra/operator/md5.rb +1 -1
- data/lib/sparql/algebra/operator/min.rb +8 -1
- data/lib/sparql/algebra/operator/minus.rb +9 -8
- data/lib/sparql/algebra/operator/minutes.rb +1 -1
- data/lib/sparql/algebra/operator/modify.rb +1 -1
- data/lib/sparql/algebra/operator/month.rb +1 -1
- data/lib/sparql/algebra/operator/move.rb +2 -2
- data/lib/sparql/algebra/operator/multiply.rb +1 -1
- data/lib/sparql/algebra/operator/negate.rb +1 -1
- data/lib/sparql/algebra/operator/not.rb +1 -1
- data/lib/sparql/algebra/operator/not_equal.rb +2 -2
- data/lib/sparql/algebra/operator/notexists.rb +2 -2
- data/lib/sparql/algebra/operator/notin.rb +1 -11
- data/lib/sparql/algebra/operator/notoneof.rb +2 -2
- data/lib/sparql/algebra/operator/now.rb +1 -1
- data/lib/sparql/algebra/operator/object.rb +27 -0
- data/lib/sparql/algebra/operator/or.rb +3 -3
- data/lib/sparql/algebra/operator/order.rb +2 -12
- data/lib/sparql/algebra/operator/path.rb +2 -2
- data/lib/sparql/algebra/operator/path_opt.rb +2 -2
- data/lib/sparql/algebra/operator/path_plus.rb +2 -2
- data/lib/sparql/algebra/operator/path_star.rb +2 -2
- data/lib/sparql/algebra/operator/plus.rb +2 -2
- data/lib/sparql/algebra/operator/predicate.rb +27 -0
- data/lib/sparql/algebra/operator/prefix.rb +8 -8
- data/lib/sparql/algebra/operator/project.rb +2 -12
- data/lib/sparql/algebra/operator/rand.rb +1 -1
- data/lib/sparql/algebra/operator/reduced.rb +2 -12
- data/lib/sparql/algebra/operator/regex.rb +5 -5
- data/lib/sparql/algebra/operator/replace.rb +3 -3
- data/lib/sparql/algebra/operator/reverse.rb +2 -2
- data/lib/sparql/algebra/operator/round.rb +2 -2
- data/lib/sparql/algebra/operator/same_term.rb +8 -5
- data/lib/sparql/algebra/operator/sample.rb +9 -2
- data/lib/sparql/algebra/operator/seconds.rb +1 -1
- data/lib/sparql/algebra/operator/seq.rb +1 -1
- data/lib/sparql/algebra/operator/sequence.rb +1 -1
- data/lib/sparql/algebra/operator/sha1.rb +1 -1
- data/lib/sparql/algebra/operator/sha256.rb +1 -1
- data/lib/sparql/algebra/operator/sha384.rb +1 -1
- data/lib/sparql/algebra/operator/sha512.rb +1 -1
- data/lib/sparql/algebra/operator/slice.rb +2 -12
- data/lib/sparql/algebra/operator/str.rb +1 -1
- data/lib/sparql/algebra/operator/strafter.rb +2 -2
- data/lib/sparql/algebra/operator/strbefore.rb +2 -2
- data/lib/sparql/algebra/operator/strdt.rb +2 -2
- data/lib/sparql/algebra/operator/strends.rb +2 -2
- data/lib/sparql/algebra/operator/strlang.rb +2 -2
- data/lib/sparql/algebra/operator/strlen.rb +2 -2
- data/lib/sparql/algebra/operator/strstarts.rb +2 -2
- data/lib/sparql/algebra/operator/struuid.rb +1 -1
- data/lib/sparql/algebra/operator/subject.rb +29 -0
- data/lib/sparql/algebra/operator/substr.rb +3 -3
- data/lib/sparql/algebra/operator/subtract.rb +1 -1
- data/lib/sparql/algebra/operator/sum.rb +1 -1
- data/lib/sparql/algebra/operator/table.rb +2 -2
- data/lib/sparql/algebra/operator/timezone.rb +1 -1
- data/lib/sparql/algebra/operator/triple.rb +27 -0
- data/lib/sparql/algebra/operator/tz.rb +1 -1
- data/lib/sparql/algebra/operator/ucase.rb +2 -2
- data/lib/sparql/algebra/operator/union.rb +7 -6
- data/lib/sparql/algebra/operator/update.rb +2 -2
- data/lib/sparql/algebra/operator/using.rb +2 -2
- data/lib/sparql/algebra/operator/uuid.rb +1 -1
- data/lib/sparql/algebra/operator/with.rb +3 -3
- data/lib/sparql/algebra/operator/year.rb +1 -1
- data/lib/sparql/algebra/query.rb +1 -1
- data/lib/sparql/algebra/update.rb +1 -1
- data/lib/sparql/algebra/version.rb +1 -1
- data/lib/sparql/extensions.rb +7 -13
- data/lib/sparql/grammar.rb +81 -6
- data/lib/sparql/grammar/meta.rb +5801 -1584
- data/lib/sparql/grammar/parser11.rb +116 -50
- data/lib/sparql/grammar/terminals11.rb +4 -0
- data/lib/sparql/results.rb +70 -43
- data/lib/sparql/version.rb +1 -1
- metadata +34 -39
@@ -6,8 +6,8 @@ module SPARQL::Grammar
|
|
6
6
|
##
|
7
7
|
# A parser for the SPARQL 1.1 grammar.
|
8
8
|
#
|
9
|
-
# @see
|
10
|
-
# @see
|
9
|
+
# @see https://www.w3.org/TR/sparql11-query/#grammar
|
10
|
+
# @see https://en.wikipedia.org/wiki/LR_parser
|
11
11
|
class Parser
|
12
12
|
include SPARQL::Grammar::Meta
|
13
13
|
include SPARQL::Grammar::Terminals
|
@@ -23,6 +23,7 @@ module SPARQL::Grammar
|
|
23
23
|
STRAFTER STRBEFORE STRDT STRENDS STRLANG STRLEN STRSTARTS STRUUID STR
|
24
24
|
TIMEZONE TZ UCASE URI UUID YEAR
|
25
25
|
isBLANK isIRI isURI isLITERAL isNUMERIC sameTerm
|
26
|
+
isTRIPLE TRIPLE SUBJECT PREDICATE OBJECT
|
26
27
|
}.map {|s| s.downcase.to_sym}.freeze
|
27
28
|
|
28
29
|
BUILTIN_RULES = [:aggregate, :regex, :substr, :replace, :exists, :notexists].freeze
|
@@ -184,6 +185,7 @@ module SPARQL::Grammar
|
|
184
185
|
|STRAFTER|STRBEFORE|STRDT|STRENDS|STRLANG|STRLEN|STRSTARTS|STRUUID|SUBSTR|STR|SUM
|
185
186
|
|TIMEZONE|TZ|UCASE|UNDEF|URI|UUID|YEAR
|
186
187
|
|isBLANK|isIRI|isURI|isLITERAL|isNUMERIC|sameTerm
|
188
|
+
|isTRIPLE|TRIPLE|SUBJECT|PREDICATE|OBJECT
|
187
189
|
}x
|
188
190
|
add_prod_datum(token.value.downcase.to_sym, token.value.downcase.to_sym)
|
189
191
|
else
|
@@ -586,7 +588,7 @@ module SPARQL::Grammar
|
|
586
588
|
production(:GroupGraphPatternSub) do |input, data, callback|
|
587
589
|
debug("GroupGraphPatternSub") {"q #{data[:query].inspect}"}
|
588
590
|
|
589
|
-
res = case data[:query].length
|
591
|
+
res = case Array(data[:query]).length
|
590
592
|
when 0 then SPARQL::Algebra::Operator::BGP.new
|
591
593
|
when 1 then data[:query].first
|
592
594
|
when 2
|
@@ -647,7 +649,7 @@ module SPARQL::Grammar
|
|
647
649
|
data[:input_query] = input.delete(:query) || [SPARQL::Algebra::Operator::BGP.new]
|
648
650
|
end
|
649
651
|
production(:GraphPatternNotTriples) do |input, data, callback|
|
650
|
-
lhs = data[:input_query].first
|
652
|
+
lhs = Array(data[:input_query]).first
|
651
653
|
|
652
654
|
# Filter trickls up to GroupGraphPatternSub
|
653
655
|
add_prod_datum(:filter, data[:filter])
|
@@ -752,7 +754,7 @@ module SPARQL::Grammar
|
|
752
754
|
end
|
753
755
|
end
|
754
756
|
|
755
|
-
# [65] DataBlockValue ::= iri | RDFLiteral | NumericLiteral | BooleanLiteral | 'UNDEF'
|
757
|
+
# [65] DataBlockValue ::= EmbTD | iri | RDFLiteral | NumericLiteral | BooleanLiteral | 'UNDEF'
|
756
758
|
production(:DataBlockValue) do |input, data, callback|
|
757
759
|
add_prod_datum :DataBlockValue, data.values.first
|
758
760
|
end
|
@@ -831,7 +833,7 @@ module SPARQL::Grammar
|
|
831
833
|
add_prod_datum(:ConstructTemplate, data[:ConstructTemplate])
|
832
834
|
end
|
833
835
|
|
834
|
-
# [75] TriplesSameSubject ::=
|
836
|
+
# [75] TriplesSameSubject ::= VarOrTermOrEmbTP PropertyListNotEmpty
|
835
837
|
# | TriplesNode PropertyList
|
836
838
|
production(:TriplesSameSubject) do |input, data, callback|
|
837
839
|
add_prod_datum(:pattern, data[:pattern])
|
@@ -840,8 +842,8 @@ module SPARQL::Grammar
|
|
840
842
|
# [77] PropertyListNotEmpty ::= Verb ObjectList
|
841
843
|
# ( ';' ( Verb ObjectList )? )*
|
842
844
|
start_production(:PropertyListNotEmpty) do |input, data, callback|
|
843
|
-
subject = input[:
|
844
|
-
error(nil, "Expected
|
845
|
+
subject = input[:VarOrTermOrEmbTP] || input[:TriplesNode] || input[:GraphNode]
|
846
|
+
error(nil, "Expected VarOrTermOrEmbTP or TriplesNode or GraphNode", production: :PropertyListNotEmpty) if validate? && !subject
|
845
847
|
data[:Subject] = subject
|
846
848
|
end
|
847
849
|
production(:PropertyListNotEmpty) do |input, data, callback|
|
@@ -867,13 +869,17 @@ module SPARQL::Grammar
|
|
867
869
|
add_prod_datum(:path, data[:path])
|
868
870
|
end
|
869
871
|
|
870
|
-
# [80] Object ::= GraphNode
|
872
|
+
# [80] Object ::= GraphNode AnnotationPattern?
|
873
|
+
start_production(:Object) do |input, data, callback|
|
874
|
+
data[:Subject] = Array(input[:Subject]).first
|
875
|
+
data[:Verb] = Array(input[:Verb]).first
|
876
|
+
end
|
871
877
|
production(:Object) do |input, data, callback|
|
872
|
-
object = data[:
|
878
|
+
object = data[:GraphNode]
|
879
|
+
add_prod_datum(:pattern, data[:pattern])
|
873
880
|
if object
|
874
881
|
if prod_data[:Verb]
|
875
882
|
add_pattern(:Object, subject: prod_data[:Subject], predicate: prod_data[:Verb], object: object)
|
876
|
-
add_prod_datum(:pattern, data[:pattern])
|
877
883
|
elsif prod_data[:VerbPath]
|
878
884
|
add_prod_datum(:path,
|
879
885
|
SPARQL::Algebra::Expression(:path,
|
@@ -883,8 +889,17 @@ module SPARQL::Grammar
|
|
883
889
|
end
|
884
890
|
end
|
885
891
|
end
|
892
|
+
start_production(:_Object_1) do |input, data, callback|
|
893
|
+
pattern = RDF::Query::Pattern.new(input[:Subject], input[:Verb], input[:GraphNode].first)
|
894
|
+
error("ObjectPath", "Expected Verb",
|
895
|
+
production: :_Object_1) unless input[:Verb]
|
896
|
+
data[:TriplesNode] = [pattern]
|
897
|
+
end
|
898
|
+
production(:_Object_1) do |input, data, callback|
|
899
|
+
add_prod_datum(:pattern, data[:pattern])
|
900
|
+
end
|
886
901
|
|
887
|
-
# [81] TriplesSameSubjectPath ::=
|
902
|
+
# [81] TriplesSameSubjectPath ::= VarOrTermOrEmbTP PropertyListPathNotEmpty | TriplesNode PropertyListPath
|
888
903
|
production(:TriplesSameSubjectPath) do |input, data, callback|
|
889
904
|
add_prod_datum(:pattern, data[:pattern])
|
890
905
|
add_prod_datum(:path, data[:path])
|
@@ -892,8 +907,8 @@ module SPARQL::Grammar
|
|
892
907
|
|
893
908
|
# [83] PropertyListPathNotEmpty ::= ( VerbPath | VerbSimple ) ObjectList ( ';' ( ( VerbPath | VerbSimple ) ObjectList )? )*
|
894
909
|
start_production(:PropertyListPathNotEmpty) do |input, data, callback|
|
895
|
-
subject = input[:
|
896
|
-
error(nil, "Expected
|
910
|
+
subject = input[:VarOrTermOrEmbTP] || input[:TriplesNode] || input[:GraphNode]
|
911
|
+
error(nil, "Expected VarOrTermOrEmbTP, got nothing", production: :PropertyListPathNotEmpty) if validate? && !subject
|
897
912
|
data[:Subject] = subject
|
898
913
|
end
|
899
914
|
production(:PropertyListPathNotEmpty) do |input, data, callback|
|
@@ -933,9 +948,13 @@ module SPARQL::Grammar
|
|
933
948
|
add_prod_datum(:path, data[:path])
|
934
949
|
end
|
935
950
|
|
936
|
-
# [87] ObjectPath ::= GraphNodePath
|
951
|
+
# [87] ObjectPath ::= GraphNodePath AnnotationPatternPath?
|
952
|
+
start_production(:ObjectPath) do |input, data, callback|
|
953
|
+
data[:Subject] = Array(input[:Subject]).first
|
954
|
+
data[:Verb] = Array(input[:Verb]).first
|
955
|
+
end
|
937
956
|
production(:ObjectPath) do |input, data, callback|
|
938
|
-
object = data[:
|
957
|
+
object = data[:VarOrTermOrEmbTP] || data[:TriplesNode] || data[:GraphNode]
|
939
958
|
if object
|
940
959
|
if prod_data[:Verb]
|
941
960
|
if data[:pattern] && data[:path]
|
@@ -943,6 +962,9 @@ module SPARQL::Grammar
|
|
943
962
|
data[:pattern].unshift(RDF::Query::Pattern.new(prod_data[:Subject].first, prod_data[:Verb], object.first))
|
944
963
|
bgp = SPARQL::Algebra::Expression[:bgp, data[:pattern]]
|
945
964
|
add_prod_datum(:path, SPARQL::Algebra::Expression[:sequence, bgp, *data[:path]])
|
965
|
+
elsif data[:path]
|
966
|
+
# AnnotationPatternPath case
|
967
|
+
add_prod_datum(:path, data[:path])
|
946
968
|
else
|
947
969
|
add_pattern(:Object, subject: prod_data[:Subject], predicate: prod_data[:Verb], object: object)
|
948
970
|
add_prod_datum(:pattern, data[:pattern])
|
@@ -956,6 +978,16 @@ module SPARQL::Grammar
|
|
956
978
|
end
|
957
979
|
end
|
958
980
|
end
|
981
|
+
start_production(:_ObjectPath_1) do |input, data, callback|
|
982
|
+
pattern = RDF::Query::Pattern.new(input[:Subject], input[:Verb], input[:GraphNode].first)
|
983
|
+
error("ObjectPath", "Expected Verb",
|
984
|
+
production: :_ObjectPath_1) unless input[:Verb]
|
985
|
+
data[:TriplesNode] = [pattern]
|
986
|
+
end
|
987
|
+
production(:_ObjectPath_1) do |input, data, callback|
|
988
|
+
add_prod_datum(:pattern, data[:pattern])
|
989
|
+
end
|
990
|
+
|
959
991
|
# [88] Path ::= PathAlternative
|
960
992
|
# output is a :Path or :iri
|
961
993
|
production(:Path) do |input, data, callback|
|
@@ -1084,24 +1116,24 @@ module SPARQL::Grammar
|
|
1084
1116
|
add_prod_datum(:path, data[:path])
|
1085
1117
|
end
|
1086
1118
|
|
1087
|
-
# [104] GraphNode ::=
|
1119
|
+
# [104] GraphNode ::= VarOrTermOrEmbTP | TriplesNode
|
1088
1120
|
production(:GraphNode) do |input, data, callback|
|
1089
|
-
term = data[:
|
1121
|
+
term = data[:VarOrTermOrEmbTP] || data[:TriplesNode]
|
1090
1122
|
add_prod_datum(:pattern, data[:pattern])
|
1091
1123
|
add_prod_datum(:GraphNode, term)
|
1092
1124
|
end
|
1093
1125
|
|
1094
|
-
# [105] GraphNodePath ::=
|
1126
|
+
# [105] GraphNodePath ::= VarOrTermOrEmbTP | TriplesNodePath
|
1095
1127
|
production(:GraphNodePath) do |input, data, callback|
|
1096
|
-
term = data[:
|
1128
|
+
term = data[:VarOrTermOrEmbTP] || data[:TriplesNode]
|
1097
1129
|
add_prod_datum(:pattern, data[:pattern])
|
1098
1130
|
add_prod_datum(:path, data[:path])
|
1099
1131
|
add_prod_datum(:GraphNode, term)
|
1100
1132
|
end
|
1101
1133
|
|
1102
|
-
# [
|
1103
|
-
production(:
|
1104
|
-
data.values.each {|v| add_prod_datum(:
|
1134
|
+
# [106s] VarOrTermOrEmbTP ::= Var | GraphTerm | EmbTP
|
1135
|
+
production(:VarOrTermOrEmbTP) do |input, data, callback|
|
1136
|
+
data.values.each {|v| add_prod_datum(:VarOrTermOrEmbTP, v)}
|
1105
1137
|
end
|
1106
1138
|
|
1107
1139
|
# [107] VarOrIri ::= Var | iri
|
@@ -1119,6 +1151,22 @@ module SPARQL::Grammar
|
|
1119
1151
|
data[:NIL])
|
1120
1152
|
end
|
1121
1153
|
|
1154
|
+
# [174] EmbTP ::= '<<' EmbSubjectOrObject Verb EmbSubjectOrObject '>>'
|
1155
|
+
production(:EmbTP) do |input, data, callback|
|
1156
|
+
subject, object = data[:EmbSubjectOrObject]
|
1157
|
+
predicate = data[:Verb]
|
1158
|
+
add_pattern(:EmbTP,
|
1159
|
+
subject: subject,
|
1160
|
+
predicate: predicate,
|
1161
|
+
object: object)
|
1162
|
+
end
|
1163
|
+
|
1164
|
+
# [175] EmbSubjectOrObject ::= Var | BlankNode | iri | RDFLiteral
|
1165
|
+
# | NumericLiteral | BooleanLiteral | EmbTP
|
1166
|
+
production(:EmbSubjectOrObject) do |input, data, callback|
|
1167
|
+
data.values.each {|v| add_prod_datum(:EmbSubjectOrObject, v)}
|
1168
|
+
end
|
1169
|
+
|
1122
1170
|
# [110] Expression ::= ConditionalOrExpression
|
1123
1171
|
production(:Expression) do |input, data, callback|
|
1124
1172
|
add_prod_datum(:Expression, data[:Expression])
|
@@ -1258,6 +1306,7 @@ module SPARQL::Grammar
|
|
1258
1306
|
# | iriOrFunction | RDFLiteral
|
1259
1307
|
# | NumericLiteral | BooleanLiteral
|
1260
1308
|
# | Var
|
1309
|
+
# | EmbTP
|
1261
1310
|
production(:PrimaryExpression) do |input, data, callback|
|
1262
1311
|
if data[:Expression]
|
1263
1312
|
add_prod_datum(:Expression, data[:Expression])
|
@@ -1271,6 +1320,8 @@ module SPARQL::Grammar
|
|
1271
1320
|
add_prod_datum(:Expression, data[:literal])
|
1272
1321
|
elsif data[:Var]
|
1273
1322
|
add_prod_datum(:Expression, data[:Var])
|
1323
|
+
elsif data[:pattern]
|
1324
|
+
add_prod_datum(:Expression, data[:pattern])
|
1274
1325
|
end
|
1275
1326
|
|
1276
1327
|
# Keep track of this for parent UnaryExpression production
|
@@ -1441,6 +1492,43 @@ module SPARQL::Grammar
|
|
1441
1492
|
add_prod_datum(:UnaryExpression, data[:UnaryExpression])
|
1442
1493
|
end
|
1443
1494
|
|
1495
|
+
# [177] AnnotationPattern ::= '{|' PropertyListNotEmpty '|}'
|
1496
|
+
#start_production(:AnnotationPattern) do |input, data, callback|
|
1497
|
+
# data[:TriplesNode] = prod_data[:TriplesNode].first
|
1498
|
+
#end
|
1499
|
+
#production(:AnnotationPattern) do |input, data, callback|
|
1500
|
+
# add_prod_datum(:pattern, data[:pattern])
|
1501
|
+
#end
|
1502
|
+
|
1503
|
+
# [178] AnnotationPatternPath ::= '{|' PropertyListPathNotEmpty '|}'
|
1504
|
+
start_production(:AnnotationPatternPath) do |input, data, callback|
|
1505
|
+
data[:TriplesNode] = input[:TriplesNode]
|
1506
|
+
end
|
1507
|
+
production(:AnnotationPatternPath) do |input, data, callback|
|
1508
|
+
if data[:pattern]
|
1509
|
+
add_prod_datum(:pattern, data[:pattern])
|
1510
|
+
elsif data[:path]
|
1511
|
+
# Replace the subject in the path with the node being annotated.
|
1512
|
+
data[:path].first.operands[0] = data[:TriplesNode]
|
1513
|
+
add_prod_datum(:path, data[:path])
|
1514
|
+
end
|
1515
|
+
end
|
1516
|
+
|
1517
|
+
# [179] EmbTD ::= '<<' DataValueTerm ( iri | 'a' ) DataValueTerm '>>'
|
1518
|
+
production(:EmbTD) do |input, data, callback|
|
1519
|
+
subject, object = data[:DataValueTerm]
|
1520
|
+
predicate = data[:iri]
|
1521
|
+
add_pattern(:EmbTD,
|
1522
|
+
subject: subject,
|
1523
|
+
predicate: predicate,
|
1524
|
+
object: object)
|
1525
|
+
end
|
1526
|
+
|
1527
|
+
# [180] DataValueTerm ::= EmbTD | iri | RDFLiteral | NumericLiteral | BooleanLiteral
|
1528
|
+
production(:DataValueTerm) do |input, data, callback|
|
1529
|
+
add_prod_datum :DataValueTerm, data.values.first
|
1530
|
+
end
|
1531
|
+
|
1444
1532
|
##
|
1445
1533
|
# Initializes a new parser instance.
|
1446
1534
|
#
|
@@ -1458,10 +1546,8 @@ module SPARQL::Grammar
|
|
1458
1546
|
# definitions.
|
1459
1547
|
# @option options [Boolean] :validate (false)
|
1460
1548
|
# whether to validate the parsed statements and values
|
1461
|
-
# @option options [
|
1462
|
-
#
|
1463
|
-
# @option options [Boolean] :debug
|
1464
|
-
# Detailed debug output
|
1549
|
+
# @option options [Logger, #write, #<<] :logger
|
1550
|
+
# Record error/info/debug output
|
1465
1551
|
# @yield [parser] `self`
|
1466
1552
|
# @yieldparam [SPARQL::Grammar::Parser] parser
|
1467
1553
|
# @yieldreturn [void] ignored
|
@@ -1473,10 +1559,6 @@ module SPARQL::Grammar
|
|
1473
1559
|
end
|
1474
1560
|
@input.encode!(Encoding::UTF_8) if @input.respond_to?(:encode!)
|
1475
1561
|
@options = {anon_base: "b0", validate: false}.merge(options)
|
1476
|
-
@options[:debug] ||= case
|
1477
|
-
when options[:progress] then 2
|
1478
|
-
when options[:validate] then 1
|
1479
|
-
end
|
1480
1562
|
|
1481
1563
|
debug("base IRI") {base_uri.inspect}
|
1482
1564
|
debug("validate") {validate?.inspect}
|
@@ -1527,8 +1609,8 @@ module SPARQL::Grammar
|
|
1527
1609
|
# @param [Symbol, #to_s] prod The starting production for the parser.
|
1528
1610
|
# It may be a URI from the grammar, or a symbol representing the local_name portion of the grammar URI.
|
1529
1611
|
# @return [Array]
|
1530
|
-
# @see
|
1531
|
-
# @see
|
1612
|
+
# @see https://www.w3.org/TR/sparql11-query/#sparqlAlgebra
|
1613
|
+
# @see https://axel.deri.ie/sparqltutorial/ESWC2007_SPARQL_Tutorial_unit2b.pdf
|
1532
1614
|
def parse(prod = START)
|
1533
1615
|
ll1_parse(@input,
|
1534
1616
|
prod.to_sym,
|
@@ -1537,23 +1619,7 @@ module SPARQL::Grammar
|
|
1537
1619
|
follow: FOLLOW,
|
1538
1620
|
whitespace: WS,
|
1539
1621
|
**@options
|
1540
|
-
)
|
1541
|
-
case context
|
1542
|
-
when :trace
|
1543
|
-
level, lineno, depth, *args = data
|
1544
|
-
message = args.to_sse
|
1545
|
-
d_str = depth > 100 ? ' ' * 100 + '+' : ' ' * depth
|
1546
|
-
str = "[#{lineno}](#{level})#{d_str}#{message}".chop
|
1547
|
-
case @options[:debug]
|
1548
|
-
when Array
|
1549
|
-
@options[:debug] << str unless level > 2
|
1550
|
-
when TrueClass
|
1551
|
-
$stderr.puts str
|
1552
|
-
when Integer
|
1553
|
-
$stderr.puts(str) if level <= @options[:debug]
|
1554
|
-
end
|
1555
|
-
end
|
1556
|
-
end
|
1622
|
+
)
|
1557
1623
|
|
1558
1624
|
# The last thing on the @prod_data stack is the result
|
1559
1625
|
@result = case
|
@@ -108,8 +108,11 @@ module SPARQL::Grammar
|
|
108
108
|
|TIMEZONE|TO|TZ|UCASE|UNDEF|UNION|URI|USING|UUID|VALUES
|
109
109
|
|WHERE|WITH|YEAR
|
110
110
|
|isBLANK|isIRI|isURI|isLITERAL|isNUMERIC|sameTerm
|
111
|
+
|isTRIPLE|TRIPLE|SUBJECT|PREDICATE|OBJECT
|
111
112
|
|true
|
112
113
|
|false
|
114
|
+
|<<|>>
|
115
|
+
|\{\||\|\}
|
113
116
|
|&&|!=|!|<=|>=|\^\^|\|\||[\(\),.;\[\]\{\}\+\-=<>\?\^\|\*\/a]
|
114
117
|
)xim.freeze
|
115
118
|
|
@@ -131,6 +134,7 @@ module SPARQL::Grammar
|
|
131
134
|
TIMEZONE TO TZ UCASE UNDEF UNION URI USING UUID
|
132
135
|
VALUES WHERE WITH YEAR
|
133
136
|
isBLANK isIRI isURI isLITERAL isNUMERIC sameTerm
|
137
|
+
isTRIPLE TRIPLE SUBJECT PREDICATE OBJECT
|
134
138
|
true false
|
135
139
|
} + [
|
136
140
|
"DELETE DATA",
|
data/lib/sparql/results.rb
CHANGED
@@ -14,28 +14,38 @@ module SPARQL
|
|
14
14
|
##
|
15
15
|
# Generate Solutions as JSON
|
16
16
|
# @return [String]
|
17
|
-
# @see
|
17
|
+
# @see https://www.w3.org/TR/rdf-sparql-json-res/
|
18
18
|
def to_json
|
19
19
|
require 'json' unless defined?(::JSON)
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
{
|
28
|
-
|
29
|
-
|
30
|
-
{n => {type: "typed-literal", datatype: s.datatype.to_s, value: s.to_s }}
|
31
|
-
elsif s.language
|
32
|
-
{n => {type: "literal", "xml:lang" => s.language.to_s, value: s.to_s }}
|
33
|
-
else
|
34
|
-
{n => {type: "literal", value: s.to_s }}
|
35
|
-
end
|
20
|
+
|
21
|
+
format = ->(value) do
|
22
|
+
case value
|
23
|
+
when RDF::URI then {type: "uri", value: value.to_s }
|
24
|
+
when RDF::Node then {type: "bnode", value: value.id }
|
25
|
+
when RDF::Literal
|
26
|
+
if value.datatype?
|
27
|
+
{type: "typed-literal", datatype: value.datatype.to_s, value: value.to_s }
|
28
|
+
elsif value.language?
|
29
|
+
{type: "literal", "xml:lang" => value.language.to_s, value: value.to_s }
|
36
30
|
else
|
37
|
-
{}
|
31
|
+
{type: "literal", value: value.to_s }
|
38
32
|
end
|
33
|
+
when RDF::Statement
|
34
|
+
{
|
35
|
+
type: 'triple',
|
36
|
+
value: {
|
37
|
+
subject: format.call(value.subject),
|
38
|
+
predicate: format.call(value.predicate),
|
39
|
+
object: format.call(value.object)
|
40
|
+
}
|
41
|
+
}
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
bindings = self.map do |solution|
|
46
|
+
variable_names.inject({}) do |memo, n|
|
47
|
+
rep = format.call(solution[n])
|
48
|
+
rep ? memo.merge(n => rep) : memo
|
39
49
|
end
|
40
50
|
end
|
41
51
|
|
@@ -48,12 +58,36 @@ module SPARQL
|
|
48
58
|
##
|
49
59
|
# Generate Solutions as XML
|
50
60
|
# @return [String]
|
51
|
-
# @see
|
61
|
+
# @see https://www.w3.org/TR/rdf-sparql-XMLres/
|
52
62
|
def to_xml
|
53
63
|
require 'builder' unless defined?(::Builder)
|
54
64
|
|
55
65
|
xml = ::Builder::XmlMarkup.new(indent: 2)
|
56
66
|
xml.instruct!
|
67
|
+
|
68
|
+
format = ->(s) do
|
69
|
+
case s
|
70
|
+
when RDF::URI
|
71
|
+
xml.uri(s.to_s)
|
72
|
+
when RDF::Node
|
73
|
+
xml.bnode(s.id)
|
74
|
+
when RDF::Literal
|
75
|
+
if s.datatype?
|
76
|
+
xml.literal(s.to_s, "datatype" => s.datatype.to_s)
|
77
|
+
elsif s.language
|
78
|
+
xml.literal(s.to_s, "xml:lang" => s.language.to_s)
|
79
|
+
else
|
80
|
+
xml.literal(s.to_s)
|
81
|
+
end
|
82
|
+
when RDF::Statement
|
83
|
+
xml.triple do
|
84
|
+
xml.subject {format.call(s.subject)}
|
85
|
+
xml.predicate {format.call(s.predicate)}
|
86
|
+
xml.object {format.call(s.object)}
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
57
91
|
xml.sparql(xmlns: "http://www.w3.org/2005/sparql-results#") do
|
58
92
|
xml.head do
|
59
93
|
variable_names.each do |n|
|
@@ -67,20 +101,7 @@ module SPARQL
|
|
67
101
|
s = solution[n]
|
68
102
|
next unless s
|
69
103
|
xml.binding(name: n) do
|
70
|
-
|
71
|
-
when RDF::URI
|
72
|
-
xml.uri(s.to_s)
|
73
|
-
when RDF::Node
|
74
|
-
xml.bnode(s.id)
|
75
|
-
when RDF::Literal
|
76
|
-
if s.datatype?
|
77
|
-
xml.literal(s.to_s, "datatype" => s.datatype.to_s)
|
78
|
-
elsif s.language
|
79
|
-
xml.literal(s.to_s, "xml:lang" => s.language.to_s)
|
80
|
-
else
|
81
|
-
xml.literal(s.to_s)
|
82
|
-
end
|
83
|
-
end
|
104
|
+
format.call(s)
|
84
105
|
end
|
85
106
|
end
|
86
107
|
end
|
@@ -118,10 +139,9 @@ module SPARQL
|
|
118
139
|
##
|
119
140
|
# Generate Solutions as CSV
|
120
141
|
# @return [String]
|
121
|
-
# @see
|
122
|
-
def to_csv
|
142
|
+
# @see https://www.w3.org/TR/2013/REC-sparql11-results-csv-tsv-20130321/
|
143
|
+
def to_csv(bnode_map: {})
|
123
144
|
require 'csv' unless defined?(::CSV)
|
124
|
-
bnode_map = {}
|
125
145
|
bnode_gen = "_:a"
|
126
146
|
CSV.generate(row_sep: "\r\n") do |csv|
|
127
147
|
csv << variable_names.to_a
|
@@ -134,8 +154,12 @@ module SPARQL
|
|
134
154
|
bnode_gen = bnode_gen.succ
|
135
155
|
this
|
136
156
|
end
|
157
|
+
when RDF::Statement
|
158
|
+
RDF::Query::Solutions(
|
159
|
+
RDF::Query::Solution.new(subject: term.subject, predicate: term.predicate, object: term.object)
|
160
|
+
).to_csv(bnode_map: bnode_map).split.last.strip
|
137
161
|
else
|
138
|
-
solution[n].to_s
|
162
|
+
solution[n].to_s.strip
|
139
163
|
end
|
140
164
|
end
|
141
165
|
end
|
@@ -144,11 +168,9 @@ module SPARQL
|
|
144
168
|
##
|
145
169
|
# Generate Solutions as TSV
|
146
170
|
# @return [String]
|
147
|
-
# @see
|
171
|
+
# @see https://www.w3.org/TR/2013/REC-sparql11-results-csv-tsv-20130321/
|
148
172
|
def to_tsv
|
149
173
|
require 'csv' unless defined?(::CSV)
|
150
|
-
bnode_map = {}
|
151
|
-
bnode_gen = "_:a"
|
152
174
|
results = [
|
153
175
|
variable_names.map {|v| "?#{v}"}.join("\t")
|
154
176
|
] + self.map do |solution|
|
@@ -156,10 +178,15 @@ module SPARQL
|
|
156
178
|
case term = solution[n]
|
157
179
|
when RDF::Literal::Integer, RDF::Literal::Decimal, RDF::Literal::Double
|
158
180
|
term.canonicalize.to_s
|
181
|
+
when RDF::Statement
|
182
|
+
emb_stmt = RDF::Query::Solutions(
|
183
|
+
RDF::Query::Solution.new(subject: term.subject, predicate: term.predicate, object: term.object)
|
184
|
+
).to_tsv.split("\n").last.strip
|
185
|
+
emb_stmt.gsub(/[\t\n\r]/, "\t" => '\t', "\n" => '\n', "\r" => '\r')
|
159
186
|
when nil
|
160
187
|
""
|
161
188
|
else
|
162
|
-
RDF::NTriples.serialize(term)
|
189
|
+
RDF::NTriples.serialize(term).strip.gsub(/[\t\n\r]/, "\t" => '\t', "\n" => '\n', "\r" => '\r')
|
163
190
|
end
|
164
191
|
end.join("\t")
|
165
192
|
end
|
@@ -226,7 +253,7 @@ module SPARQL
|
|
226
253
|
when RDF::Queryable
|
227
254
|
begin
|
228
255
|
require 'linkeddata'
|
229
|
-
rescue LoadError
|
256
|
+
rescue LoadError
|
230
257
|
require 'rdf/ntriples'
|
231
258
|
end
|
232
259
|
fmt = RDF::Format.for(format ? format.to_sym : {content_type: content_type})
|
@@ -280,7 +307,7 @@ module SPARQL
|
|
280
307
|
# @param [Array<String>] available
|
281
308
|
# @return [String]
|
282
309
|
#
|
283
|
-
# @see
|
310
|
+
# @see https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1
|
284
311
|
def first_content_type(acceptable, available)
|
285
312
|
return acceptable.first if available.empty?
|
286
313
|
available.flatten!
|