Class: RDF::Turtle::Reader

Inherits:
Reader show all
Includes:
EBNF::LL1::Parser, Terminals, Util::Logger
Defined in:
vendor/bundler/ruby/2.7.0/bundler/gems/rdf-turtle-574b3b7c8c08/lib/rdf/turtle/reader.rb

Overview

A parser for the Turtle 2

Direct Known Subclasses

RDF::TriG::Reader

Defined Under Namespace

Classes: Recovery, SyntaxError

Constant Summary

Constants included from Util::Logger

Util::Logger::IOWrapper

Constants included from Terminals

Terminals::ANON, Terminals::BASE, Terminals::BLANK_NODE_LABEL, Terminals::DECIMAL, Terminals::DOUBLE, Terminals::ECHAR, Terminals::EXPONENT, Terminals::INTEGER, Terminals::IRIREF, Terminals::IRI_RANGE, Terminals::LANGTAG, Terminals::PERCENT, Terminals::PLX, Terminals::PNAME_LN, Terminals::PNAME_NS, Terminals::PN_CHARS, Terminals::PN_CHARS_BASE, Terminals::PN_CHARS_BODY, Terminals::PN_CHARS_U, Terminals::PN_LOCAL, Terminals::PN_LOCAL_BODY, Terminals::PN_LOCAL_ESC, Terminals::PN_PREFIX, Terminals::PREFIX, Terminals::STRING_LITERAL_LONG_QUOTE, Terminals::STRING_LITERAL_LONG_SINGLE_QUOTE, Terminals::STRING_LITERAL_QUOTE, Terminals::STRING_LITERAL_SINGLE_QUOTE, Terminals::UCHAR, Terminals::U_CHARS1, Terminals::U_CHARS2, Terminals::WS

Instance Attribute Summary

Attributes included from EBNF::LL1::Parser

#lineno

Attributes inherited from Reader

#options

Attributes included from Enumerable

#existentials, #universals

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Util::Logger

#log_debug, #log_depth, #log_error, #log_fatal, #log_info, #log_recover, #log_recovering?, #log_statistics, #log_warn, #logger

Methods included from EBNF::LL1::Parser

#add_prod_data, #add_prod_datum, #depth, #parse, #prod_data, #warn

Methods inherited from Reader

#base_uri, #canonicalize?, #close, each, #each_pg_statement, #encoding, #fail_object, #fail_predicate, #fail_subject, for, format, #intern?, #lineno, open, #prefixes, #prefixes=, #read_triple, #rewind, #to_sym, to_sym, #valid?, #validate?

Methods included from Util::Aliasing::LateBound

#alias_method

Methods included from Enumerable

add_entailment, #dump, #each_graph, #each_object, #each_predicate, #each_quad, #each_subject, #each_term, #entail, #enum_graph, #enum_object, #enum_predicate, #enum_quad, #enum_statement, #enum_subject, #enum_term, #enum_triple, #graph_names, #has_graph?, #has_object?, #has_predicate?, #has_quad?, #has_statement?, #has_subject?, #has_term?, #has_triple?, #invalid?, #method_missing, #objects, #predicates, #project_graph, #quads, #respond_to_missing?, #statements, #subjects, #supports?, #terms, #to_a, #to_h, #to_set, #triples, #valid?, #validate!

Methods included from Countable

#count, #empty?

Methods included from Isomorphic

#bijection_to, #isomorphic_with?

Methods included from Readable

#readable?

Constructor Details

#initialize(input = nil, **options, &block) ⇒ RDF::Turtle::Reader

Initializes a new reader instance.

Note, the spec does not define a default mapping for the empty prefix, but it is so commonly used in examples that we define it to be the empty string anyway, except when validating.

Parameters:

Options Hash (**options):

  • :prefixes (Hash) — default: Hash.new

    the prefix mappings to use (for acessing intermediate parser productions)

  • :base_uri (#to_s) — default: nil

    the base URI to use when resolving relative URIs (for acessing intermediate parser productions)

  • :anon_base (#to_s) — default: "b0"

    Basis for generating anonymous Nodes

  • :validate (Boolean) — default: false

    whether to validate the parsed statements and values. If not validating, the parser will attempt to recover from errors.

  • :logger (Logger, #write, #<<)

    Record error/info/debug output

  • :freebase (Boolean) — default: false

    Use optimized Freebase reader



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'vendor/bundler/ruby/2.7.0/bundler/gems/rdf-turtle-574b3b7c8c08/lib/rdf/turtle/reader.rb', line 92

def initialize(input = nil, **options, &block)
  super do
    @options = {
      anon_base:  "b0",
      whitespace:  WS,
      depth: 0,
    }.merge(@options)
    @prod_stack = []

    @options[:base_uri] = RDF::URI(base_uri || "")
    debug("base IRI") {base_uri.inspect}
    
    debug("validate") {validate?.inspect}
    debug("canonicalize") {canonicalize?.inspect}
    debug("intern") {intern?.inspect}

    @lexer = EBNF::LL1::Lexer.new(input, self.class.patterns, **@options)

    if block_given?
      case block.arity
        when 0 then instance_eval(&block)
        else block.call(self)
      end
    end
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class RDF::Enumerable

Class Method Details

.optionsObject

Reader options



44
45
46
47
48
49
50
51
52
# File 'vendor/bundler/ruby/2.7.0/bundler/gems/rdf-turtle-574b3b7c8c08/lib/rdf/turtle/reader.rb', line 44

def self.options
  super + [
    RDF::CLI::Option.new(
      symbol: :freebase,
      datatype: TrueClass,
      on: ["--freebase"],
      description: "Use optimized Freebase reader.") {true},
  ]
end

Instance Method Details

#add_statement(production, statement) ⇒ RDF::Statement

add a statement, object can be literal or URI or bnode

Parameters:

Returns:

Raises:

  • (RDF::ReaderError)

    Checks parameter types and raises if they are incorrect if parsing mode is validate.



172
173
174
175
176
177
178
# File 'vendor/bundler/ruby/2.7.0/bundler/gems/rdf-turtle-574b3b7c8c08/lib/rdf/turtle/reader.rb', line 172

def add_statement(production, statement)
  error("Statement is invalid: #{statement.inspect}", production: produciton) if validate? && statement.invalid?
  @callback.call(statement) if statement.subject &&
                               statement.predicate &&
                               statement.object &&
                               (validate? ? statement.valid? : true)
end

#bnode(value = nil) ⇒ Object

Keep track of allocated BNodes



236
237
238
239
240
# File 'vendor/bundler/ruby/2.7.0/bundler/gems/rdf-turtle-574b3b7c8c08/lib/rdf/turtle/reader.rb', line 236

def bnode(value = nil)
  return RDF::Node.new unless value
  @bnode_cache ||= {}
  @bnode_cache[value.to_s] ||= RDF::Node.new(value)
end

#debug(*args, &block) ⇒ Object (protected)



625
626
627
628
629
630
631
# File 'vendor/bundler/ruby/2.7.0/bundler/gems/rdf-turtle-574b3b7c8c08/lib/rdf/turtle/reader.rb', line 625

def debug(*args, &block)
  lineno = (options[:token].lineno if options[:token].respond_to?(:lineno)) || (@lexer && @lexer.lineno)
  opts = args.last.is_a?(Hash) ? args.pop : {}
  opts[:level] ||= 0
  opts[:lineno] ||= lineno
  log_debug(*args, **opts, &block)
end

#each_statement {|statement| ... }

This method returns an undefined value.

Iterates the given block for each RDF statement in the input.

Yields:

  • (statement)

Yield Parameters:



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'vendor/bundler/ruby/2.7.0/bundler/gems/rdf-turtle-574b3b7c8c08/lib/rdf/turtle/reader.rb', line 129

def each_statement(&block)
  if block_given?
    log_recover
    @callback = block

    begin
      while (@lexer.first rescue true)
        read_statement
      end
    rescue EBNF::LL1::Lexer::Error, SyntaxError, EOFError, Recovery
      # Terminate loop if EOF found while recovering
    end

    if validate? && log_statistics[:error]
      raise RDF::ReaderError, "Errors found during processing"
    end
  end
  enum_for(:each_statement)
end

#each_triple {|subject, predicate, object| ... }

This method returns an undefined value.

Iterates the given block for each RDF triple in the input.

Yields:

  • (subject, predicate, object)

Yield Parameters:



157
158
159
160
161
162
163
164
# File 'vendor/bundler/ruby/2.7.0/bundler/gems/rdf-turtle-574b3b7c8c08/lib/rdf/turtle/reader.rb', line 157

def each_triple(&block)
  if block_given?
    each_statement do |statement|
      block.call(*statement.to_triple)
    end
  end
  enum_for(:each_triple)
end

#error(node, message, options) ⇒ Object (protected)

Error information, used as level 0 debug messages.

Parameters:

  • node (String)

    Relevant location associated with message

  • message (String)

    Error string

  • options (Hash)

Options Hash (options):

  • :production (URI, #to_s)
  • :token (Token)

See Also:

  • RDF::Turtle::Reader.{{#debug}


643
644
645
646
647
648
649
650
651
652
653
654
# File 'vendor/bundler/ruby/2.7.0/bundler/gems/rdf-turtle-574b3b7c8c08/lib/rdf/turtle/reader.rb', line 643

def error(*args)
  ctx = ""
  ctx += "(found #{options[:token].inspect})" if options[:token]
  ctx += ", production = #{options[:production].inspect}" if options[:production]
  lineno = @lineno || (options[:token].lineno if options[:token].respond_to?(:lineno)) || @lexer.lineno
  log_error(*args, ctx,
    lineno:     lineno,
    token:      options[:token],
    production: options[:production],
    depth:      options[:depth],
    exception:  SyntaxError,)
end

#inspectObject



119
120
121
# File 'vendor/bundler/ruby/2.7.0/bundler/gems/rdf-turtle-574b3b7c8c08/lib/rdf/turtle/reader.rb', line 119

def inspect
  sprintf("#<%s:%#0x(%s)>", self.class.name, __id__, base_uri.to_s)
end

#literal(value, **options) ⇒ Object

Create a literal



194
195
196
197
198
199
200
201
202
203
204
# File 'vendor/bundler/ruby/2.7.0/bundler/gems/rdf-turtle-574b3b7c8c08/lib/rdf/turtle/reader.rb', line 194

def literal(value, **options)
  debug("literal", depth: @options[:depth]) do
    "value: #{value.inspect}, " +
    "options: #{options.inspect}, " +
    "validate: #{validate?.inspect}, " +
    "c14n?: #{canonicalize?.inspect}"
  end
  RDF::Literal.new(value, validate:  validate?, canonicalize:  canonicalize?, **options)
rescue ArgumentError => e
  error("Argument Error #{e.message}", production: :literal, token: @lexer.first)
end

#pname(prefix, suffix) ⇒ Object

Expand a PNAME using string concatenation



220
221
222
223
224
225
226
227
228
229
230
231
232
233
# File 'vendor/bundler/ruby/2.7.0/bundler/gems/rdf-turtle-574b3b7c8c08/lib/rdf/turtle/reader.rb', line 220

def pname(prefix, suffix)
  # Prefixes must be defined, except special case for empty prefix being alias for current @base
  base = if prefix(prefix)
    prefix(prefix).to_s
  elsif prefix.to_s.empty? && !validate?
    base_uri.to_s
  else
    error("undefined prefix", production: :pname, token: prefix)
    ''
  end
  suffix = suffix.to_s.sub(/^\#/, "") if base.index("#")
  debug("pname", depth: options[:depth]) {"base: '#{base}', suffix: '#{suffix}'"}
  process_iri(base + suffix.to_s)
end

#prefix(prefix, iri = nil) ⇒ Object

Override #prefix to take a relative IRI

prefix directives map a local name to an IRI, also resolved against the current In-Scope Base URI. Spec confusion, presume that an undefined empty prefix has an empty relative IRI, which uses string contatnation rules against the in-scope IRI at the time of use



212
213
214
215
216
# File 'vendor/bundler/ruby/2.7.0/bundler/gems/rdf-turtle-574b3b7c8c08/lib/rdf/turtle/reader.rb', line 212

def prefix(prefix, iri = nil)
  # Relative IRIs are resolved against @base
  iri = process_iri(iri) if iri
  super(prefix, iri)
end

#process_iri(iri) ⇒ Object

Process a URI against base



181
182
183
184
185
186
187
188
189
190
191
# File 'vendor/bundler/ruby/2.7.0/bundler/gems/rdf-turtle-574b3b7c8c08/lib/rdf/turtle/reader.rb', line 181

def process_iri(iri)
  iri = iri.value[1..-2] if iri === :IRIREF
  value = RDF::URI(iri)
  value = base_uri.join(value) if value.relative?
  value.validate! if validate?
  value.canonicalize! if canonicalize? && !value.frozen?
  value = RDF::URI.intern(value) if intern?
  value
rescue ArgumentError => e
  error("process_iri", e)
end

#prod(production, recover_to = []) ⇒ Object (protected)



555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
# File 'vendor/bundler/ruby/2.7.0/bundler/gems/rdf-turtle-574b3b7c8c08/lib/rdf/turtle/reader.rb', line 555

def prod(production, recover_to = [])
  @prod_stack << {prod: production, recover_to: recover_to}
  @options[:depth] += 1
  recover("#{production}(start)", depth: options[:depth], token: @lexer.first)
  yield
rescue EBNF::LL1::Lexer::Error, SyntaxError, Recovery =>  e
  # Lexer encountered an illegal token or the parser encountered
  # a terminal which is inappropriate for the current production.
  # Perform error recovery to find a reasonable terminal based
  # on the follow sets of the relevant productions. This includes
  # remaining terms from the current production and the stacked
  # productions
  case e
  when EBNF::LL1::Lexer::Error
    @lexer.recover
    begin
      error("Lexer error", "With input '#{e.input}': #{e.message}",
        production: production,
        token: e.token)
    rescue SyntaxError
    end
  end
  raise EOFError, "End of input found when recovering" if @lexer.first.nil?
  debug("recovery", "current token: #{@lexer.first.inspect}", depth: options[:depth])

  unless e.is_a?(Recovery)
    # Get the list of follows for this sequence, this production and the stacked productions.
    debug("recovery", "stack follows:", depth: options[:depth])
    @prod_stack.reverse.each do |prod|
      debug("recovery", level: 4, depth: options[:depth]) {"  #{prod[:prod]}: #{prod[:recover_to].inspect}"}
    end
  end

  # Find all follows to the top of the stack
  follows = @prod_stack.map {|prod| Array(prod[:recover_to])}.flatten.compact.uniq

  # Skip tokens until one is found in follows
  while (token = (@lexer.first rescue @lexer.recover)) && follows.none? {|t| token === t}
    skipped = @lexer.shift
    debug("recovery", depth: options[:depth]) {"skip #{skipped.inspect}"}
  end
  debug("recovery", depth: options[:depth]) {"found #{token.inspect} in follows"}

  # Re-raise the error unless token is a follows of this production
  raise Recovery unless Array(recover_to).any? {|t| token === t}

  # Skip that token to get something reasonable to start the next production with
  @lexer.shift
ensure
  progress("#{production}(finish)", depth: options[:depth])
  @options[:depth] -= 1
  @prod_stack.pop
end

#progress(*args, &block) ⇒ Object (protected)



609
610
611
612
613
614
615
# File 'vendor/bundler/ruby/2.7.0/bundler/gems/rdf-turtle-574b3b7c8c08/lib/rdf/turtle/reader.rb', line 609

def progress(*args, &block)
  lineno = (options[:token].lineno if options[:token].respond_to?(:lineno)) || (@lexer && @lexer.lineno)
  opts = args.last.is_a?(Hash) ? args.pop : {}
  opts[:level] ||= 1
  opts[:lineno] ||= lineno
  log_info(*args, **opts, &block)
end

#read_annotation(subject, predicate, object) ⇒ Object (protected)

Read an annotation on a triple



438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
# File 'vendor/bundler/ruby/2.7.0/bundler/gems/rdf-turtle-574b3b7c8c08/lib/rdf/turtle/reader.rb', line 438

def read_annotation(subject, predicate, object)
  error("Unexpected end of file", production: :annotation) unless token = @lexer.first
  if token === '{|'
    prod(:annotation, %(|})) do
      @lexer.shift

      # Statement becomes subject for predicateObjectList
      statement = RDF::Statement(subject, predicate, object)
      read_predicateObjectList(statement) ||
        error("Expected predicateObjectList", production: :annotation, token: @lexer.first)
      error("annotation", "Expected closing '|}'") unless @lexer.first === '|}'
      @lexer.shift
    end
  end

end

#read_BlankNodeRDF::Node (protected)

Returns:



547
548
549
550
551
552
553
# File 'vendor/bundler/ruby/2.7.0/bundler/gems/rdf-turtle-574b3b7c8c08/lib/rdf/turtle/reader.rb', line 547

def read_BlankNode
  token = @lexer.first
  case token && token.type
  when :BLANK_NODE_LABEL then prod(:BlankNode) {bnode(@lexer.shift.value[2..-1])}
  when :ANON then @lexer.shift && prod(:BlankNode) {bnode}
  end
end

#read_blankNodePropertyListRDF::Node (protected)

Returns:



500
501
502
503
504
505
506
507
508
509
510
511
512
513
# File 'vendor/bundler/ruby/2.7.0/bundler/gems/rdf-turtle-574b3b7c8c08/lib/rdf/turtle/reader.rb', line 500

def read_blankNodePropertyList
  token = @lexer.first
  if token === '['
    prod(:blankNodePropertyList, %{]}) do
      @lexer.shift
      progress("blankNodePropertyList", depth: options[:depth]) {"token: #{token.inspect}"}
      node = bnode
      read_predicateObjectList(node)
      error("blankNodePropertyList", "Expected closing ']'") unless @lexer.first === ']'
      @lexer.shift
      node
    end
  end
end

#read_collectionRDF::Node (protected)

Returns:



516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
# File 'vendor/bundler/ruby/2.7.0/bundler/gems/rdf-turtle-574b3b7c8c08/lib/rdf/turtle/reader.rb', line 516

def read_collection
  if @lexer.first === '('
    prod(:collection, %{)}) do
      @lexer.shift
      token = @lexer.first
      progress("collection", depth: options[:depth]) {"token: #{token.inspect}"}
      objects = []
      while object = read_object
        objects << object
      end
      list = RDF::List.new(values: objects)
      list.each_statement do |statement|
        add_statement("collection", statement)
      end
      error("collection", "Expected closing ')'") unless @lexer.first === ')'
      @lexer.shift
      list.subject
    end
  end
end

#read_directive (protected)

This method returns an undefined value.



264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
# File 'vendor/bundler/ruby/2.7.0/bundler/gems/rdf-turtle-574b3b7c8c08/lib/rdf/turtle/reader.rb', line 264

def read_directive
  prod(:directive, %w{.}) do
    token = @lexer.first
    case token.type
    when :BASE
      prod(:base) do
        @lexer.shift
        terminated = token.value == '@base'
        iri = @lexer.shift
        error("Expected IRIREF", production: :base, token: iri) unless iri === :IRIREF
        @options[:base_uri] = process_iri(iri)
        error("base", "#{token} should be downcased") if token.value.start_with?('@') && token.value != '@base'

        if terminated
          error("base", "Expected #{token} to be terminated") unless @lexer.first === '.'
          @lexer.shift
        elsif @lexer.first === '.'
          error("base", "Expected #{token} not to be terminated") 
        else
          true
        end
      end
    when :PREFIX
      prod(:prefixID, %w{.}) do
        @lexer.shift
        pfx, iri = @lexer.shift, @lexer.shift
        terminated = token.value == '@prefix'
        error("Expected PNAME_NS", production: :prefix, token: pfx) unless pfx === :PNAME_NS
        error("Expected IRIREF", production: :prefix, token: iri) unless iri === :IRIREF
        debug("prefixID", depth: options[:depth]) {"Defined prefix #{pfx.inspect} mapping to #{iri.inspect}"}
        prefix(pfx.value[0..-2], process_iri(iri))
        error("prefixId", "#{token} should be downcased") if token.value.start_with?('@') && token.value != '@prefix'

        if terminated
          error("prefixID", "Expected #{token} to be terminated") unless @lexer.first === '.'
          @lexer.shift
        elsif @lexer.first === '.'
          error("prefixID", "Expected #{token} not to be terminated") 
        else
          true
        end
      end
    end
  end
end

#read_embObject(subject = nil, predicate = nil) ⇒ RDF::Term (protected)

Returns:



428
429
430
431
432
433
434
435
# File 'vendor/bundler/ruby/2.7.0/bundler/gems/rdf-turtle-574b3b7c8c08/lib/rdf/turtle/reader.rb', line 428

def read_embObject(subject = nil, predicate = nil)
  prod(:embObject) do
    read_iri ||
    read_BlankNode ||
    read_literal ||
    read_embTriple
  end
end

#read_embSubjectRDF::Resource (protected)

Returns:



418
419
420
421
422
423
424
425
# File 'vendor/bundler/ruby/2.7.0/bundler/gems/rdf-turtle-574b3b7c8c08/lib/rdf/turtle/reader.rb', line 418

def read_embSubject
  prod(:embSubject) do
    read_iri ||
    read_BlankNode ||
    read_embTriple ||
    error( "Expected embedded subject", production: :embSubject, token: @lexer.first)
  end
end

#read_embTripleRDF::Statement (protected)

Read an RDF* reified statement

Returns:



399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
# File 'vendor/bundler/ruby/2.7.0/bundler/gems/rdf-turtle-574b3b7c8c08/lib/rdf/turtle/reader.rb', line 399

def read_embTriple
  return unless @options[:rdfstar]
  if @lexer.first.value == '<<'
    prod(:embTriple) do
      @lexer.shift # eat <<
      subject = read_embSubject || error("Failed to parse subject", production: :embTriple, token: @lexer.first)
      predicate = read_verb || error("Failed to parse predicate", production: :embTriple, token: @lexer.first)
      object = read_embObject || error("Failed to parse object", production: :embTriple, token: @lexer.first)
      unless @lexer.first.value == '>>'
        error("Failed to end of embedded triple", production: :embTriple, token: @lexer.first)
      end
      @lexer.shift
      statement = RDF::Statement(subject, predicate, object)
      statement
    end
  end
end

#read_iriRDF::URI (protected)

Returns:



538
539
540
541
542
543
544
# File 'vendor/bundler/ruby/2.7.0/bundler/gems/rdf-turtle-574b3b7c8c08/lib/rdf/turtle/reader.rb', line 538

def read_iri
  token = @lexer.first
  case token && token.type
  when :IRIREF then prod(:iri)  {process_iri(@lexer.shift)}
  when :PNAME_LN, :PNAME_NS then prod(:iri) {pname(*@lexer.shift.value.split(':', 2))}
  end
end

#read_literalRDF::Literal (protected)

Returns:



456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
# File 'vendor/bundler/ruby/2.7.0/bundler/gems/rdf-turtle-574b3b7c8c08/lib/rdf/turtle/reader.rb', line 456

def read_literal
  error("Unexpected end of file", production: :literal) unless token = @lexer.first
  case token.type || token.value
  when :INTEGER then prod(:literal) {literal(@lexer.shift.value, datatype:  RDF::XSD.integer)}
  when :DECIMAL
    prod(:literal) do
      value = @lexer.shift.value
      value = "0#{value}" if value.start_with?(".")
      literal(value, datatype:  RDF::XSD.decimal)
    end
  when :DOUBLE then prod(:literal) {literal(@lexer.shift.value.sub(/\.([eE])/, '.0\1'), datatype:  RDF::XSD.double)}
  when "true", "false" then prod(:literal) {literal(@lexer.shift.value, datatype: RDF::XSD.boolean)}
  when :STRING_LITERAL_QUOTE, :STRING_LITERAL_SINGLE_QUOTE
    prod(:literal) do
      value = @lexer.shift.value[1..-2]
      error("read_literal", "Unexpected end of file") unless token = @lexer.first
      case token.type || token.value
      when :LANGTAG
        literal(value, language: @lexer.shift.value[1..-1].to_sym)
      when '^^'
        @lexer.shift
        literal(value, datatype: read_iri)
      else
        literal(value)
      end
    end
  when :STRING_LITERAL_LONG_QUOTE, :STRING_LITERAL_LONG_SINGLE_QUOTE
    prod(:literal) do
      value = @lexer.shift.value[3..-4]
      error("read_literal", "Unexpected end of file") unless token = @lexer.first
      case token.type || token.value
      when :LANGTAG
        literal(value, language: @lexer.shift.value[1..-1].to_sym)
      when '^^'
        @lexer.shift
        literal(value, datatype: read_iri)
      else
        literal(value)
      end
    end
  end
end

#read_object(subject = nil, predicate = nil) (protected)

This method returns an undefined value.



382
383
384
385
386
387
388
389
390
391
392
393
394
395
# File 'vendor/bundler/ruby/2.7.0/bundler/gems/rdf-turtle-574b3b7c8c08/lib/rdf/turtle/reader.rb', line 382

def read_object(subject = nil, predicate = nil)
  prod(:object) do
    if object = read_iri ||
      read_BlankNode ||
      read_collection ||
      read_blankNodePropertyList ||
      read_literal ||
      read_embTriple

      add_statement(:object, RDF::Statement(subject, predicate, object)) if subject && predicate
      object
    end
  end
end

#read_objectList(subject, predicate) ⇒ RDF::Term (protected)

Returns the last matched subject.

Returns:



345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
# File 'vendor/bundler/ruby/2.7.0/bundler/gems/rdf-turtle-574b3b7c8c08/lib/rdf/turtle/reader.rb', line 345

def read_objectList(subject, predicate)
  prod(:objectList, %{,}) do
    last_object = nil
    while object = prod(:_objectList_2) {read_object(subject, predicate)}
      last_object = object

      # If object is followed by an annotation, read that and also emit an embedded triple.
      read_annotation(subject, predicate, object)

      break unless @lexer.first === ','
      @lexer.shift while @lexer.first === ','
    end
    last_object
  end
end

#read_predicateObjectList(subject) ⇒ RDF::URI (protected)

Returns the last matched verb.

Parameters:

Returns:



329
330
331
332
333
334
335
336
337
338
339
340
341
342
# File 'vendor/bundler/ruby/2.7.0/bundler/gems/rdf-turtle-574b3b7c8c08/lib/rdf/turtle/reader.rb', line 329

def read_predicateObjectList(subject)
  prod(:predicateObjectList, %{;}) do
    last_verb = nil
    while verb = read_verb
      last_verb = verb
      prod(:_predicateObjectList_5) do
        read_objectList(subject, verb) || error("Expected objectList", production: :predicateObjectList, token: @lexer.first)
      end
      break unless @lexer.first === ';'
      @lexer.shift while @lexer.first === ';'
    end
    last_verb
  end
end

#read_statement (protected)

This method returns an undefined value.



244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
# File 'vendor/bundler/ruby/2.7.0/bundler/gems/rdf-turtle-574b3b7c8c08/lib/rdf/turtle/reader.rb', line 244

def read_statement
  prod(:statement, %w{.}) do
    error("read_statement", "Unexpected end of file") unless token = @lexer.first
    case token.type
    when :BASE, :PREFIX
      read_directive || error("Failed to parse directive", production: :directive, token: token)
    else
      read_triples || error("Expected token", production: :statement, token: token)
      if !log_recovering? || @lexer.first === '.'
        # If recovering, we will have eaten the closing '.'
        token = @lexer.shift
        unless token && token.value == '.'
          error("Expected '.' following triple", production: :statement, token: token)
        end
      end
    end
  end
end

#read_subjectRDF::Resource (protected)

Returns:



371
372
373
374
375
376
377
378
379
# File 'vendor/bundler/ruby/2.7.0/bundler/gems/rdf-turtle-574b3b7c8c08/lib/rdf/turtle/reader.rb', line 371

def read_subject
  prod(:subject) do
    read_iri ||
    read_BlankNode ||
    read_collection ||
    read_embTriple ||
    error( "Expected subject", production: :subject, token: @lexer.first)
  end
end

#read_triplesObject (protected)

Returns the last verb matched, or subject BNode on predicateObjectList?

Returns:

  • (Object)

    returns the last verb matched, or subject BNode on predicateObjectList?



311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
# File 'vendor/bundler/ruby/2.7.0/bundler/gems/rdf-turtle-574b3b7c8c08/lib/rdf/turtle/reader.rb', line 311

def read_triples
  prod(:triples, %w{.}) do
    error("read_triples", "Unexpected end of file") unless token = @lexer.first
    case token.type || token.value
    when '['
      # blankNodePropertyList predicateObjectList? 
      subject = read_blankNodePropertyList || error("Failed to parse blankNodePropertyList", production: :triples, token: @lexer.first)
      read_predicateObjectList(subject) || subject
    else
      # subject predicateObjectList
      subject = read_subject || error("Failed to parse subject", production: :triples, token: @lexer.first)
      read_predicateObjectList(subject) || error("Expected predicateObjectList", production: :triples, token: @lexer.first)
    end
  end
end

#read_verbRDF::URI (protected)

Returns:



362
363
364
365
366
367
368
# File 'vendor/bundler/ruby/2.7.0/bundler/gems/rdf-turtle-574b3b7c8c08/lib/rdf/turtle/reader.rb', line 362

def read_verb
  error("read_verb", "Unexpected end of file") unless token = @lexer.first
  case token.type || token.value
  when 'a' then prod(:verb) {@lexer.shift && RDF.type}
  else prod(:verb) {read_iri}
  end
end

#recover(*args, &block) ⇒ Object (protected)



617
618
619
620
621
622
623
# File 'vendor/bundler/ruby/2.7.0/bundler/gems/rdf-turtle-574b3b7c8c08/lib/rdf/turtle/reader.rb', line 617

def recover(*args, &block)
  lineno = (options[:token].lineno if options[:token].respond_to?(:lineno)) || (@lexer && @lexer.lineno)
  opts = args.last.is_a?(Hash) ? args.pop : {}
  opts[:level] ||= 1
  opts[:lineno] ||= lineno
  log_recover(*args, **opts, &block)
end