Remove RuleSet creation from Grammar

This commit is contained in:
Josh Holtrop 2022-06-05 15:16:41 -04:00
parent ca6a93a4c5
commit c42c3576a5
4 changed files with 24 additions and 28 deletions

View File

@ -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|
@grammar.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]
elsif rule_sets[component]
rule_sets[component]
else
raise Error.new("Symbol #{component} not found")
end
end
end
end
@lexer = Lexer.new(@grammar.tokens, @grammar.drop_tokens)
@parser = Parser.new(rule_sets["Start"])
end
end

View File

@ -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) + "..."

View File

@ -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

View File

@ -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