rdf-turtle 1.0.0 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/History +7 -0
- data/{README.markdown → README.md} +11 -26
- data/VERSION +1 -1
- data/lib/rdf/turtle.rb +1 -2
- data/lib/rdf/turtle/meta.rb +1027 -1175
- data/lib/rdf/turtle/reader.rb +92 -79
- data/lib/rdf/turtle/terminals.rb +31 -31
- data/lib/rdf/turtle/writer.rb +2 -2
- metadata +127 -161
- data/lib/ebnf.rb +0 -638
- data/lib/rdf/ll1/lexer.rb +0 -475
- data/lib/rdf/ll1/parser.rb +0 -541
- data/lib/rdf/ll1/scanner.rb +0 -101
data/lib/rdf/turtle/reader.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'rdf/turtle/meta'
|
2
|
-
require '
|
2
|
+
require 'ebnf/ll1/parser'
|
3
3
|
|
4
4
|
module RDF::Turtle
|
5
5
|
##
|
@@ -7,46 +7,46 @@ module RDF::Turtle
|
|
7
7
|
class Reader < RDF::Reader
|
8
8
|
format Format
|
9
9
|
include RDF::Turtle::Meta
|
10
|
-
include
|
10
|
+
include EBNF::LL1::Parser
|
11
11
|
include RDF::Turtle::Terminals
|
12
12
|
|
13
13
|
# Terminals passed to lexer. Order matters!
|
14
|
-
terminal(:ANON, ANON) do |
|
15
|
-
input[:resource] =
|
14
|
+
terminal(:ANON, ANON) do |prod, token, input|
|
15
|
+
input[:resource] = self.bnode
|
16
16
|
end
|
17
|
-
terminal(:BLANK_NODE_LABEL, BLANK_NODE_LABEL) do |
|
18
|
-
input[:resource] =
|
17
|
+
terminal(:BLANK_NODE_LABEL, BLANK_NODE_LABEL) do |prod, token, input|
|
18
|
+
input[:resource] = self.bnode(token.value[2..-1])
|
19
19
|
end
|
20
|
-
terminal(:IRIREF, IRIREF, :unescape => true) do |
|
20
|
+
terminal(:IRIREF, IRIREF, :unescape => true) do |prod, token, input|
|
21
21
|
begin
|
22
|
-
input[:resource] =
|
22
|
+
input[:resource] = process_iri(token.value[1..-2])
|
23
23
|
rescue ArgumentError => e
|
24
24
|
raise RDF::ReaderError, e.message
|
25
25
|
end
|
26
26
|
end
|
27
|
-
terminal(:DOUBLE, DOUBLE) do |
|
27
|
+
terminal(:DOUBLE, DOUBLE) do |prod, token, input|
|
28
28
|
# Note that a Turtle Double may begin with a '.[eE]', so tack on a leading
|
29
29
|
# zero if necessary
|
30
30
|
value = token.value.sub(/\.([eE])/, '.0\1')
|
31
|
-
input[:resource] =
|
31
|
+
input[:resource] = literal(value, :datatype => RDF::XSD.double)
|
32
32
|
end
|
33
|
-
terminal(:DECIMAL, DECIMAL) do |
|
33
|
+
terminal(:DECIMAL, DECIMAL) do |prod, token, input|
|
34
34
|
# Note that a Turtle Decimal may begin with a '.', so tack on a leading
|
35
35
|
# zero if necessary
|
36
36
|
value = token.value
|
37
37
|
value = "0#{token.value}" if token.value[0,1] == "."
|
38
|
-
input[:resource] =
|
38
|
+
input[:resource] = literal(value, :datatype => RDF::XSD.decimal)
|
39
39
|
end
|
40
|
-
terminal(:INTEGER, INTEGER) do |
|
41
|
-
input[:resource] =
|
40
|
+
terminal(:INTEGER, INTEGER) do |prod, token, input|
|
41
|
+
input[:resource] = literal(token.value, :datatype => RDF::XSD.integer)
|
42
42
|
end
|
43
43
|
# Spec confusion: spec says : "Literals , prefixed names and IRIs may also contain escape sequences"
|
44
|
-
terminal(:PNAME_LN, PNAME_LN, :unescape => true) do |
|
44
|
+
terminal(:PNAME_LN, PNAME_LN, :unescape => true) do |prod, token, input|
|
45
45
|
prefix, suffix = token.value.split(":", 2)
|
46
|
-
input[:resource] =
|
46
|
+
input[:resource] = pname(prefix, suffix)
|
47
47
|
end
|
48
48
|
# Spec confusion: spec says : "Literals , prefixed names and IRIs may also contain escape sequences"
|
49
|
-
terminal(:PNAME_NS, PNAME_NS) do |
|
49
|
+
terminal(:PNAME_NS, PNAME_NS) do |prod, token, input|
|
50
50
|
prefix = token.value[0..-2]
|
51
51
|
|
52
52
|
# Two contexts, one when prefix is being defined, the other when being used
|
@@ -54,24 +54,24 @@ module RDF::Turtle
|
|
54
54
|
when :prefixID, :sparqlPrefix
|
55
55
|
input[:prefix] = prefix
|
56
56
|
else
|
57
|
-
input[:resource] =
|
57
|
+
input[:resource] = pname(prefix, '')
|
58
58
|
end
|
59
59
|
end
|
60
|
-
terminal(:STRING_LITERAL_LONG_SINGLE_QUOTE, STRING_LITERAL_LONG_SINGLE_QUOTE, :unescape => true) do |
|
60
|
+
terminal(:STRING_LITERAL_LONG_SINGLE_QUOTE, STRING_LITERAL_LONG_SINGLE_QUOTE, :unescape => true) do |prod, token, input|
|
61
61
|
input[:string_value] = token.value[3..-4]
|
62
62
|
end
|
63
|
-
terminal(:STRING_LITERAL_LONG_QUOTE, STRING_LITERAL_LONG_QUOTE, :unescape => true) do |
|
63
|
+
terminal(:STRING_LITERAL_LONG_QUOTE, STRING_LITERAL_LONG_QUOTE, :unescape => true) do |prod, token, input|
|
64
64
|
input[:string_value] = token.value[3..-4]
|
65
65
|
end
|
66
|
-
terminal(:STRING_LITERAL_QUOTE, STRING_LITERAL_QUOTE, :unescape => true) do |
|
66
|
+
terminal(:STRING_LITERAL_QUOTE, STRING_LITERAL_QUOTE, :unescape => true) do |prod, token, input|
|
67
67
|
input[:string_value] = token.value[1..-2]
|
68
68
|
end
|
69
|
-
terminal(:STRING_LITERAL_SINGLE_QUOTE, STRING_LITERAL_SINGLE_QUOTE, :unescape => true) do |
|
69
|
+
terminal(:STRING_LITERAL_SINGLE_QUOTE, STRING_LITERAL_SINGLE_QUOTE, :unescape => true) do |prod, token, input|
|
70
70
|
input[:string_value] = token.value[1..-2]
|
71
71
|
end
|
72
72
|
|
73
73
|
# String terminals
|
74
|
-
terminal(nil, %r([\(\),.;\[\]a]|\^\^|@base|@prefix|true|false)) do |
|
74
|
+
terminal(nil, %r([\(\),.;\[\]a]|\^\^|@base|@prefix|true|false)) do |prod, token, input|
|
75
75
|
case token.value
|
76
76
|
when 'a' then input[:resource] = RDF.type
|
77
77
|
when 'true', 'false' then input[:resource] = RDF::Literal::Boolean.new(token.value)
|
@@ -80,74 +80,77 @@ module RDF::Turtle
|
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
83
|
-
terminal(:LANGTAG, LANGTAG) do |
|
83
|
+
terminal(:LANGTAG, LANGTAG) do |prod, token, input|
|
84
84
|
input[:lang] = token.value[1..-1]
|
85
85
|
end
|
86
86
|
|
87
|
-
terminal(:SPARQL_PREFIX, SPARQL_PREFIX) do |
|
87
|
+
terminal(:SPARQL_PREFIX, SPARQL_PREFIX) do |prod, token, input|
|
88
88
|
input[:string_value] = token.value.downcase
|
89
89
|
end
|
90
|
-
terminal(:SPARQL_BASE, SPARQL_BASE) do |
|
90
|
+
terminal(:SPARQL_BASE, SPARQL_BASE) do |prod, token, input|
|
91
91
|
input[:string_value] = token.value.downcase
|
92
92
|
end
|
93
93
|
|
94
94
|
# Productions
|
95
95
|
|
96
96
|
# [4] prefixID defines a prefix mapping
|
97
|
-
production(:prefixID) do |
|
98
|
-
next unless phase == :finish
|
97
|
+
production(:prefixID) do |input, current, callback|
|
99
98
|
prefix = current[:prefix]
|
100
99
|
iri = current[:resource]
|
101
100
|
callback.call(:trace, "prefixID", lambda {"Defined prefix #{prefix.inspect} mapping to #{iri.inspect}"})
|
102
|
-
|
101
|
+
prefix(prefix, iri)
|
103
102
|
end
|
104
103
|
|
105
104
|
# [5] base set base_uri
|
106
|
-
production(:base) do |
|
107
|
-
next unless phase == :finish
|
105
|
+
production(:base) do |input, current, callback|
|
108
106
|
iri = current[:resource]
|
109
107
|
callback.call(:trace, "base", lambda {"Defined base as #{iri}"})
|
110
|
-
|
108
|
+
options[:base_uri] = iri
|
111
109
|
end
|
112
110
|
|
113
111
|
# [28s] sparqlPrefix ::= [Pp][Rr][Ee][Ff][Ii][Xx] PNAME_NS IRIREF
|
114
|
-
production(:sparqlPrefix) do |
|
115
|
-
next unless phase == :finish
|
112
|
+
production(:sparqlPrefix) do |input, current, callback|
|
116
113
|
prefix = current[:prefix]
|
117
114
|
iri = current[:resource]
|
118
115
|
callback.call(:trace, "sparqlPrefix", lambda {"Defined prefix #{prefix.inspect} mapping to #{iri.inspect}"})
|
119
|
-
|
116
|
+
prefix(prefix, iri)
|
120
117
|
end
|
121
118
|
|
122
119
|
# [29s] sparqlBase ::= [Bb][Aa][Ss][Ee] IRIREF
|
123
|
-
production(:sparqlBase) do |
|
124
|
-
next unless phase == :finish
|
120
|
+
production(:sparqlBase) do |input, current, callback|
|
125
121
|
iri = current[:resource]
|
126
122
|
callback.call(:trace, ":sparqlBase", lambda {"Defined base as #{iri}"})
|
127
|
-
|
123
|
+
options[:base_uri] = iri
|
128
124
|
end
|
129
125
|
|
130
126
|
# [6] triples
|
131
|
-
|
127
|
+
start_production(:triples) do |input, current, callback|
|
128
|
+
# Note production as triples for blankNodePropertyList
|
129
|
+
# to set :subject instead of :resource
|
130
|
+
current[:triples] = true
|
131
|
+
end
|
132
|
+
production(:triples) do |input, current, callback|
|
132
133
|
# Note production as triples for blankNodePropertyList
|
133
134
|
# to set :subject instead of :resource
|
134
135
|
current[:triples] = true
|
135
136
|
end
|
136
137
|
|
137
138
|
# [9] verb ::= predicate | "a"
|
138
|
-
production(:verb) do |
|
139
|
-
input[:predicate] = current[:resource]
|
139
|
+
production(:verb) do |input, current, callback|
|
140
|
+
input[:predicate] = current[:resource]
|
140
141
|
end
|
141
142
|
|
142
143
|
# [10] subject ::= IRIref | BlankNode | collection
|
143
|
-
|
144
|
-
current[:triples] = nil
|
145
|
-
|
144
|
+
start_production(:subject) do |input, current, callback|
|
145
|
+
current[:triples] = nil
|
146
|
+
end
|
147
|
+
|
148
|
+
production(:subject) do |input, current, callback|
|
149
|
+
input[:subject] = current[:resource]
|
146
150
|
end
|
147
151
|
|
148
152
|
# [12] object ::= iri | BlankNode | collection | blankNodePropertyList | literal
|
149
|
-
production(:object) do |
|
150
|
-
next unless phase == :finish
|
153
|
+
production(:object) do |input, current, callback|
|
151
154
|
if input[:object_list]
|
152
155
|
# Part of an rdf:List collection
|
153
156
|
input[:object_list] << current[:resource]
|
@@ -158,10 +161,12 @@ module RDF::Turtle
|
|
158
161
|
end
|
159
162
|
|
160
163
|
# [14] blankNodePropertyList ::= "[" predicateObjectList "]"
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
164
|
+
start_production(:blankNodePropertyList) do |input, current, callback|
|
165
|
+
current[:subject] = self.bnode
|
166
|
+
end
|
167
|
+
|
168
|
+
production(:blankNodePropertyList) do |input, current, callback|
|
169
|
+
if input[:triples]
|
165
170
|
input[:subject] = current[:subject]
|
166
171
|
else
|
167
172
|
input[:resource] = current[:subject]
|
@@ -169,35 +174,35 @@ module RDF::Turtle
|
|
169
174
|
end
|
170
175
|
|
171
176
|
# [15] collection ::= "(" object* ")"
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
# Return bnode as resource
|
190
|
-
input[:resource] = bnode
|
177
|
+
start_production(:collection) do |input, current, callback|
|
178
|
+
# Tells the object production to collect and not generate statements
|
179
|
+
current[:object_list] = []
|
180
|
+
end
|
181
|
+
|
182
|
+
production(:collection) do |input, current, callback|
|
183
|
+
# Create an RDF list
|
184
|
+
bnode = self.bnode
|
185
|
+
objects = current[:object_list]
|
186
|
+
list = RDF::List.new(bnode, nil, objects)
|
187
|
+
list.each_statement do |statement|
|
188
|
+
# Spec Confusion, referenced section "Collection" is missing from the spec.
|
189
|
+
# Anicdodal evidence indicates that some expect each node to be of type rdf:list,
|
190
|
+
# but existing Notation3 and Turtle tests (http://www.w3.org/2001/sw/DataAccess/df1/tests/manifest.ttl) do not.
|
191
|
+
next if statement.predicate == RDF.type && statement.object == RDF.List
|
192
|
+
callback.call(:statement, "collection", statement.subject, statement.predicate, statement.object)
|
191
193
|
end
|
194
|
+
bnode = RDF.nil if list.empty?
|
195
|
+
|
196
|
+
# Return bnode as resource
|
197
|
+
input[:resource] = bnode
|
192
198
|
end
|
193
199
|
|
194
200
|
# [16] RDFLiteral ::= String ( LanguageTag | ( "^^" IRIref ) )?
|
195
|
-
production(:RDFLiteral) do |
|
196
|
-
next unless phase == :finish
|
201
|
+
production(:RDFLiteral) do |input, current, callback|
|
197
202
|
opts = {}
|
198
203
|
opts[:datatype] = current[:resource] if current[:resource]
|
199
204
|
opts[:language] = current[:lang] if current[:lang]
|
200
|
-
input[:resource] =
|
205
|
+
input[:resource] = literal(current[:string_value], opts)
|
201
206
|
end
|
202
207
|
|
203
208
|
##
|
@@ -229,7 +234,11 @@ module RDF::Turtle
|
|
229
234
|
# @return [RDF::Turtle::Reader]
|
230
235
|
def initialize(input = nil, options = {}, &block)
|
231
236
|
super do
|
232
|
-
@options = {
|
237
|
+
@options = {
|
238
|
+
:anon_base => "b0",
|
239
|
+
:validate => false,
|
240
|
+
:debug => RDF::Turtle.debug?,
|
241
|
+
}.merge(options)
|
233
242
|
@options = {:prefixes => {nil => ""}}.merge(@options) unless @options[:validate]
|
234
243
|
|
235
244
|
debug("base IRI") {base_uri.inspect}
|
@@ -272,7 +281,7 @@ module RDF::Turtle
|
|
272
281
|
debug(loc, *(data.dup << {:level => 0}))
|
273
282
|
end
|
274
283
|
end
|
275
|
-
rescue ArgumentError,
|
284
|
+
rescue ArgumentError, EBNF::LL1::Parser::Error => e
|
276
285
|
progress("Parsing completed with errors:\n\t#{e.message}")
|
277
286
|
raise RDF::ReaderError, e.message if validate?
|
278
287
|
end
|
@@ -298,8 +307,8 @@ module RDF::Turtle
|
|
298
307
|
# @return [RDF::Statement] Added statement
|
299
308
|
# @raise [RDF::ReaderError] Checks parameter types and raises if they are incorrect if parsing mode is _validate_.
|
300
309
|
def add_statement(node, statement)
|
301
|
-
error(node, "Statement is invalid: #{statement.inspect}") unless statement.valid?
|
302
|
-
progress(node) {"generate statement: #{statement}"}
|
310
|
+
error(node, "Statement is invalid: #{statement.inspect.inspect}") unless statement.valid?
|
311
|
+
progress(node) {"generate statement: #{statement.to_ntriples}"}
|
303
312
|
@callback.call(statement)
|
304
313
|
end
|
305
314
|
|
@@ -376,7 +385,7 @@ module RDF::Turtle
|
|
376
385
|
#
|
377
386
|
# @yieldreturn [String] added to message
|
378
387
|
def debug(*args)
|
379
|
-
return unless @options[:debug]
|
388
|
+
return unless @options[:debug]
|
380
389
|
options = args.last.is_a?(Hash) ? args.pop : {}
|
381
390
|
debug_level = options.fetch(:level, 1)
|
382
391
|
return unless debug_level <= DEBUG_LEVEL
|
@@ -387,8 +396,12 @@ module RDF::Turtle
|
|
387
396
|
args << yield if block_given?
|
388
397
|
message = "#{args.join(': ')}"
|
389
398
|
str = "[#{@lineno}]#{' ' * depth}#{message}"
|
390
|
-
|
391
|
-
|
399
|
+
case @options[:debug]
|
400
|
+
when Array
|
401
|
+
@options[:debug] << str
|
402
|
+
when TrueClass
|
403
|
+
$stderr.puts str
|
404
|
+
end
|
392
405
|
end
|
393
406
|
end # class Reader
|
394
407
|
end # module RDF::Turtle
|
data/lib/rdf/turtle/terminals.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'ebnf/ll1/lexer'
|
2
2
|
|
3
3
|
module RDF::Turtle
|
4
4
|
module Terminals
|
@@ -13,8 +13,8 @@ module RDF::Turtle
|
|
13
13
|
[\\u2070-\\u218F]|[\\u2C00-\\u2FEF]|[\\u3001-\\uD7FF]|
|
14
14
|
[\\uF900-\\uFDCF]|[\\uFDF0-\\uFFFD]|[\\u{10000}-\\u{EFFFF}]
|
15
15
|
EOS
|
16
|
-
U_CHARS2 = Regexp.compile("\\u00B7|[\\u0300-\\u036F]|[\\u203F-\\u2040]")
|
17
|
-
IRI_RANGE = Regexp.compile("[[^<>\"{}|^`\\\\]&&[^\\x00-\\x20]]")
|
16
|
+
U_CHARS2 = Regexp.compile("\\u00B7|[\\u0300-\\u036F]|[\\u203F-\\u2040]").freeze
|
17
|
+
IRI_RANGE = Regexp.compile("[[^<>\"{}|^`\\\\]&&[^\\x00-\\x20]]").freeze
|
18
18
|
else
|
19
19
|
##
|
20
20
|
# UTF-8 regular expressions for Ruby 1.8.x.
|
@@ -60,62 +60,62 @@ module RDF::Turtle
|
|
60
60
|
end
|
61
61
|
|
62
62
|
# 26
|
63
|
-
UCHAR =
|
63
|
+
UCHAR = EBNF::LL1::Lexer::UCHAR
|
64
64
|
# 170s
|
65
|
-
PERCENT = /%[0-9A-Fa-f]{2}
|
65
|
+
PERCENT = /%[0-9A-Fa-f]{2}/.freeze
|
66
66
|
# 172s
|
67
|
-
PN_LOCAL_ESC = /\\[_~\.\-\!$\&'\(\)\*\+,;=:\/\?\#@%]
|
67
|
+
PN_LOCAL_ESC = /\\[_~\.\-\!$\&'\(\)\*\+,;=:\/\?\#@%]/.freeze
|
68
68
|
# 169s
|
69
|
-
PLX = /#{PERCENT}|#{PN_LOCAL_ESC}
|
69
|
+
PLX = /#{PERCENT}|#{PN_LOCAL_ESC}/.freeze.freeze
|
70
70
|
# 163s
|
71
|
-
PN_CHARS_BASE = /[A-Z]|[a-z]|#{U_CHARS1}
|
71
|
+
PN_CHARS_BASE = /[A-Z]|[a-z]|#{U_CHARS1}/.freeze
|
72
72
|
# 164s
|
73
|
-
PN_CHARS_U = /_|#{PN_CHARS_BASE}
|
73
|
+
PN_CHARS_U = /_|#{PN_CHARS_BASE}/.freeze
|
74
74
|
# 166s
|
75
|
-
PN_CHARS = /-|[0-9]|#{PN_CHARS_U}|#{U_CHARS2}
|
76
|
-
PN_LOCAL_BODY = /(?:(?:\.|:|#{PN_CHARS}|#{PLX})*(?:#{PN_CHARS}|:|#{PLX}))
|
77
|
-
PN_CHARS_BODY = /(?:(?:\.|#{PN_CHARS})*#{PN_CHARS})
|
75
|
+
PN_CHARS = /-|[0-9]|#{PN_CHARS_U}|#{U_CHARS2}/.freeze
|
76
|
+
PN_LOCAL_BODY = /(?:(?:\.|:|#{PN_CHARS}|#{PLX})*(?:#{PN_CHARS}|:|#{PLX}))?/.freeze
|
77
|
+
PN_CHARS_BODY = /(?:(?:\.|#{PN_CHARS})*#{PN_CHARS})?/.freeze
|
78
78
|
# 167s
|
79
|
-
PN_PREFIX = /#{PN_CHARS_BASE}#{PN_CHARS_BODY}
|
80
|
-
#
|
81
|
-
PN_LOCAL = /(?:[0-9]|:|#{PN_CHARS_U}|#{PLX})#{PN_LOCAL_BODY}
|
79
|
+
PN_PREFIX = /#{PN_CHARS_BASE}#{PN_CHARS_BODY}/.freeze
|
80
|
+
# 168s
|
81
|
+
PN_LOCAL = /(?:[0-9]|:|#{PN_CHARS_U}|#{PLX})#{PN_LOCAL_BODY}/.freeze
|
82
82
|
# 154s
|
83
83
|
EXPONENT = /[eE][+-]?[0-9]+/
|
84
84
|
# 159s
|
85
85
|
ECHAR = /\\[tbnrf\\"']/
|
86
86
|
# 18
|
87
|
-
IRIREF = /<(?:#{IRI_RANGE}|#{UCHAR})
|
87
|
+
IRIREF = /<(?:#{IRI_RANGE}|#{UCHAR})*>/.freeze
|
88
88
|
# 139s
|
89
|
-
PNAME_NS = /#{PN_PREFIX}
|
89
|
+
PNAME_NS = /#{PN_PREFIX}?:/.freeze
|
90
90
|
# 140s
|
91
|
-
PNAME_LN = /#{PNAME_NS}#{PN_LOCAL}
|
91
|
+
PNAME_LN = /#{PNAME_NS}#{PN_LOCAL}/.freeze
|
92
92
|
# 141s
|
93
|
-
BLANK_NODE_LABEL = /_:(?:[0-9]|#{PN_CHARS_U})(
|
93
|
+
BLANK_NODE_LABEL = /_:(?:[0-9]|#{PN_CHARS_U})(?:(?:#{PN_CHARS}|\.)*#{PN_CHARS})?/.freeze
|
94
94
|
# 144s
|
95
|
-
LANGTAG = /@[a-zA-Z]+(?:-[a-zA-Z0-9]+)
|
95
|
+
LANGTAG = /@[a-zA-Z]+(?:-[a-zA-Z0-9]+)*/.freeze
|
96
96
|
# 19
|
97
|
-
INTEGER = /[+-]?[0-9]
|
97
|
+
INTEGER = /[+-]?[0-9]+/.freeze
|
98
98
|
# 20
|
99
|
-
DECIMAL = /[+-]?(?:[0-9]*\.[0-9]+)
|
99
|
+
DECIMAL = /[+-]?(?:[0-9]*\.[0-9]+)/.freeze
|
100
100
|
# 21
|
101
|
-
DOUBLE = /[+-]?(?:[0-9]+\.[0-9]*#{EXPONENT}|\.?[0-9]+#{EXPONENT})
|
101
|
+
DOUBLE = /[+-]?(?:[0-9]+\.[0-9]*#{EXPONENT}|\.?[0-9]+#{EXPONENT})/.freeze
|
102
102
|
# 22
|
103
|
-
STRING_LITERAL_QUOTE = /'(?:[^\'\\\n\r]|#{ECHAR}|#{UCHAR})*'
|
103
|
+
STRING_LITERAL_QUOTE = /'(?:[^\'\\\n\r]|#{ECHAR}|#{UCHAR})*'/.freeze
|
104
104
|
# 23
|
105
|
-
STRING_LITERAL_SINGLE_QUOTE = /"(?:[^\"\\\n\r]|#{ECHAR}|#{UCHAR})*"
|
105
|
+
STRING_LITERAL_SINGLE_QUOTE = /"(?:[^\"\\\n\r]|#{ECHAR}|#{UCHAR})*"/.freeze.freeze
|
106
106
|
# 24
|
107
|
-
STRING_LITERAL_LONG_SINGLE_QUOTE = /'''(?:(?:'|'')?(?:[^'\\]|#{ECHAR}|#{UCHAR}))*'''/m
|
107
|
+
STRING_LITERAL_LONG_SINGLE_QUOTE = /'''(?:(?:'|'')?(?:[^'\\]|#{ECHAR}|#{UCHAR}))*'''/m.freeze
|
108
108
|
# 25
|
109
|
-
STRING_LITERAL_LONG_QUOTE = /"""(?:(?:"|"")?(?:[^"\\]|#{ECHAR}|#{UCHAR}))*"""/m
|
109
|
+
STRING_LITERAL_LONG_QUOTE = /"""(?:(?:"|"")?(?:[^"\\]|#{ECHAR}|#{UCHAR}))*"""/m.freeze
|
110
110
|
|
111
111
|
# 161s
|
112
|
-
WS = / |\t|\r|\n
|
112
|
+
WS = / |\t|\r|\n /.freeze
|
113
113
|
# 162s
|
114
|
-
ANON = /\[#{WS}*\]/
|
114
|
+
ANON = /\[#{WS}*\]/m.freeze
|
115
115
|
# 28t
|
116
|
-
SPARQL_PREFIX = /prefix/i
|
116
|
+
SPARQL_PREFIX = /prefix/i.freeze
|
117
117
|
# 29t
|
118
|
-
SPARQL_BASE = /base/i
|
118
|
+
SPARQL_BASE = /base/i.freeze
|
119
119
|
|
120
120
|
end
|
121
121
|
end
|
data/lib/rdf/turtle/writer.rb
CHANGED
@@ -163,7 +163,7 @@ module RDF::Turtle
|
|
163
163
|
pname = case
|
164
164
|
when @uri_to_pname.has_key?(uri)
|
165
165
|
return @uri_to_pname[uri]
|
166
|
-
when u = @uri_to_prefix.keys.detect {|u| uri.index(u.to_s) == 0}
|
166
|
+
when u = @uri_to_prefix.keys.sort_by {|u| u.length}.reverse.detect {|u| uri.index(u.to_s) == 0}
|
167
167
|
# Use a defined prefix
|
168
168
|
prefix = @uri_to_prefix[u]
|
169
169
|
unless u.to_s.empty?
|
@@ -343,7 +343,7 @@ module RDF::Turtle
|
|
343
343
|
references = ref_count(statement.object) + 1
|
344
344
|
@references[statement.object] = references
|
345
345
|
@subjects[statement.subject] = true
|
346
|
-
|
346
|
+
|
347
347
|
# Pre-fetch pnames, to fill prefixes
|
348
348
|
get_pname(statement.subject)
|
349
349
|
get_pname(statement.predicate)
|