module RedParse::StackableClasses

Public Instance Methods

LEFT() click to toggle source

just the left side (the stack/lookahead matchers)

# File lib/redparse/stackableclasses.rb, line 22
def LEFT
  @rules.map{|r| r.left.subregs }.flatten
end
LEFT_NO_LOOKING() click to toggle source

remove lookahead and lookback decoration

# File lib/redparse/stackableclasses.rb, line 27
def LEFT_NO_LOOKING
l=LEFT()
l.map!{|m|
  case m #
  when Reg::LookAhead,Reg::LookBack; m.subregs[0]
  when Proc; []
  else m #
  end #
}
l
end
LOOKAHEAD_CLASSES(rule) click to toggle source
# File lib/redparse/stackableclasses.rb, line 93
def LOOKAHEAD_CLASSES rule
  last=rule.left.subregs.last
  return STACKABLE_CLASSES() unless Reg::LookAhead===last
  la= last.subregs[0]
  return juice(la).flatten.compact
end
STACKABLE_CLASSES() click to toggle source

all classes mentioned in rules, on left and right sides

# File lib/redparse/stackableclasses.rb, line 40
def STACKABLE_CLASSES #
  return @sc_result unless  @sc_result.nil?
  @sc_result=false
  l=LEFT_NO_LOOKING()
  l=l.map{|lm| sc_juice lm}.flatten.compact
  r=  @rules.map{|rr| rr.right }.grep(Class) #classes in productions
  result=l+r
  @sc_result=result.grep(Class).uniq
  fail if @sc_result.empty?
  return @sc_result
end
TOS_CLASSES(rule) click to toggle source
# File lib/redparse/stackableclasses.rb, line 100
def TOS_CLASSES rule
  i=-1
  mats=rule.left.subregs
  m=mats[i]
  m=mats[i-=1] if Reg::LookAhead===m || Proc===m
  result=[]
  while Reg::Repeat===m and m.times.min.zero?
    result<<juice(m.subregs[0])
    m=mats[i-=1]
  end
  return (result+juice(m)).flatten.compact
end
juice(m) click to toggle source
# File lib/redparse/stackableclasses.rb, line 52
def juice(m)
  case m  #
  when Class;
    return [m] unless @subclasses_of
    result=[m]  # and subclasses too
    i=0
    while item=result[i]
      #p item
      result.concat @subclasses_of[item]
      i += 1
    end
    result
  when String,Regexp; juice(RedParse.KW(m))
  when Reg::And; m.subregs.map{|x| juice(x).flatten.compact}.inject{|sum,rr| sum&rr}
  when Reg::Or; m.subregs.map( &method(:juice) )
  when Reg::Not;
    m=m.subregs[0]
    if Class===m or (Reg::Or===m  and
         m.subregs.inject{|sum,x| sum && (Class===x) })
      j=juice(m)
      STACKABLE_CLASSES()-j.flatten.compact rescue j
    else
      STACKABLE_CLASSES()
    end
  else STACKABLE_CLASSES()
  end
end
sc_juice(m) click to toggle source
# File lib/redparse/stackableclasses.rb, line 80
    def sc_juice(m)
      case m #
      when Class; [m]
      when String,Regexp; juice(RedParse.KW(m))
#      when String,Regexp; [KeywordToken]
      when Reg::And; m.subregs.map{|x| sc_juice(x)}.compact.map{|x| x.flatten.compact}.inject{|sum,rr| sum&rr }
      when Reg::Or; m.subregs.map( &method(:sc_juice) )
      when Reg::Not; sc_juice(m.subregs[0])
      when Reg::LookAhead, Reg::LookBack; sc_juice(m.subregs[0])
      else []
      end
    end