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.
@@ -1,5 +1,5 @@
1
1
  require 'rdf/turtle/meta'
2
- require 'rdf/ll1/parser'
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 RDF::LL1::Parser
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 |reader, prod, token, input|
15
- input[:resource] = reader.bnode
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 |reader, prod, token, input|
18
- input[:resource] = reader.bnode(token.value[2..-1])
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 |reader, prod, token, input|
20
+ terminal(:IRIREF, IRIREF, :unescape => true) do |prod, token, input|
21
21
  begin
22
- input[:resource] = reader.process_iri(token.value[1..-2])
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 |reader, prod, token, input|
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] = reader.literal(value, :datatype => RDF::XSD.double)
31
+ input[:resource] = literal(value, :datatype => RDF::XSD.double)
32
32
  end
33
- terminal(:DECIMAL, DECIMAL) do |reader, prod, token, input|
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] = reader.literal(value, :datatype => RDF::XSD.decimal)
38
+ input[:resource] = literal(value, :datatype => RDF::XSD.decimal)
39
39
  end
40
- terminal(:INTEGER, INTEGER) do |reader, prod, token, input|
41
- input[:resource] = reader.literal(token.value, :datatype => RDF::XSD.integer)
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 |reader, prod, token, input|
44
+ terminal(:PNAME_LN, PNAME_LN, :unescape => true) do |prod, token, input|
45
45
  prefix, suffix = token.value.split(":", 2)
46
- input[:resource] = reader.pname(prefix, suffix)
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 |reader, prod, token, input|
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] = reader.pname(prefix, '')
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 |reader, prod, token, input|
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 |reader, prod, token, input|
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 |reader, prod, token, input|
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 |reader, prod, token, input|
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 |reader, prod, token, input|
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 |reader, prod, token, input|
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 |reader, prod, token, input|
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 |reader, prod, token, input|
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 |reader, phase, input, current, callback|
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
- reader.prefix(prefix, iri)
101
+ prefix(prefix, iri)
103
102
  end
104
103
 
105
104
  # [5] base set base_uri
106
- production(:base) do |reader, phase, input, current, callback|
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
- reader.options[:base_uri] = iri
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 |reader, phase, input, current, callback|
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
- reader.prefix(prefix, iri)
116
+ prefix(prefix, iri)
120
117
  end
121
118
 
122
119
  # [29s] sparqlBase ::= [Bb][Aa][Ss][Ee] IRIREF
123
- production(:sparqlBase) do |reader, phase, input, current, callback|
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
- reader.options[:base_uri] = iri
123
+ options[:base_uri] = iri
128
124
  end
129
125
 
130
126
  # [6] triples
131
- production(:triples) do |reader, phase, input, current, callback|
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 |reader, phase, input, current, callback|
139
- input[:predicate] = current[:resource] if phase == :finish
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
- production(:subject) do |reader, phase, input, current, callback|
144
- current[:triples] = nil if phase == :start
145
- input[:subject] = current[:resource] if phase == :finish
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 |reader, phase, input, current, callback|
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
- production(:blankNodePropertyList) do |reader, phase, input, current, callback|
162
- if phase == :start
163
- current[:subject] = reader.bnode
164
- elsif input[:triples]
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
- production(:collection) do |reader, phase, input, current, callback|
173
- if phase == :start
174
- current[:object_list] = [] # Tells the object production to collect and not generate statements
175
- else
176
- # Create an RDF list
177
- bnode = reader.bnode
178
- objects = current[:object_list]
179
- list = RDF::List.new(bnode, nil, objects)
180
- list.each_statement do |statement|
181
- # Spec Confusion, referenced section "Collection" is missing from the spec.
182
- # Anicdodal evidence indicates that some expect each node to be of type rdf:list,
183
- # but existing Notation3 and Turtle tests (http://www.w3.org/2001/sw/DataAccess/df1/tests/manifest.ttl) do not.
184
- next if statement.predicate == RDF.type && statement.object == RDF.List
185
- callback.call(:statement, "collection", statement.subject, statement.predicate, statement.object)
186
- end
187
- bnode = RDF.nil if list.empty?
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 |reader, phase, input, current, callback|
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] = reader.literal(current[:string_value], opts)
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 = {:anon_base => "b0", :validate => false}.merge(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, RDF::LL1::Parser::Error => e
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] || RDF::Turtle.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
- @options[:debug] << str if @options[:debug].is_a?(Array)
391
- $stderr.puts(str) if RDF::Turtle.debug?
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
@@ -1,4 +1,4 @@
1
- require 'rdf/ll1/lexer'
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 = RDF::LL1::Lexer::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
- # 100s
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})(#{PN_CHARS}|\.)*/
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
@@ -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)