Class: Rule
- Inherits:
-
Object
- Object
- Rule
- Defined in:
- lib/cofgratx/cfg/rule.rb
Instance Attribute Summary collapse
-
#rule ⇒ Object
readonly
Returns the value of attribute rule.
-
#translation ⇒ Object
readonly
Returns the value of attribute translation.
-
#translation_error_message ⇒ Object
readonly
Returns the value of attribute translation_error_message.
Instance Method Summary collapse
- #extract(candidate, translate_non_terminals = false) ⇒ Object
-
#initialize(subrules = [], translations = []) ⇒ Rule
constructor
A new instance of Rule.
- #match?(candidate) ⇒ Boolean
- #set_rule(*rule) ⇒ Object
- #set_translation(*translation) ⇒ Object
- #translate(candidate) ⇒ Object
- #valid_translation? ⇒ Boolean
Constructor Details
#initialize(subrules = [], translations = []) ⇒ Rule
Returns a new instance of Rule.
4 5 6 7 8 |
# File 'lib/cofgratx/cfg/rule.rb', line 4 def initialize subrules = [], translations = [] = nil @rule = set_rule subrules @translation = set_translation translations end |
Instance Attribute Details
#rule ⇒ Object (readonly)
Returns the value of attribute rule.
2 3 4 |
# File 'lib/cofgratx/cfg/rule.rb', line 2 def rule @rule end |
#translation ⇒ Object (readonly)
Returns the value of attribute translation.
2 3 4 |
# File 'lib/cofgratx/cfg/rule.rb', line 2 def translation @translation end |
#translation_error_message ⇒ Object (readonly)
Returns the value of attribute translation_error_message.
2 3 4 |
# File 'lib/cofgratx/cfg/rule.rb', line 2 def end |
Instance Method Details
#extract(candidate, translate_non_terminals = false) ⇒ Object
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/cofgratx/cfg/rule.rb', line 58 def extract candidate, translate_non_terminals = false working_matches = [ ["",candidate.dup,[[]]] ] @rule.each do |subrule| surviving_matches = [] working_matches.each do |current_match, working_candidate, current_set| if subrule.class == Repetition surviving_matches.concat extract_repetition_character subrule, current_match.dup, deep_clone_a_set(current_set), working_candidate.dup, translate_non_terminals elsif subrule.class == Terminal match, working_candidate = subrule.extract working_candidate if match current_set.first << match surviving_matches << [ current_match + match, working_candidate.dup, deep_clone_a_set(current_set) ] end elsif subrule.class == NonTerminal matches = if translate_non_terminals translations = subrule.translate(working_candidate).select{|tx| tx[0]} translations.map{|tx| tx[2] = deep_clone_a_set(current_set); tx[2].first << tx[0].dup; tx } translations else subrule.extract(working_candidate) end if matches.size > 0 and matches.first[0] surviving_matches.concat matches end else raise "Rule is corrupt, found a bad subrule:#{subrule} with class:#{subrule.class}" end end working_matches = surviving_matches.dup end return [ [nil,candidate,[[]]] ] if working_matches.size == 0 working_matches end |
#match?(candidate) ⇒ Boolean
54 55 56 |
# File 'lib/cofgratx/cfg/rule.rb', line 54 def match? candidate extract(candidate).first[0] != nil end |
#set_rule(*rule) ⇒ Object
10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/cofgratx/cfg/rule.rb', line 10 def set_rule *rule good_parts = [] rule.flatten(2).each do |part| if ! [Repetition, Terminal, NonTerminal].include? part.class raise ArgumentError.new("expected Terminal, NonTerminal or Repetition; got #{part.class.name}") elsif part.class == Repetition and good_parts.size == 0 raise RuleError.new("cannot have repetition as the first part of the rule") elsif good_parts.last.class == Repetition raise RuleError.new("nothing can follow the repetition") end good_parts << part end @rule = good_parts end |
#set_translation(*translation) ⇒ Object
25 26 27 28 29 30 31 32 33 34 |
# File 'lib/cofgratx/cfg/rule.rb', line 25 def set_translation *translation good_parts = [] translation.flatten.each do |part| if ! [Fixnum, String, TranslationRepetitionSet].include? part.class raise ArgumentError.new("expected Fixnum, String or TranslationRepetitionSet; got #{part.class.name}") end good_parts << part end @translation = good_parts end |
#translate(candidate) ⇒ Object
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/cofgratx/cfg/rule.rb', line 96 def translate candidate matches = extract candidate, true translations = matches.inject([]) do |txs, match| current_match, working_candidate, current_set = match next txs << [nil, candidate] unless current_match next txs << [current_set.join(""), working_candidate.dup] unless @translation.size > 0 current_translation = "" @translation.each do |sub_translation| if sub_translation.class == TranslationRepetitionSet current_set[(sub_translation.offset-1)..-1].to_a.each do |current| sub_translation.translations.each do |translation| current_translation += translation_helper current, translation end end else current_translation += translation_helper current_set.first, sub_translation end end txs << [current_translation, working_candidate] end return [ [nil, candidate] ] unless translations.size > 0 translations end |
#valid_translation? ⇒ Boolean
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/cofgratx/cfg/rule.rb', line 36 def valid_translation? @translation.each do |part| if part.class == TranslationRepetitionSet if @rule.last.class != Repetition = "rule does not contain repetition" return false elsif part.translations.select{|tx| tx.class == Fixnum and tx > @rule.size}.count > 0 = "rule contains fewer parts than the TranslationRepetitionSet has for a translation: #{part.translations.inspect}" return false end elsif part.class == Fixnum = "rule contains fewer parts than translation number: #{part.inspect}" return false if part > @rule.size end end true end |