Class: Kotoshu::Readers::CompoundRule
- Inherits:
-
Object
- Object
- Kotoshu::Readers::CompoundRule
- Defined in:
- lib/kotoshu/readers/aff_data.rb
Overview
Compound rule pattern.
Instance Attribute Summary collapse
-
#flags ⇒ Set<String>
Flags in this rule.
-
#partial_re ⇒ Regexp
Compiled regex for prefix matching.
-
#re ⇒ Regexp
Compiled regex for full matching.
-
#text ⇒ String
The rule text.
Instance Method Summary collapse
-
#fullmatch(flag_sets) ⇒ Boolean
Check if flag sets fully match this rule.
-
#initialize(text) ⇒ CompoundRule
constructor
Create a new compound rule.
-
#partial_match(flag_sets) ⇒ Boolean
Check if flag sets form a valid prefix of this rule.
Constructor Details
#initialize(text) ⇒ CompoundRule
Create a new compound rule.
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
# File 'lib/kotoshu/readers/aff_data.rb', line 226 def initialize(text) @text = text # Parse flags from rule text if text.include?('(') @flags = text.scan(/\((.+?)\)/).flatten.to_set parts = text.scan(/\([^*?]+?\)[*?]?/) else @flags = text.gsub(/[*?]/, '').chars.to_set # Handle ) as a flag character (used in sv dictionaries) parts = text.gsub(/(?<=[^*?])\)/, '\\)').gsub(/([^*?])/, '\1') .scan(/[^*?][*?]?/) end # Full-match regex: the entire flag-combination string must match. @re = Regexp.new("\\A#{parts.join}\\z") # Partial-match regex: any prefix of the rule is accepted. Built # by making each trailing part optional, from the end backwards: # parts ["A","B","C"] → "A(B(C?)?)?" which matches "A", "AB", "ABC". @partial_re = if parts.empty? Regexp.new('\\A\\z') else Regexp.new("\\A#{build_partial(parts)}\\z") end end |
Instance Attribute Details
#flags ⇒ Set<String>
Flags in this rule
220 221 222 |
# File 'lib/kotoshu/readers/aff_data.rb', line 220 def flags @flags end |
#partial_re ⇒ Regexp
Compiled regex for prefix matching
220 221 222 |
# File 'lib/kotoshu/readers/aff_data.rb', line 220 def partial_re @partial_re end |
#re ⇒ Regexp
Compiled regex for full matching
220 221 222 |
# File 'lib/kotoshu/readers/aff_data.rb', line 220 def re @re end |
#text ⇒ String
The rule text
220 221 222 |
# File 'lib/kotoshu/readers/aff_data.rb', line 220 def text @text end |
Instance Method Details
#fullmatch(flag_sets) ⇒ Boolean
Check if flag sets fully match this rule.
256 257 258 259 260 261 262 263 |
# File 'lib/kotoshu/readers/aff_data.rb', line 256 def fullmatch(flag_sets) relevant_flags = flag_sets.map { |f| @flags.intersection(f).to_a } return false if relevant_flags.empty? || relevant_flags.any?(&:empty?) relevant_flags[0].product(*relevant_flags[1..]).any? do |fc| @re.match?(fc.join) end end |
#partial_match(flag_sets) ⇒ Boolean
Check if flag sets form a valid prefix of this rule.
Used during compounds_by_rules recursion to prune branches that can never lead to a full match.
272 273 274 275 276 277 278 279 |
# File 'lib/kotoshu/readers/aff_data.rb', line 272 def partial_match(flag_sets) relevant_flags = flag_sets.map { |f| @flags.intersection(f).to_a } return false if relevant_flags.empty? || relevant_flags.any?(&:empty?) relevant_flags[0].product(*relevant_flags[1..]).any? do |fc| @partial_re.match?(fc.join) end end |