lib/rdf/turtle/reader.rb in rdf-turtle-0.1.0 vs lib/rdf/turtle/reader.rb in rdf-turtle-0.1.1

- old
+ new

@@ -94,42 +94,40 @@ # [4] prefixID defines a prefix mapping production(:prefixID) do |reader, phase, input, current, callback| next unless phase == :finish prefix = current[:prefix] iri = current[:resource] - callback.call(:trace, "prefixID", "Defined prefix #{prefix.inspect} mapping to #{iri.inspect}") + callback.call(:trace, "prefixID", lambda {"Defined prefix #{prefix.inspect} mapping to #{iri.inspect}"}) reader.prefix(prefix, iri) end # [5] base set base_uri production(:base) do |reader, phase, input, current, callback| next unless phase == :finish iri = current[:resource] - callback.call(:trace, "base", "Defined base as #{iri}") + callback.call(:trace, "base", lambda {"Defined base as #{iri}"}) reader.options[:base_uri] = iri end # [9] verb ::= predicate | "a" production(:verb) do |reader, phase, input, current, callback| - next unless phase == :finish input[:predicate] = current[:resource] if phase == :finish end # [10] subject ::= IRIref | blank production(:subject) do |reader, phase, input, current, callback| - next unless phase == :finish input[:subject] = current[:resource] if phase == :finish end # [12] object ::= IRIref | blank | literal production(:object) do |reader, phase, input, current, callback| next unless phase == :finish if input[:object_list] # Part of an rdf:List collection input[:object_list] << current[:resource] else - callback.call(:trace, "object", "current: #{current.inspect}") + callback.call(:trace, "object", lambda {"current: #{current.inspect}"}) callback.call(:statement, "object", input[:subject], input[:predicate], current[:resource]) end end # [15] blankNodePropertyList ::= "[" predicateObjectList "]" @@ -174,10 +172,14 @@ end ## # 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. + # # @param [String, #to_s] input # @param [Hash{Symbol => Object}] options # @option options [Hash] :prefixes (Hash.new) # the prefix mappings to use (for acessing intermediate parser productions) # @option options [#to_s] :base_uri (nil) @@ -197,10 +199,11 @@ # Detailed debug output # @return [RDF::Turtle::Reader] def initialize(input = nil, options = {}, &block) super do @options = {:anon_base => "b0", :validate => false}.merge(options) + @options = {:prefixes => {nil => ""}}.merge(@options) unless @options[:validate] debug("base IRI") {base_uri.inspect} debug("validate") {validate?.inspect} debug("canonicalize") {canonicalize?.inspect} @@ -226,20 +229,25 @@ # @yieldparam [RDF::Statement] statement # @return [void] def each_statement(&block) @callback = block - parse(@input, START.to_sym, @options.merge(:branch => BRANCH, :follow => FOLLOW)) do |context, *data| + parse(@input, START.to_sym, @options.merge(:branch => BRANCH, + :first => FIRST, + :follow => FOLLOW) + ) do |context, *data| + loc = data.shift case context when :statement - add_triple(*data) + add_statement(loc, RDF::Statement.from(data)) when :trace - debug(*data) + debug(loc, *data) end end rescue RDF::LL1::Parser::Error => e - error("each_statement", e.message, :backtrace => e.backtrace) + debug("Parsing completed with errors:\n\t#{e.message}") + raise RDF::ReaderError, e.message if validate? end ## # Iterates the given block for each RDF triple in the input. # @@ -260,12 +268,11 @@ # @param [URI, Node] subject:: the subject of the statement # @param [URI] predicate:: the predicate of the statement # @param [URI, Node, Literal] object:: the object of the statement # @return [Statement]:: Added statement # @raise [RDF::ReaderError]:: Checks parameter types and raises if they are incorrect if parsing mode is _validate_. - def add_triple(node, subject, predicate, object) - statement = RDF::Statement.new(subject, predicate, object) + def add_statement(node, statement) if statement.valid? debug(node) {"generate statement: #{statement}"} @callback.call(statement) else error(node, "Statement is invalid: #{statement.inspect}") @@ -332,31 +339,24 @@ return RDF::Node.new unless value @bnode_cache ||= {} @bnode_cache[value.to_s] ||= RDF::Node.new(value) end - # @param [String] str Error string - # @param [Hash] options - # @option options [URI, #to_s] :production - # @option options [Token] :token - def error(node, message, options = {}) - if !validate? && !options[:fatal] - debug(node, message, options) - else - raise RDF::ReaderError, message, options[:backtrace] - end - end - ## # Progress output when debugging # @param [String] node relative location in input # @param [String] message ("") # @yieldreturn [String] added to message - def debug(node, message = "", options = {}) + def debug(*args) return unless @options[:debug] || RDF::Turtle.debug? + options = args.last.is_a?(Hash) ? args.pop : {} depth = options[:depth] || self.depth - message += yield if block_given? - str = "[#{@lineno}]#{' ' * depth}#{node}: #{message}" + message = args.pop + message = message.call if message.is_a?(Proc) + args << message if message + args << yield if block_given? + message = "#{args.join(': ')}" + str = "[#{@lineno}]#{' ' * depth}#{message}" @options[:debug] << str if @options[:debug].is_a?(Array) $stderr.puts(str) if RDF::Turtle.debug? end end # class Reader end # module RDF::Turtle