Class: RedParse::RuleSet
- Inherits:
-
Object
- Object
- RedParse::RuleSet
- Defined in:
- lib/redparse/compile.rb
Constant Summary collapse
- @@FFS_TABLE =
[nil]
Instance Method Summary collapse
- #[](i) ⇒ Object
- #each_rule(mask = @maxmask) ⇒ Object
-
#initialize(rules) ⇒ RuleSet
constructor
A new instance of RuleSet.
- #juice(m) ⇒ Object
-
#LEFT ⇒ Object
just the left side (the stack/lookahead matchers).
-
#LEFT_NO_LOOKING ⇒ Object
remove lookahead and lookback decoration.
- #LOOKAHEAD_CLASSES(rule) ⇒ Object
- #mask2rules(mask) ⇒ Object
- #rb_ffs(mask) ⇒ Object
- #rules2mask(rules) ⇒ Object
- #sc_juice(m) ⇒ Object
-
#STACKABLE_CLASSES ⇒ Object
all classes mentioned in rules, on left and right sides.
- #TOS_CLASSES(rule) ⇒ Object
Constructor Details
#initialize(rules) ⇒ RuleSet
Returns a new instance of RuleSet.
43 44 45 46 47 48 49 |
# File 'lib/redparse/compile.rb', line 43 def initialize(rules) @rules=rules.reverse #rule order must be reversed relative to the usual RedParse rule #order... merely so that ffs can work right. @maxmask=(1<<@rules.size)-1 @subclasses_of=child_relations_among(*STACKABLE_CLASSES()) end |
Instance Method Details
#[](i) ⇒ Object
241 242 243 |
# File 'lib/redparse/compile.rb', line 241 def [](i) @rules[i] end |
#each_rule(mask = @maxmask) ⇒ Object
76 77 78 79 80 |
# File 'lib/redparse/compile.rb', line 76 def each_rule(mask=-1) @rules.each_with_index{|r,i| yield r,i if mask&(1<<i) } end |
#juice(m) ⇒ Object
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/redparse/compile.rb', line 180 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 |
#LEFT ⇒ Object
just the left side (the stack/lookahead matchers)
150 151 152 |
# File 'lib/redparse/compile.rb', line 150 def LEFT @rules.map{|r| r.left.subregs }.flatten end |
#LEFT_NO_LOOKING ⇒ Object
remove lookahead and lookback decoration
155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/redparse/compile.rb', line 155 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
221 222 223 224 225 226 |
# File 'lib/redparse/compile.rb', line 221 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 |
#mask2rules(mask) ⇒ Object
59 60 61 62 63 64 65 |
# File 'lib/redparse/compile.rb', line 59 def mask2rules(mask) rules=[] @rules.each_with_index{|r,i| rules<<r if mask&(1<<i) } return rules end |
#rb_ffs(mask) ⇒ Object
95 96 97 98 99 100 101 102 103 104 |
# File 'lib/redparse/compile.rb', line 95 def rb_ffs(mask) chunks=0 until mask.zero? result=@@FFS_TABLE[mask&0xFF] return result+(chunks<<3) if result chunks+=1 mask>>=8 end return 0 end |
#rules2mask(rules) ⇒ Object
51 52 53 54 55 56 57 |
# File 'lib/redparse/compile.rb', line 51 def rules2mask(rules) mask=0 @rules.each_with_index{|r,i| mask |= 1<<i if rules.include? r } return mask end |
#sc_juice(m) ⇒ Object
208 209 210 211 212 213 214 215 216 217 218 219 |
# File 'lib/redparse/compile.rb', line 208 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_CLASSES ⇒ Object
all classes mentioned in rules, on left and right sides
168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/redparse/compile.rb', line 168 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
228 229 230 231 232 233 234 235 236 237 238 239 |
# File 'lib/redparse/compile.rb', line 228 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 |