From c42c3576a51ed0c6565145b4a0388a02ea414973 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Sun, 5 Jun 2022 15:16:41 -0400 Subject: [PATCH] Remove RuleSet creation from Grammar --- lib/propane/generator.rb | 33 +++++++++++++++++---------------- lib/propane/grammar.rb | 8 +++----- lib/propane/parser.rb | 4 ++-- lib/propane/rule_set.rb | 7 ++----- 4 files changed, 24 insertions(+), 28 deletions(-) diff --git a/lib/propane/generator.rb b/lib/propane/generator.rb index 0a7c5f2..11ab8c9 100644 --- a/lib/propane/generator.rb +++ b/lib/propane/generator.rb @@ -8,8 +8,6 @@ class Propane @log_file = log_file @classname = @grammar.classname || File.basename(output_file).sub(%r{[^a-zA-Z0-9].*}, "").capitalize process_grammar! - @lexer = Lexer.new(@grammar.tokens, @grammar.drop_tokens) - @parser = Parser.new(@grammar.rule_sets) end def generate @@ -30,27 +28,30 @@ class Propane end tokens_by_name[token.name] = token end - @grammar.rule_sets.each do |rule_name, rule_set| - if tokens_by_name.include?(rule_name) - raise Error.new("Rule name collides with token name #{rule_name.inspect}") + rule_sets = {} + @grammar.rules.each do |rule| + if tokens_by_name.include?(rule.name) + raise Error.new("Rule name collides with token name #{rule.name.inspect}") end + rule_sets[rule.name] ||= RuleSet.new(rule.name) + rule_sets[rule.name] << rule end - unless @grammar.rule_sets["Start"] + unless rule_sets["Start"] raise Error.new("Start rule not found") end - @grammar.rule_sets.each do |rule_name, rule_set| - rule_set.rules.each do |rule| - rule.components.map! do |component| - if tokens_by_name[component] - tokens_by_name[component] - elsif @grammar.rule_sets[component] - @grammar.rule_sets[component] - else - raise Error.new("Symbol #{component} not found") - end + @grammar.rules.each do |rule| + rule.components.map! do |component| + if tokens_by_name[component] + tokens_by_name[component] + elsif rule_sets[component] + rule_sets[component] + else + raise Error.new("Symbol #{component} not found") end end end + @lexer = Lexer.new(@grammar.tokens, @grammar.drop_tokens) + @parser = Parser.new(rule_sets["Start"]) end end diff --git a/lib/propane/grammar.rb b/lib/propane/grammar.rb index c0572a8..105f5df 100644 --- a/lib/propane/grammar.rb +++ b/lib/propane/grammar.rb @@ -5,13 +5,13 @@ class Propane attr_reader :classname attr_reader :drop_tokens attr_reader :modulename - attr_reader :rule_sets + attr_reader :rules attr_reader :tokens def initialize(input) @tokens = [] @drop_tokens = [] - @rule_sets = {} + @rules = [] input = input.gsub("\r\n", "\n") parse_grammar(input) end @@ -44,9 +44,7 @@ class Propane elsif sliced = input.slice!(/\A(\S+)\s*:\s*\[(.*?)\] <<\n(.*?)^>>\n/m) rule_name, components, code = $1, $2, $3 components = components.strip.split(/\s+/) - @rule_sets[rule_name] ||= RuleSet.new(rule_name, @rule_sets.size) - rule = Rule.new(rule_name, components, code, line_number) - @rule_sets[rule_name].add_rule(rule) + @rules << Rule.new(rule_name, components, code, line_number) else if input.size > 25 input = input.slice(0..20) + "..." diff --git a/lib/propane/parser.rb b/lib/propane/parser.rb index be5c70c..172d936 100644 --- a/lib/propane/parser.rb +++ b/lib/propane/parser.rb @@ -2,11 +2,11 @@ class Propane class Parser - def initialize(rule_sets) + def initialize(start_rule_set) @token_eof = Token.new(name: "$", id: TOKEN_EOF) @item_sets = [] @item_sets_set = {} - start_items = rule_sets["Start"].rules.map do |rule| + start_items = start_rule_set.rules.map do |rule| rule.components << @token_eof Item.new(rule, 0) end diff --git a/lib/propane/rule_set.rb b/lib/propane/rule_set.rb index 3c4637c..6013ba1 100644 --- a/lib/propane/rule_set.rb +++ b/lib/propane/rule_set.rb @@ -2,19 +2,16 @@ class Propane class RuleSet - attr_reader :id - attr_reader :name attr_reader :rules - def initialize(name, id) + def initialize(name) @name = name - @id = id @rules = [] end - def add_rule(rule) + def <<(rule) @rules << rule end