lib/shex/algebra/semact.rb in shex-0.2.0 vs lib/shex/algebra/semact.rb in shex-0.3.0
- old
+ new
@@ -1,35 +1,85 @@
module ShEx::Algebra
##
class SemAct < Operator
NAME = :semact
+ ##
+ # Creates an operator instance from a parsed ShExJ representation
+ # @param (see Operator#from_shexj)
+ # @return [Operator]
+ def self.from_shexj(operator, options = {})
+ raise ArgumentError unless operator.is_a?(Hash) && operator['type'] == "SemAct"
+ raise ArgumentError, "missing name in #{operator.inspect}" unless operator.has_key?('name')
+ code = operator.delete('code')
+ operator['code'] = code if code # Reorders operands appropriately
+ super
+ end
+
+ ##
+ # Called on entry
#
+ # @param [String] code
+ # @param [Array<RDF::Statement>] arcs_in available statements to be matched having `focus` as an object
+ # @param [Array<RDF::Statement>] arcs_out available statements to be matched having `focus` as a subject
+ # @param [Integer] depth for logging
+ # @param [Hash{Symbol => Object}] options
+ # Other, operand-specific options
+ # @return [Boolean] Returning `false` results in {ShEx::NotSatisfied} exception
+ def enter(**options)
+ if implementation = schema.extensions[operands.first.to_s]
+ implementation.enter(code: operands[0], expression: parent, **options)
+ end
+ end
+
+ #
# The evaluation semActsSatisfied on a list of SemActs returns success or failure. The evaluation of an individual SemAct is implementation-dependent.
- # @param [Array<RDF::Statement>] statements
+ #
+ # In addition to standard arguments `satsisfies` arguments, the current `matched` and `unmatched` statements may be passed. Additionally, all sub-classes of `Operator` have available `parent`, and `schema` accessors, which allows access to the operands of the parent, for example.
+ #
+ # @param [Object] focus (ignored)
+ # @param [Array<RDF::Statement>] matched matched statements
+ # @param [Array<RDF::Statement>] unmatched unmatched statements
# @return [Boolean] `true` if satisfied, `false` if it does not apply
# @raise [ShEx::NotSatisfied] if not satisfied
- def satisfies?(statements)
- # FIXME: should have a registry
- case operands.first.to_s
- when "http://shex.io/extensions/Test/"
- str = if md = /^ *(fail|print) *\( *(?:(\"(?:[^\\"]|\\")*\")|([spo])) *\) *$/.match(operands[1].to_s)
- md[2] || case md[3]
- when 's' then statements.first.subject
- when 'p' then statements.first.predicate
- when 'o' then statements.first.object
- else statements.first.to_sxp
- end.to_s
- else
- statements.empty? ? 'no statement' : statements.first.to_sxp
+ def satisfies?(focus, matched: [], unmatched: [], depth: 0)
+ if implementation = schema.extensions[operands.first.to_s]
+ if matched.empty?
+ implementation.visit(code: operands[1],
+ expression: parent,
+ depth: depth) ||
+ not_satisfied("SemAct failed", unmatched: unmatched)
end
- $stdout.puts str
- status str
- not_satisfied "fail" if md && md[1] == 'fail'
- true
+ matched.all? do |statement|
+ implementation.visit(code: operands[1],
+ matched: statement,
+ expression: parent,
+ depth: depth)
+ end || not_satisfied("SemAct failed", matched: matched, unmatched: unmatched)
else
- status("unknown SemAct name #{operands.first}") {"expression: #{self.to_sxp}"}
+ status("unknown SemAct name #{operands.first}", depth: depth) {"expression: #{self.to_sxp}"}
false
+ end
+ end
+
+ ##
+ # Called on exit from containing {ShEx::TripleExpression}
+ #
+ # @param [String] code
+ # @param [Array<RDF::Statement>] matched statements matched by this expression
+ # @param [Array<RDF::Statement>] unmatched statements considered, but not matched by this expression
+ # @param [ShEx::Algebra::TripleExpression] expression containing this semantic act
+ # @param [Integer] depth for logging
+ # @param [Hash{Symbol => Object}] options
+ # Other, operand-specific options
+ # @return [void]
+ def exit(code: nil, matched: [], unmatched: [], depth: 0, **options)
+ if implementation = schema.extensions[operands.first.to_s]
+ implementation.exit(code: operands[1],
+ matched: matched,
+ unmatched: unmatched,
+ expresssion: parent,
+ depth: depth)
end
end
# Does This operator is SemAct
def semact?; true; end