Class: RDF::Turtle::Reader
- Inherits:
-
Reader
- Object
- Reader
- RDF::Turtle::Reader
- Includes:
- EBNF::LL1::Parser, Terminals, Util::Logger
- Defined in:
- lib/rdf/turtle/reader.rb
Overview
A parser for the Turtle 2
Defined Under Namespace
Classes: Recovery, SyntaxError
Constant Summary
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::LANG_DIR, 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
Class Method Summary collapse
-
.new(input = nil, **options, &block) ⇒ Object
Redirect for Freebase Reader.
-
.options ⇒ Object
Reader options.
Instance Method Summary collapse
-
#add_statement(production, statement) ⇒ RDF::Statement
add a statement, object can be literal or URI or bnode.
-
#bnode(value = nil) ⇒ Object
Keep track of allocated BNodes.
-
#each_statement {|statement| ... } ⇒ void
Iterates the given block for each RDF statement in the input.
-
#each_triple {|subject, predicate, object| ... } ⇒ void
Iterates the given block for each RDF triple in the input.
-
#initialize(input = nil, **options, &block) ⇒ RDF::Turtle::Reader
constructor
Initializes a new reader instance.
- #inspect ⇒ Object
-
#literal(value, **options) ⇒ Object
Create a literal.
-
#pname(prefix, suffix) ⇒ Object
Expand a PNAME using string concatenation.
-
#prefix(prefix, iri = nil) ⇒ Object
Override #prefix to take a relative IRI.
-
#process_iri(iri) ⇒ Object
Process a URI against base.
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.
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 'lib/rdf/turtle/reader.rb', line 92 def initialize(input = nil, **, &block) super do = { anon_base: "b0", whitespace: WS, depth: 0, }.merge() @prod_stack = [] [: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, **) if block_given? case block.arity when 0 then instance_eval(&block) else block.call(self) end end end end |
Class Method Details
.new(input = nil, **options, &block) ⇒ Object
Redirect for Freebase Reader
58 59 60 61 62 63 64 65 66 67 |
# File 'lib/rdf/turtle/reader.rb', line 58 def self.new(input = nil, **, &block) klass = if [:freebase] FreebaseReader else self end reader = klass.allocate reader.send(:initialize, input, **, &block) reader end |
.options ⇒ Object
Reader options
44 45 46 47 48 49 50 51 52 |
# File 'lib/rdf/turtle/reader.rb', line 44 def self. 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
172 173 174 175 176 177 178 |
# File '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
243 244 245 246 247 |
# File 'lib/rdf/turtle/reader.rb', line 243 def bnode(value = nil) return RDF::Node.new unless value @bnode_cache ||= {} @bnode_cache[value.to_s] ||= RDF::Node.new(value) end |
#each_statement {|statement| ... } ⇒ void
This method returns an undefined value.
Iterates the given block for each RDF statement in the input.
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File '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| ... } ⇒ void
This method returns an undefined value.
Iterates the given block for each RDF triple in the input.
157 158 159 160 161 162 163 164 |
# File '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 |
#inspect ⇒ Object
119 120 121 |
# File '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 'lib/rdf/turtle/reader.rb', line 194 def literal(value, **) debug("literal", depth: [:depth]) do "value: #{value.inspect}, " + "options: #{options.inspect}, " + "validate: #{validate?.inspect}, " + "c14n?: #{canonicalize?.inspect}" end RDF::Literal.new(value, validate: validate?, canonicalize: canonicalize?, **) 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 234 235 236 237 238 239 240 |
# File '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 # Unescape PN_LOCAL_ESC suffix = suffix.gsub(PN_LOCAL_ESC) {|esc| esc[1]} if suffix.match?(PN_LOCAL_ESC) # Remove any redundant leading hash from suffix suffix = suffix.sub(/^\#/, "") if base.index("#") debug("pname", depth: [: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 '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 '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 |