module Regexp::Expression::Shared
def self.included(mod)
def self.included(mod) mod.class_eval do extend Shared::ClassMethods attr_accessor :type, :token, :text, :ts, :te, :level, :set_level, :conditional_level, :options attr_reader :nesting_level, :quantifier end end
def ==(other)
def ==(other) other.class == self.class && other.to_s == to_s && other.options == options end
def base_length
def base_length to_s(:base).length end
def coded_offset
def coded_offset '@%d+%d' % offset end
def full_length
def full_length to_s.length end
def human_name
def human_name [token, type].compact.join(' ').tr('_', ' ') end
def init_from_token_and_options(token, options = {})
def init_from_token_and_options(token, options = {}) self.type = token.type self.token = token.token self.text = token.text self.ts = token.ts self.te = token.te self.level = token.level self.set_level = token.set_level self.conditional_level = token.conditional_level self.nesting_level = 0 self.options = options || {} end
def initialize_copy(orig)
def initialize_copy(orig) self.text = orig.text.dup if orig.text self.options = orig.options.dup if orig.options self.quantifier = orig.quantifier.clone if orig.quantifier super end
def is?(test_token, test_type = nil)
exp.is? :dot, [:meta, :escape]
# is it a :meta or :escape :dot
exp.is? :dot, :meta
# is it a :meta :dot
exp.is? :character, :set
# is it a :character and a :set
exp.is? :capture
# is it a :capture
exp.is? :* # always returns true
# Any expressions
test_type.
Test if this expression has the given test_token, and optionally a given
def is?(test_token, test_type = nil) return true if test_token === :* token == test_token and (test_type ? type?(test_type) : true) end
def nesting_level=(lvl)
def nesting_level=(lvl) @nesting_level = lvl quantifier && quantifier.nesting_level = lvl terminal? || each { |subexp| subexp.nesting_level = lvl + 1 } end
def offset
def offset [starts_at, full_length] end
def one_of?(scope, top = true)
exp.one_of?({meta: [:dot], set: :*})
# meta dots and any set tokens
exp.one_of?(:meta => [:dot, :alternation])
# meta dots and alternations
exp.one_of?(:meta => :*)
# any expression of type meta
exp.one_of?(:group)
# like exp.type?(:group)
exp.one_of?(:*) # always true
# any expression
expression.
from a hash, it will be checked against the token of the
type of the expression. If it's being called for a value
a symbol then it will always be checked against the
the level of the call. If one_of? is called directly with
. A symbol: matches the expression's token or type, depending on
evaluate the key's value.
case, when the scope is a hash, one_of? calls itself to
and the value is either a symbol or an array. In this
. A hash: Where the key is interpreted as the expression type
of the expression's token.
. An array: Interpreted as a set of tokens, tested for inclusion
A scope spec can be one of:
Test if this expression matches an entry in the given scope spec.
def one_of?(scope, top = true) case scope when Array scope.include?(:*) || scope.include?(token) when Hash if scope.has_key?(:*) test_type = scope.has_key?(type) ? type : :* one_of?(scope[test_type], false) else scope.has_key?(type) && one_of?(scope[type], false) end when Symbol scope.equal?(:*) || (top ? type?(scope) : is?(scope)) else raise ArgumentError, "Array, Hash, or Symbol expected, #{scope.class.name} given" end end
def optional?
def optional? quantified? && quantifier.min == 0 end
def parts
def parts [text.dup] end
def quantified?
def quantified? !quantifier.nil? end
def quantifier=(qtf)
def quantifier=(qtf) @quantifier = qtf @repetitions = nil # clear memoized value end
def quantifier_affix(expression_format)
def quantifier_affix(expression_format) quantifier.to_s if quantified? && expression_format != :base end
def starts_at
def starts_at ts end
def terminal?
def terminal? !respond_to?(:expressions) end
def to_s(format = :full)
def to_s(format = :full) "#{parts.join}#{quantifier_affix(format)}" end
def token_class
def token_class self.class.token_class end
def type?(test_type)
exp.type? [:set, :meta]
# is it a :set, or :meta
exp.type? :group
# is it a :group expression
a symbol or an array of symbols to check against the expression's type.
Test if this expression has the given test_type, which can be either
def type?(test_type) test_types = Array(test_type).map(&:to_sym) test_types.include?(:*) || test_types.include?(type) end