Move RuleSet::Patern to top-level Rule class

This commit is contained in:
Josh Holtrop 2022-06-04 17:49:36 -04:00
parent 7598c589fe
commit 34eb1370ff
5 changed files with 44 additions and 40 deletions

View File

@ -14,6 +14,7 @@ require_relative "propane/regex"
require_relative "propane/regex/nfa" require_relative "propane/regex/nfa"
require_relative "propane/regex/unit" require_relative "propane/regex/unit"
require_relative "propane/rule_set" require_relative "propane/rule_set"
require_relative "propane/rule"
require_relative "propane/token" require_relative "propane/token"
require_relative "propane/version" require_relative "propane/version"
@ -86,7 +87,7 @@ class Propane
rule_name, components, code = $1, $2, $3 rule_name, components, code = $1, $2, $3
components = components.strip.split(/\s+/) components = components.strip.split(/\s+/)
@rule_sets[rule_name] ||= RuleSet.new(rule_name, @rule_sets.size) @rule_sets[rule_name] ||= RuleSet.new(rule_name, @rule_sets.size)
@rule_sets[rule_name].add_pattern(components, code) @rule_sets[rule_name].add_rule(components, code)
else else
if input.size > 25 if input.size > 25
input = input.slice(0..20) + "..." input = input.slice(0..20) + "..."
@ -105,7 +106,7 @@ class Propane
raise Error.new("Start rule not found") raise Error.new("Start rule not found")
end end
@rule_sets.each do |rule_name, rule_set| @rule_sets.each do |rule_name, rule_set|
rule_set.patterns.each do |rule| rule_set.rules.each do |rule|
rule.components.map! do |component| rule.components.map! do |component|
if @tokens[component] if @tokens[component]
@tokens[component] @tokens[component]

View File

@ -2,13 +2,13 @@ class Propane
class Parser class Parser
def initialize(tokens, rules) def initialize(tokens, rule_sets)
@token_eof = Token.new("$", nil, TOKEN_EOF) @token_eof = Token.new("$", nil, TOKEN_EOF)
@item_sets = [] @item_sets = []
@item_sets_set = {} @item_sets_set = {}
start_items = rules["Start"].patterns.map do |pattern| start_items = rule_sets["Start"].rules.map do |rule|
pattern.components << @token_eof rule.components << @token_eof
Item.new(pattern, 0) Item.new(rule, 0)
end end
eval_item_sets = Set.new eval_item_sets = Set.new
eval_item_sets << ItemSet.new(start_items) eval_item_sets << ItemSet.new(start_items)

View File

@ -3,24 +3,24 @@ class Propane
class Item class Item
attr_reader :pattern attr_reader :rule
attr_reader :position attr_reader :position
def initialize(pattern, position) def initialize(rule, position)
@pattern = pattern @rule = rule
@position = position @position = position
end end
def next_component def next_component
@pattern.components[@position] @rule.components[@position]
end end
def hash def hash
[@pattern, @position].hash [@rule, @position].hash
end end
def ==(other) def ==(other)
@pattern == other.pattern && @position == other.position @rule == other.rule && @position == other.position
end end
def eql?(other) def eql?(other)
@ -28,9 +28,9 @@ class Propane
end end
def closed_items def closed_items
if @pattern.components[@position].is_a?(RuleSet) if @rule.components[@position].is_a?(RuleSet)
@pattern.components[@position].patterns.map do |pattern| @rule.components[@position].rules.map do |rule|
Item.new(pattern, 0) Item.new(rule, 0)
end end
else else
[] []
@ -38,7 +38,7 @@ class Propane
end end
def follow_symbol def follow_symbol
@pattern.components[@position] @rule.components[@position]
end end
def followed_by?(symbol) def followed_by?(symbol)
@ -46,21 +46,21 @@ class Propane
end end
def next_position def next_position
Item.new(@pattern, @position + 1) Item.new(@rule, @position + 1)
end end
def to_s def to_s
parts = [] parts = []
@pattern.components.each_with_index do |symbol, index| @rule.components.each_with_index do |symbol, index|
if @position == index if @position == index
parts << "." parts << "."
end end
parts << symbol.name parts << symbol.name
end end
if @position == @pattern.components.size if @position == @rule.components.size
parts << "." parts << "."
end end
"#{@pattern.rule_set.name} -> #{parts.join(" ")}" "#{@rule.name} -> #{parts.join(" ")}"
end end
end end

19
lib/propane/rule.rb Normal file
View File

@ -0,0 +1,19 @@
class Propane
class Rule
attr_reader :name
attr_reader :components
attr_reader :code
def initialize(name, components, code)
@name = name
@components = components
@code = code
end
end
end

View File

@ -2,36 +2,20 @@ class Propane
class RuleSet class RuleSet
class Pattern
attr_reader :rule_set
attr_reader :components
attr_reader :code
def initialize(rule_set, components, code)
@rule_set = rule_set
@components = components
@code = code
end
end
attr_reader :id attr_reader :id
attr_reader :name attr_reader :name
attr_reader :patterns attr_reader :rules
def initialize(name, id) def initialize(name, id)
@name = name @name = name
@id = id @id = id
@patterns = [] @rules = []
end end
def add_pattern(components, code) def add_rule(components, code)
@patterns << Pattern.new(self, components, code) @rules << Rule.new(@name, components, code)
end end
end end