lib/rley/parser/parse_forest_builder.rb in rley-0.3.09 vs lib/rley/parser/parse_forest_builder.rb in rley-0.3.10

- old
+ new

@@ -27,11 +27,11 @@ attr_reader(:last_visitee) # A hash with pairs of the form: visited parse entry => forest node attr_reader(:entry2node) - # A hash with pairs of the form: + # A hash with pairs of the form: # parent end entry => path to alternative node # This is needed for synchronizing backtracking attr_reader(:entry2path_to_alt) def initialize(theTokens) @@ -87,27 +87,27 @@ # puts "Current parent #{curr_parent.to_string(0)}" # puts "Antecedent index #{antecedent_index}" when :revisit - # Retrieve the already existing node corresponding + # Retrieve the already existing node corresponding # to re-visited entry popular = @entry2node[anEntry] - + # Share with parent (if needed)... - children = curr_parent.subnodes + children = curr_parent.subnodes curr_parent.add_subnode(popular) unless children.include? popular else raise NotImplementedError end end def process_item_entry(anEvent, anEntry, anIndex) case anEvent - when :visit + when :visit if anEntry.exit_entry? # Previous entry was an end entry (X. pattern) # Does the previous entry have multiple antecedent? if last_visitee.end_entry? && last_visitee.antecedents.size > 1 # Store current path for later backtracking @@ -117,21 +117,21 @@ curr_parent.refinement = :or create_alternative_node(anEntry) end end - + # Does this entry have multiple antecedent? if anEntry.antecedents.size > 1 # Store current path for later backtracking # puts "Store backtrack context #{anEntry}" # puts "path [#{curr_path.map{|e|e.to_string(0)}.join(', ')}]" entry2path_to_alt[anEntry] = curr_path.dup # curr_parent.refinement = :or create_alternative_node(anEntry) - end + end # Retrieve the grammar symbol before the dot (if any) prev_symbol = anEntry.prev_symbol case prev_symbol when Syntax::Terminal @@ -144,21 +144,21 @@ # ... without changing current path create_epsilon_node(anEntry, anIndex) end curr_path.pop if curr_parent.kind_of?(SPPF::AlternativeNode) end - + when :backtrack # Restore path @curr_path = entry2path_to_alt[anEntry].dup # puts "Special restore path [#{curr_path.map{|e|e.to_string(0)}.join(', ')}]" antecedent_index = curr_parent.subnodes.size # puts "Current parent #{curr_parent.to_string(0)}" # puts "Antecedent index #{antecedent_index}" - - create_alternative_node(anEntry) - + + create_alternative_node(anEntry) + when :revisit # Retrieve the grammar symbol before the dot (if any) prev_symbol = anEntry.prev_symbol case prev_symbol when Syntax::Terminal @@ -170,11 +170,11 @@ # Empty rhs => create an epsilon node ... # ... without changing current path create_epsilon_node(anEntry, anIndex) end curr_path.pop if curr_parent.kind_of?(SPPF::AlternativeNode) - end + end end end # Create an empty parse forest def create_forest(aRootNode) @@ -185,12 +185,12 @@ # Factory method. Build and return an SPPF non-terminal node. def create_non_terminal_node(anEntry, aRange, nonTSymb = nil) non_terminal = nonTSymb.nil? ? anEntry.vertex.non_terminal : nonTSymb new_node = Rley::SPPF::NonTerminalNode.new(non_terminal, aRange) entry2node[anEntry] = new_node - # puts "FOREST ADD #{curr_parent.key if curr_parent}/#{new_node.key}" add_subnode(new_node) + # puts "FOREST ADD #{curr_parent.key if curr_parent}/#{new_node.key}" return new_node end @@ -198,10 +198,11 @@ def create_alternative_node(anEntry) vertex = anEntry.vertex range = curr_parent.range alternative = Rley::SPPF::AlternativeNode.new(vertex, range) add_subnode(alternative) + forest.is_ambiguous = true # puts "FOREST ADD #{alternative.key}" return alternative end @@ -229,16 +230,16 @@ end # Add the given node if not yet present in parse forest def add_node_to_forest(aNode) key_node = aNode.key - if forest.include?(key_node) - new_node = forest.key2node[key_node] - else - new_node = aNode - forest.key2node[key_node] = new_node - # puts "FOREST ADD #{key_node}" - end + if forest.include?(key_node) + new_node = forest.key2node[key_node] + else + new_node = aNode + forest.key2node[key_node] = new_node + # puts "FOREST ADD #{key_node}" + end add_subnode(new_node, false) return new_node end