class LD::Patch::Parser
A parser for the LD
Patch
grammar.
@see www.w3.org/TR/ldpatch/#concrete-syntax @see en.wikipedia.org/wiki/LR_parser
Attributes
Accumulated errors found during processing @return [Array<String>]
The current input string being processed.
@return [String]
Any additional options for the parser.
@return [Hash]
The internal representation of the result @return [Array]
The current input tokens being processed.
@return [Array<Token>]
Public Class Methods
Source
# File lib/ld/patch/parser.rb, line 326 def initialize(input = nil, **options, &block) @input = case input when IO, StringIO then input.read else input.to_s.dup end @input.encode!(Encoding::UTF_8) if @input.respond_to?(:encode!) @options = {anon_base: "b0", validate: false}.merge(options) @errors = @options[:errors] @options[:debug] ||= case when options[:progress] then 2 when options[:validate] then (@errors ? nil : 1) end debug("base IRI") {base_uri.inspect} debug("validate") {validate?.inspect} @vars = {} if block_given? case block.arity when 0 then instance_eval(&block) else block.call(self) end end end
Initializes a new parser instance.
@param [String, IO, StringIO, to_s] input @param [Hash{Symbol => Object}] options @option options [#to_s] :base_uri (nil)
the base URI to use when resolving relative URIs
@option options [#to_s] :anon_base (“b0”)
Basis for generating anonymous Nodes
@option options [Boolean] :resolve_iris (false)
Resolve prefix and relative IRIs, otherwise, when serializing the parsed SSE as S-Expressions, use the original prefixed and relative URIs along with `base` and `prefix` definitions.
@option options [Boolean] :validate (false)
whether to validate the parsed statements and values
@option options [Array] :errors
array for placing errors found when parsing
@option options [Array] :warnings
array for placing warnings found when parsing
@option options [Boolean] :progress
Show progress of parser productions
@option options [Boolean] :debug
Detailed debug output
@yield [parser] ‘self` @yieldparam [LD::Patch::Parser] parser @return [LD::Patch::Parser] The parser instance, or result returned from block
Public Instance Methods
Source
# File lib/ld/patch/parser.rb, line 426 def base_uri RDF::URI(@options[:base_uri]) end
Returns the Base URI defined for the parser, as specified or when parsing a BASE prologue element.
@example
base #=> RDF::URI('http://example.com/')
@return [HRDF::URI]
Source
# File lib/ld/patch/parser.rb, line 439 def base_uri=(iri) @options[:base_uri] = RDF::URI(iri) end
Set the Base URI to use for this parser.
@param [RDF::URI, to_s] iri
@example
base_uri = RDF::URI('http://purl.org/dc/terms/')
@return [RDF::URI]
Source
# File lib/ld/patch/parser.rb, line 368 def parse(prod = START) ll1_parse(@input, prod.to_sym, branch: BRANCH, first: FIRST, follow: FOLLOW, whitespace: WS, **@options ) do |context, *data| case context when :trace level, lineno, depth, *args = data message = args.to_sse d_str = depth > 100 ? ' ' * 100 + '+' : ' ' * depth str = "[#{lineno}](#{level})#{d_str}#{message}".chop if @errors && level == 0 @errors << str else case @options[:debug] when Array @options[:debug] << str when TrueClass $stderr.puts str when Integer $stderr.puts(str) if level <= @options[:debug] end end end end # The last thing on the @prod_data stack is the result @result = case when !prod_data.is_a?(Hash) prod_data when prod_data.empty? nil when prod_data[:ldpatch] prod_data[:ldpatch] else key = prod_data.keys.first [key] + Array(prod_data[key]) # Creates [:key, [:triple], ...] end # Validate resulting expression @result.validate! if @result && validate? @result rescue EBNF::LL1::Parser::Error, EBNF::LL1::Lexer::Error => e raise LD::Patch::ParseError.new(e.message, lineno: e.lineno, token: e.token) end
Parse patch
The result is an S-List. Productions return an array such as the following:
(prefix ((: <http://example/>))
@param [Symbol, to_s] prod The starting production for the parser.
It may be a URI from the grammar, or a symbol representing the local_name portion of the grammar URI.
@return [SPARQL::Algebra::Operator, Object] @raise [ParseError] when illegal grammar detected.
Source
# File lib/ld/patch/parser.rb, line 472 def prefix(name = nil, iri = nil) name = name.to_s.empty? ? nil : (name.respond_to?(:to_sym) ? name.to_sym : name.to_s.to_sym) iri.nil? ? prefixes[name] : prefixes[name] = iri end
Defines the given named URI prefix for this parser.
@example Defining a URI prefix
prefix :dc, RDF::URI('http://purl.org/dc/terms/')
@example Returning a URI prefix
prefix(:dc) #=> RDF::URI('http://purl.org/dc/terms/')
@overload prefix(name, uri)
@param [Symbol, #to_s] name @param [RDF::URI, #to_s] uri
@overload prefix(name)
@param [Symbol, #to_s] name
@return [RDF::URI]
Source
# File lib/ld/patch/parser.rb, line 451 def prefixes @options[:prefixes] ||= {} end
Returns the URI prefixes currently defined for this parser.
@example
prefixes[:dc] #=> RDF::URI('http://purl.org/dc/terms/')
@return [Hash{Symbol => RDF::URI}] @since 0.3.0
Private Instance Methods
Source
# File lib/ld/patch/parser.rb, line 510 def bnode(id = nil) unless id id = @options[:anon_base] @options[:anon_base] = @options[:anon_base].succ end # Don't use provided ID to avoid aliasing issues when re-serializing the graph, when the bnode identifiers are re-used (@bnode_cache ||= {})[id.to_s] ||= begin new_bnode = RDF::Node.new new_bnode.lexical = "_:#{id}" new_bnode end end
Generate a BNode identifier
Source
# File lib/ld/patch/parser.rb, line 524 def iri(value) # If we have a base URI, use that when constructing a new URI iri = if base_uri u = base_uri.join(value.to_s) u.lexical = "<#{value}>" unless u.to_s == value.to_s || resolve_iris? u else RDF::URI(value) end iri.validate! if validate? && iri.respond_to?(:validate) #iri = RDF::URI.intern(iri) if intern? iri end
Create URIs
Source
# File lib/ld/patch/parser.rb, line 558 def literal(value, **options) options = options.dup # Internal representation is to not use xsd:string, although it could arguably go the other way. options.delete(:datatype) if options[:datatype] == RDF::XSD.string debug("literal") do "value: #{value.inspect}, " + "options: #{options.inspect}, " + "validate: #{validate?.inspect}, " end RDF::Literal.new(value, validate: validate?, **options) end
Create a literal
Source
# File lib/ld/patch/parser.rb, line 539 def ns(prefix, suffix) error("pname", "undefined prefix #{prefix.inspect}") unless prefix(prefix) base = prefix(prefix).to_s # Unescape PN_LOCAL_ESC suffix = suffix.gsub(PN_LOCAL_ESC) {|esc| esc[1]} if suffix.to_s.match?(PN_LOCAL_ESC) # Remove any redundant leading hash from suffix suffix = suffix.to_s.sub(/^\#/, "") if base.index("#") debug {"ns(#{prefix.inspect}): base: '#{base}', suffix: '#{suffix}'"} iri = iri(base + suffix.to_s) # Cause URI to be serialized as a lexical iri.lexical = "#{prefix}:#{suffix}" unless resolve_iris? iri end
Source
# File lib/ld/patch/parser.rb, line 483 def resolve_iris? @options[:resolve_iris] end
Returns ‘true` if parsed statements and values should be validated.
@return [Boolean] ‘true` or `false` @since 0.3.0
Source
# File lib/ld/patch/parser.rb, line 492 def validate? @options[:validate] end
Returns ‘true` when resolving IRIs, otherwise BASE and PREFIX are retained in the output algebra.
@return [Boolean] ‘true` or `false` @since 1.0.3
Source
# File lib/ld/patch/parser.rb, line 501 def variable(id, distinguished = true) @vars[id] ||= begin v = RDF::Query::Variable.new(id) v.distinguished = distinguished v end end
Return variable allocated to an ID. If no ID is provided, a new variable is allocated. Otherwise, any previous assignment will be used. @return [RDF::Query::Variable]