Module: RedParse::StackableClasses

Included in:
RuleSet
Defined in:
lib/redparse/stackableclasses.rb

Instance Method Summary collapse

Instance Method Details

#juice(m) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# 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

#LEFTObject

just the left side (the stack/lookahead matchers)



22
23
24
# File 'lib/redparse/stackableclasses.rb', line 22

def LEFT
  @rules.map{|r| r.left.subregs }.flatten
end

#LEFT_NO_LOOKINGObject

remove lookahead and lookback decoration



27
28
29
30
31
32
33
34
35
36
37
# 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) ⇒ Object



93
94
95
96
97
98
# 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

#sc_juice(m) ⇒ Object



80
81
82
83
84
85
86
87
88
89
90
91
# 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

#STACKABLE_CLASSESObject

all classes mentioned in rules, on left and right sides



40
41
42
43
44
45
46
47
48
49
50
# 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) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
111
# 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