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