class Interscript::Node::Rule::Sub
Attributes
after[RW]
before[RW]
from[RW]
not_after[RW]
not_before[RW]
priority[RW]
reverse_after[RW]
reverse_before[RW]
reverse_not_after[RW]
reverse_not_before[RW]
reverse_run[RW]
to[RW]
Public Class Methods
new(from, to, before: nil, not_before: nil, after: nil, not_after: nil, priority: nil, reverse_run: nil)
click to toggle source
# File lib/interscript/node/rule/sub.rb, line 8 def initialize (from, to, before: nil, not_before: nil, after: nil, not_after: nil, priority: nil, reverse_run: nil) self.from = Interscript::Node::Item.try_convert from if to == :upcase self.to = :upcase elsif to == :downcase self.to = :downcase else self.to = Interscript::Node::Item.try_convert to end self.priority = priority #raise TypeError, "Can't supply both before and not_before" if before && not_before #raise TypeError, "Can't supply both after and not_after" if after && not_after self.reverse_run = reverse_run self.before = Interscript::Node::Item.try_convert(before) if before self.after = Interscript::Node::Item.try_convert(after) if after self.not_before = Interscript::Node::Item.try_convert(not_before) if not_before self.not_after = Interscript::Node::Item.try_convert(not_after) if not_after end
Public Instance Methods
==(other)
click to toggle source
Calls superclass method
Interscript::Node::Rule#==
# File lib/interscript/node/rule/sub.rb, line 199 def ==(other) super && self.from == other.from && self.to == other.to && self.before == other.before && self.after == other.after && self.not_before == other.not_before && self.not_after == other.not_after && self.priority == other.priority end
has_assertions?()
click to toggle source
# File lib/interscript/node/rule/sub.rb, line 99 def has_assertions? !!(before || not_before || not_after || after) end
inspect()
click to toggle source
# File lib/interscript/node/rule/sub.rb, line 210 def inspect out = "sub " params = [] params << @from.inspect if Symbol === @to params << @to.to_s else params << @to.inspect end params << "reverse_run: #{@reverse_run.inspect}" unless @reverse_run.nil? params << "before: #{@before.inspect}" if @before params << "after: #{@after.inspect}" if @after params << "not_before: #{@not_before.inspect}" if @not_before params << "not_after: #{@not_after.inspect}" if @not_after params << "priority: #{@priority.inspect}" if @priority out << params.join(", ") end
max_length()
click to toggle source
# File lib/interscript/node/rule/sub.rb, line 34 def max_length len = self.from.max_length len += self.before.max_length if self.before len += self.after.max_length if self.after len += self.not_before.max_length if self.not_before len += self.not_after.max_length if self.not_after len += self.priority if self.priority len end
reverse()
click to toggle source
# File lib/interscript/node/rule/sub.rb, line 67 def reverse if to == :upcase xfrom = from.downcase xto = :downcase elsif to == :downcase xfrom = from.upcase xto = :upcase else xto, xfrom = reverse_transfer(from, to) end # A special case: sub "a", "" shouldn't be present in a reverse map rrun = self.reverse_run.nil? ? nil : !self.reverse_run if rrun.nil? && !has_assertions? && (xfrom == "" || (Interscript::Node::Item::String === xfrom && xfrom.data == '') || (Interscript::Node::Item::Alias === xfrom && xfrom.name == :none) ) rrun = true end Interscript::Node::Rule::Sub.new(xfrom, xto, before: before, after: after, not_before: not_before, not_after: not_after, reverse_run: rrun, priority: priority ? -priority : nil ) end
reverse_transfer(from, to)
click to toggle source
Attempt to transfer some references to boundary/line_begin around. Those in general should go into before/after clauses, but for now let's try to get the best compatibility possible. Also, CaptureGroup, CaptureRef need to be shifted around
# File lib/interscript/node/rule/sub.rb, line 107 def reverse_transfer from, to # This part is about moving initial and final boundary like aliases case from when Interscript::Node::Item::Group first = from.children.first last = from.children.last if Interscript::Node::Item::Alias === first && first.boundary_like? out = Interscript::Node::Item::Group.new + first + to to = out.compact from = from.dup.tap do |i| i.children = i.children[1..-1] end.compact end if Interscript::Node::Item::Alias === last && last.boundary_like? out = Interscript::Node::Item::Group.new + to + last to = out.compact from = from.dup.tap do |i| i.children = i.children[0..-2] end.compact end when Interscript::Node::Item::Alias if from.boundary_like? to = if from.name.to_s.end_with? "_end" Interscript::Node::Item::Group.new + to + from else Interscript::Node::Item::Group.new + from + to end from = Interscript::Node::Item::Alias.new(:none) end end # This part is about moving backreferences state = {left:[], right:[]} from = reverse_transfer_visit(from, :from, state) to = reverse_transfer_visit(to, :to, state) [from, to] end
to_hash()
click to toggle source
# File lib/interscript/node/rule/sub.rb, line 44 def to_hash puts self.from.inspect if $DEBUG puts params.inspect if $DEBUG hash = { :class => self.class.to_s, :from => self.from.to_hash, :to => Symbol === self.to ? self.to : self.to.to_hash, :reverse_run => self.reverse_run, :before => self.before&.to_hash, :not_before => self.not_before&.to_hash, :after => self.after&.to_hash, :not_after => self.not_after&.to_hash, :priority => self.priority } hash[:before] = self.before&.to_hash if self.before hash[:not_before] = self.not_before&.to_hash if self.not_before hash[:after] = self.after&.to_hash if self.after hash[:not_after] = self.not_after&.to_hash if self.not_after hash[:priority] = self.priority if self.priority hash end
Private Instance Methods
reverse_transfer_visit(node, type, state)
click to toggle source
# File lib/interscript/node/rule/sub.rb, line 151 def reverse_transfer_visit(node, type, state) node = Interscript::Node::Item.try_convert(node) case node when Interscript::Node::Item::Alias if node.name == :kor_maybedash state[:left] << node Interscript::Node::Item::CaptureRef.new(state[:left].length) else node end when Interscript::Node::Item::String node when Interscript::Node::Item::Any if Array === node.value node.dup.tap do |i| i.value = i.value.map { |c| reverse_transfer_visit(c, type, state) } end else node end when Interscript::Node::Item::Group node.dup.tap do |i| i.children = i.children.map { |c| reverse_transfer_visit(c, type, state) } end when Interscript::Node::Item::Repeat node.dup.tap do |i| i.data = reverse_transfer_visit(i.data, type, state) end when Interscript::Node::Item::CaptureRef if type == :from node elsif state[:right][node.id] node else state[:right][node.id] = true state[:left][node.id - 1] or raise "Capture count doesn't match" end when Interscript::Node::Item::CaptureGroup state[:left] << node out = Interscript::Node::Item::CaptureRef.new(state[:left].length) reverse_transfer_visit(node.data, type, state) # Visit but don't care out else raise "Type #{node.class} unhandled!" end end