diff --git a/lib/imbecile/generator.rb b/lib/imbecile/generator.rb index 081b32c..c8bf164 100644 --- a/lib/imbecile/generator.rb +++ b/lib/imbecile/generator.rb @@ -9,6 +9,19 @@ module Imbecile end def generate(output_file) + token_names = @grammar.tokens.each_with_object({}) do |token, token_names| + if token_names.include?(token.name) + raise Error.new("Duplicate token name #{token.name}") + end + token_names[token.name] = token + end + rule_names = @grammar.rules.each_with_object({}) do |rule, rule_names| + if token_names.include?(rule.name) + raise Error.new("Rule name collides with token name #{rule.name}") + end + rule_names[rule.name] ||= [] + rule_names[rule.name] << rule + end lexer_dfa = LexerDFA.new(@grammar.tokens) classname = @grammar.classname || output_file.sub(%r{[^a-zA-Z0-9].*}, "").capitalize erb = ERB.new(File.read(File.join(File.dirname(File.expand_path(__FILE__)), "../../assets/parser.d.erb")), nil, "<>") diff --git a/lib/imbecile/grammar.rb b/lib/imbecile/grammar.rb index d9c1dfa..2a0375b 100644 --- a/lib/imbecile/grammar.rb +++ b/lib/imbecile/grammar.rb @@ -16,7 +16,6 @@ module Imbecile def initialize(input) @tokens = [] @rules = [] - @token_names = Set.new input = input.gsub("\r\n", "\n") while !input.empty? consume(input) @@ -42,11 +41,7 @@ module Imbecile unless name =~ /^[a-zA-Z_][a-zA-Z_0-9]*$/ raise Error.new("Invalid token name #{name}") end - if @token_names.include?(name) - raise Error.new("Duplicate token name #{name}") - end @tokens << Token.new(name, pattern, @tokens.size) - @token_names << name elsif input.slice!(/\Adrop\s+(\S+)\n/) pattern = $1 @tokens << Token.new(nil, pattern, @tokens.size)