Add p_parse_*() API for each start rule
This commit is contained in:
1 parent
87890a3d77
commit
5187cff24d
6 files changed
+55
-10
No files matched your search
@@ -71,14 +71,15 @@ class Propane
|
||||
end
|
||||
tokens_by_name[token.name] = token
|
||||
end
|
||||
# Check for user start rules.
|
||||
@grammar.start_rules.each_with_index do |start_rule, i|
|
||||
# Create real start rule(s).
|
||||
real_start_rules = @grammar.start_rules.map do |start_rule|
|
||||
unless @grammar.rules.find {|rule| rule.name == start_rule}
|
||||
raise Error.new("Start rule `#{start_rule}` not found")
|
||||
end
|
||||
# Add "real" start rule.
|
||||
@grammar.rules.unshift(Rule.new("$#{start_rule}", [start_rule, "$EOF"], nil, nil, nil))
|
||||
Rule.new("$#{start_rule}", [start_rule, "$EOF"], nil, nil, nil)
|
||||
end
|
||||
# Add real start rules before user-given rules.
|
||||
@grammar.rules = real_start_rules + @grammar.rules
|
||||
# Generate and add rules for optional components.
|
||||
generate_optional_component_rules!(tokens_by_name)
|
||||
# Build rule sets.
|
||||
|
||||
@@ -11,7 +11,7 @@ class Propane
|
||||
attr_reader :free_token_node
|
||||
attr_reader :modulename
|
||||
attr_reader :patterns
|
||||
attr_reader :rules
|
||||
attr_accessor :rules
|
||||
attr_reader :start_rules
|
||||
attr_reader :tokens
|
||||
attr_reader :code_blocks
|
||||
|
||||
+12
-3
@@ -16,11 +16,20 @@ class Propane
|
||||
@warnings = Set.new
|
||||
@errors = Set.new
|
||||
@options = options
|
||||
start_item = Item.new(grammar.rules.first, 0)
|
||||
eval_item_sets = Set[ItemSet.new([start_item])]
|
||||
start_items = grammar.rules[0...grammar.start_rules.length].map do |start_rule|
|
||||
Item.new(start_rule, 0)
|
||||
end
|
||||
start_item_sets = start_items.map {|item| ItemSet.new([item])}
|
||||
eval_item_sets = Set[*start_item_sets]
|
||||
|
||||
while eval_item_sets.size > 0
|
||||
item_set = eval_item_sets.first
|
||||
item_set =
|
||||
if start_item_sets.size > 0
|
||||
# Ensure we evaluate start_item_sets first in order
|
||||
start_item_sets.slice!(0)
|
||||
else
|
||||
eval_item_sets.first
|
||||
end
|
||||
eval_item_sets.delete(item_set)
|
||||
unless @item_sets_set.include?(item_set)
|
||||
item_set.id = @item_sets.size
|
||||
|
||||
Reference in new issue
Block a user