diff --git a/lib/lrama/context.rb b/lib/lrama/context.rb index 22267f85..d796de12 100644 --- a/lib/lrama/context.rb +++ b/lib/lrama/context.rb @@ -23,7 +23,7 @@ def initialize(states) # enum yytokentype def yytokentype - @states.terms.symbols.reject do |term| + @states.terms.reject do |term| 0 < term.token_id && term.token_id < 128 end.map do |term| [term.id.s_value, term.token_id, term.display_name] @@ -68,7 +68,7 @@ def yynstates # Last token number def yymaxutok - @states.terms.symbols.map(&:token_id).max + @states.terms.map(&:token_id).max end # YYTRANSLATE @@ -78,7 +78,7 @@ def yytranslate # 2 is YYSYMBOL_YYUNDEF a = Array.new(yymaxutok, 2) - @states.terms.symbols.each do |term| + @states.terms.each do |term| a[term.token_id] = term.number end @@ -88,7 +88,7 @@ def yytranslate def yytranslate_inverted a = Array.new(@states.symbols.count, @states.undef_symbol.token_id) - @states.terms.symbols.each do |term| + @states.terms.each do |term| a[term.number] = term.token_id end @@ -300,7 +300,7 @@ def compute_yydefgoto end end - @states.nterms.symbols.each do |nterm| + @states.nterms.each do |nterm| if !(states = nterm_to_next_states[nterm]) default_goto = 0 not_default_gotos = [] diff --git a/lib/lrama/grammar.rb b/lib/lrama/grammar.rb index de2b0f2a..2173fa91 100644 --- a/lib/lrama/grammar.rb +++ b/lib/lrama/grammar.rb @@ -176,7 +176,7 @@ def compute_nullable while true do rs = @rules.select {|e| e.nullable.nil? } - nts = nterms.unset_nullable + nts = nterms.select {|e| e.nullable.nil? } rule_count_1 = rs.count nterm_count_1 = nts.count @@ -195,7 +195,7 @@ def compute_nullable end rule_count_2 = @rules.count {|e| e.nullable.nil? } - nterm_count_2 = nterms.unset_nullable.count + nterm_count_2 = nterms.select {|e| e.nullable.nil? }.count if (rule_count_1 == rule_count_2) && (nterm_count_1 == nterm_count_2) break @@ -206,18 +206,18 @@ def compute_nullable rule.nullable = false end - nterms.unset_nullable.each do |nterm| + nterms.select {|e| e.nullable.nil? }.each do |nterm| nterm.nullable = false end end def compute_first_set - terms.symbols.each do |term| + terms.each do |term| term.first_set = Set.new([term]).freeze term.first_set_bitmap = Lrama::Bitmap.from_array([term.number]) end - nterms.symbols.each do |nterm| + nterms.each do |nterm| nterm.first_set = Set.new([]).freeze nterm.first_set_bitmap = Lrama::Bitmap.from_array([]) end @@ -239,7 +239,7 @@ def compute_first_set break unless changed end - nterms.symbols.each do |nterm| + nterms.each do |nterm| nterm.first_set = Lrama::Bitmap.to_array(nterm.first_set_bitmap).map do |number| find_symbol_by_number!(number) end.to_set diff --git a/lib/lrama/grammar/symbols.rb b/lib/lrama/grammar/symbols.rb index e46c83b3..cc9b4ec5 100644 --- a/lib/lrama/grammar/symbols.rb +++ b/lib/lrama/grammar/symbols.rb @@ -1,4 +1 @@ -require_relative "symbols/base" -require_relative "symbols/nterms" require_relative "symbols/resolver" -require_relative "symbols/terms" diff --git a/lib/lrama/grammar/symbols/base.rb b/lib/lrama/grammar/symbols/base.rb deleted file mode 100644 index 2912168a..00000000 --- a/lib/lrama/grammar/symbols/base.rb +++ /dev/null @@ -1,23 +0,0 @@ -module Lrama - class Grammar - class Symbols - class Base - attr_reader :symbols - - # YYEMPTY = -2 - # YYEOF = 0 - # YYerror = 1 - # YYUNDEF = 2 - INITIAL_NUMBER = 3 - - def initialize - @symbols = [] - end - - def count - @symbols.count - end - end - end - end -end diff --git a/lib/lrama/grammar/symbols/nterms.rb b/lib/lrama/grammar/symbols/nterms.rb deleted file mode 100644 index 658583b6..00000000 --- a/lib/lrama/grammar/symbols/nterms.rb +++ /dev/null @@ -1,55 +0,0 @@ -module Lrama - class Grammar - class Symbols - class Nterms < Base - def add(id:, alias_name: nil, tag: nil) - @symbols << Symbol.new( - id: id, alias_name: alias_name, number: nil, tag: tag, - term: false, token_id: nil, nullable: nil, - ) - end - - def unset_nullable - @symbols.select {|e| e.nullable.nil? } - end - - def find_by_id!(id) - @symbols.find do |s| - s.id == id - end || (raise "Symbol not found: #{id}") - end - - # Fill nterm's tag defined by %type decl - def fill_type(types) - types.each do |type| - nterm = find_by_id!(type.id) - nterm.tag = type.tag - end - end - - # Fill #number and #token_id - def fill_symbol_number(used_numbers) - number = INITIAL_NUMBER - token_id = 0 - - @symbols.each do |sym| - while used_numbers[number] do - number += 1 - end - - if sym.number.nil? - sym.number = number - used_numbers[number] = true - number += 1 - end - - if sym.token_id.nil? - sym.token_id = token_id - token_id += 1 - end - end - end - end - end - end -end diff --git a/lib/lrama/grammar/symbols/resolver.rb b/lib/lrama/grammar/symbols/resolver.rb index 677f9e56..456993b8 100644 --- a/lib/lrama/grammar/symbols/resolver.rb +++ b/lib/lrama/grammar/symbols/resolver.rb @@ -5,12 +5,12 @@ class Resolver attr_reader :terms, :nterms def initialize - @terms = Terms.new - @nterms = Nterms.new + @terms = [] + @nterms = [] end def symbols - @symbols ||= (@terms.symbols + @nterms.symbols) + @symbols ||= (@terms + @nterms) end def sort_by_number! @@ -33,14 +33,24 @@ def add_term(id:, alias_name: nil, tag: nil, token_id: nil, replace: false) end @symbols = nil - @terms.add(id: id, alias_name: alias_name, tag: tag, token_id: token_id).last + term = Symbol.new( + id: id, alias_name: alias_name, number: nil, tag: tag, + term: true, token_id: token_id, nullable: false + ) + @terms << term + term end def add_nterm(id:, alias_name: nil, tag: nil) return if find_symbol_by_id(id) @symbols = nil - @nterms.add(id: id, alias_name: alias_name, tag: tag).last + nterm = Symbol.new( + id: id, alias_name: alias_name, number: nil, tag: tag, + term: false, token_id: nil, nullable: nil, + ) + @nterms << nterm + nterm end def find_symbol_by_s_value(s_value) @@ -75,12 +85,20 @@ def find_symbol_by_number!(number) end def fill_symbol_number - @terms.fill_symbol_number(used_numbers) - @nterms.fill_symbol_number(used_numbers) + # YYEMPTY = -2 + # YYEOF = 0 + # YYerror = 1 + # YYUNDEF = 2 + @number = 3 + fill_terms_number + fill_nterms_number end def fill_nterm_type(types) - @nterms.fill_type(types) + types.each do |type| + nterm = find_nterm_by_id!(type.id) + nterm.tag = type.tag + end end def fill_printer(printers) @@ -133,6 +151,88 @@ def validate! private + def find_nterm_by_id!(id) + @nterms.find do |s| + s.id == id + end || (raise "Symbol not found: #{id}") + end + + def fill_terms_number + # Character literal in grammar file has + # token id corresponding to ASCII code by default, + # so start token_id from 256. + token_id = 256 + + @terms.each do |sym| + while used_numbers[@number] do + @number += 1 + end + + if sym.number.nil? + sym.number = @number + used_numbers[@number] = true + @number += 1 + end + + # If id is Token::Char, it uses ASCII code + if sym.token_id.nil? + if sym.id.is_a?(Lrama::Lexer::Token::Char) + # Ignore ' on the both sides + case sym.id.s_value[1..-2] + when "\\b" + sym.token_id = 8 + when "\\f" + sym.token_id = 12 + when "\\n" + sym.token_id = 10 + when "\\r" + sym.token_id = 13 + when "\\t" + sym.token_id = 9 + when "\\v" + sym.token_id = 11 + when "\"" + sym.token_id = 34 + when "'" + sym.token_id = 39 + when "\\\\" + sym.token_id = 92 + when /\A\\(\d+)\z/ + sym.token_id = Integer($1, 8) + when /\A(.)\z/ + sym.token_id = $1.bytes.first + else + raise "Unknown Char s_value #{sym}" + end + else + sym.token_id = token_id + token_id += 1 + end + end + end + end + + def fill_nterms_number + token_id = 0 + + @nterms.each do |sym| + while used_numbers[@number] do + @number += 1 + end + + if sym.number.nil? + sym.number = @number + used_numbers[@number] = true + @number += 1 + end + + if sym.token_id.nil? + sym.token_id = token_id + token_id += 1 + end + end + end + def used_numbers return @used_numbers if defined?(@used_numbers) diff --git a/lib/lrama/grammar/symbols/terms.rb b/lib/lrama/grammar/symbols/terms.rb deleted file mode 100644 index 453b0cc0..00000000 --- a/lib/lrama/grammar/symbols/terms.rb +++ /dev/null @@ -1,71 +0,0 @@ -module Lrama - class Grammar - class Symbols - class Terms < Base - def add(id:, alias_name: nil, tag: nil, token_id: nil, replace: false) - @symbols << Symbol.new( - id: id, alias_name: alias_name, number: nil, tag: tag, - term: true, token_id: token_id, nullable: false - ) - end - - # Fill #number and #token_id - def fill_symbol_number(used_numbers) - number = INITIAL_NUMBER - # Character literal in grammar file has - # token id corresponding to ASCII code by default, - # so start token_id from 256. - token_id = 256 - - @symbols.each do |sym| - while used_numbers[number] do - number += 1 - end - - if sym.number.nil? - sym.number = number - used_numbers[number] = true - number += 1 - end - - # If id is Token::Char, it uses ASCII code - if sym.token_id.nil? - if sym.id.is_a?(Lrama::Lexer::Token::Char) - # Ignore ' on the both sides - case sym.id.s_value[1..-2] - when "\\b" - sym.token_id = 8 - when "\\f" - sym.token_id = 12 - when "\\n" - sym.token_id = 10 - when "\\r" - sym.token_id = 13 - when "\\t" - sym.token_id = 9 - when "\\v" - sym.token_id = 11 - when "\"" - sym.token_id = 34 - when "'" - sym.token_id = 39 - when "\\\\" - sym.token_id = 92 - when /\A\\(\d+)\z/ - sym.token_id = Integer($1, 8) - when /\A(.)\z/ - sym.token_id = $1.bytes.first - else - raise "Unknown Char s_value #{sym}" - end - else - sym.token_id = token_id - token_id += 1 - end - end - end - end - end - end - end -end diff --git a/lib/lrama/states_reporter.rb b/lib/lrama/states_reporter.rb index fe8e7db3..6a0b75d9 100644 --- a/lib/lrama/states_reporter.rb +++ b/lib/lrama/states_reporter.rb @@ -217,7 +217,7 @@ def report_states(io, itemsets, lookaheads, solved, counterexamples, verbose) # Report direct_read_sets io << " [Direct Read sets]\n" direct_read_sets = @states.direct_read_sets - @states.nterms.symbols.each do |nterm| + @states.nterms.each do |nterm| terms = direct_read_sets[[state.id, nterm.token_id]] next if !terms next if terms.empty? @@ -229,12 +229,12 @@ def report_states(io, itemsets, lookaheads, solved, counterexamples, verbose) # Report reads_relation io << " [Reads Relation]\n" - @states.nterms.symbols.each do |nterm| + @states.nterms.each do |nterm| a = @states.reads_relation[[state.id, nterm.token_id]] next if !a a.each do |state_id2, nterm_id2| - n = @states.nterms.symbols.find {|n| n.token_id == nterm_id2 } + n = @states.nterms.find {|n| n.token_id == nterm_id2 } io << " (State #{state_id2}, #{n.id.s_value})\n" end end @@ -243,7 +243,7 @@ def report_states(io, itemsets, lookaheads, solved, counterexamples, verbose) # Report read_sets io << " [Read sets]\n" read_sets = @states.read_sets - @states.nterms.symbols.each do |nterm| + @states.nterms.each do |nterm| terms = read_sets[[state.id, nterm.token_id]] next if !terms next if terms.empty? @@ -256,12 +256,12 @@ def report_states(io, itemsets, lookaheads, solved, counterexamples, verbose) # Report includes_relation io << " [Includes Relation]\n" - @states.nterms.symbols.each do |nterm| + @states.nterms.each do |nterm| a = @states.includes_relation[[state.id, nterm.token_id]] next if !a a.each do |state_id2, nterm_id2| - n = @states.nterms.symbols.find {|n| n.token_id == nterm_id2 } + n = @states.nterms.find {|n| n.token_id == nterm_id2 } io << " (State #{state.id}, #{nterm.id.s_value}) -> (State #{state_id2}, #{n.id.s_value})\n" end end @@ -274,7 +274,7 @@ def report_states(io, itemsets, lookaheads, solved, counterexamples, verbose) next if !a a.each do |state_id2, nterm_id2| - n = @states.nterms.symbols.find {|n| n.token_id == nterm_id2 } + n = @states.nterms.find {|n| n.token_id == nterm_id2 } io << " (Rule: #{rule}) -> (State #{state_id2}, #{n.id.s_value})\n" end end @@ -283,7 +283,7 @@ def report_states(io, itemsets, lookaheads, solved, counterexamples, verbose) # Report follow_sets io << " [Follow sets]\n" follow_sets = @states.follow_sets - @states.nterms.symbols.each do |nterm| + @states.nterms.each do |nterm| terms = follow_sets[[state.id, nterm.token_id]] next if !terms diff --git a/spec/lrama/parser_spec.rb b/spec/lrama/parser_spec.rb index 44d2d802..9df99a07 100644 --- a/spec/lrama/parser_spec.rb +++ b/spec/lrama/parser_spec.rb @@ -423,7 +423,7 @@ grammar.prepare grammar.validate! - expect(grammar.nterms.symbols.sort_by(&:number)).to match_symbols([ + expect(grammar.nterms.sort_by(&:number)).to match_symbols([ Sym.new(id: T::Ident.new(s_value: "$accept"), alias_name: nil, number: 6, tag: nil, term: false, token_id: 0, nullable: false), Sym.new(id: T::Ident.new(s_value: "program"), alias_name: nil, number: 7, tag: nil, term: false, token_id: 1, nullable: true), Sym.new(id: T::Ident.new(s_value: "stmt"), alias_name: nil, number: 8, tag: nil, term: false, token_id: 2, nullable: true), @@ -578,7 +578,7 @@ let(:path) { "parameterizing_rules/option.y" } it "expands parameterizing rules" do - expect(grammar.nterms.symbols.sort_by(&:number)).to match_symbols([ + expect(grammar.nterms.sort_by(&:number)).to match_symbols([ Sym.new(id: T::Ident.new(s_value: "$accept"), alias_name: nil, number: 5, tag: nil, term: false, token_id: 0, nullable: false), Sym.new(id: T::Ident.new(s_value: "option_number"), alias_name: nil, number: 6, tag: nil, term: false, token_id: 1, nullable: true), Sym.new(id: T::Ident.new(s_value: "program"), alias_name: nil, number: 7, tag: nil, term: false, token_id: 2, nullable: true), @@ -674,7 +674,7 @@ end it "expands parameterizing rules" do - expect(grammar.nterms.symbols.sort_by(&:number)).to match_symbols([ + expect(grammar.nterms.sort_by(&:number)).to match_symbols([ Sym.new(id: T::Ident.new(s_value: "$accept"), alias_name: nil, number: 5, tag: nil, term: false, token_id: 0, nullable: false), Sym.new(id: T::Ident.new(s_value: "option_number"), alias_name: nil, number: 6, tag: nil, term: false, token_id: 1, nullable: true), Sym.new(id: T::Ident.new(s_value: "program"), alias_name: nil, number: 7, tag: nil, term: false, token_id: 2, nullable: true), @@ -766,7 +766,7 @@ let(:path) { "parameterizing_rules/between_rhs.y" } it "expands parameterizing rules" do - expect(grammar.nterms.symbols.sort_by(&:number)).to match_symbols([ + expect(grammar.nterms.sort_by(&:number)).to match_symbols([ Sym.new(id: T::Ident.new(s_value: "$accept"), alias_name: nil, number: 6, tag: nil, term: false, token_id: 0, nullable: false), Sym.new(id: T::Ident.new(s_value: "option_bar"), alias_name: nil, number: 7, tag: nil, term: false, token_id: 1, nullable: true), Sym.new(id: T::Ident.new(s_value: "program"), alias_name: nil, number: 8, tag: nil, term: false, token_id: 2, nullable: false), @@ -828,7 +828,7 @@ let(:path) { "parameterizing_rules/option_with_tag.y" } it "expands parameterizing rules" do - expect(grammar.nterms.symbols.sort_by(&:number)).to match_symbols([ + expect(grammar.nterms.sort_by(&:number)).to match_symbols([ Sym.new(id: T::Ident.new(s_value: "$accept"), alias_name: nil, number: 5, tag: nil, term: false, token_id: 0, nullable: false), Sym.new(id: T::Ident.new(s_value: "option_number"), alias_name: nil, number: 6, tag: T::Tag.new(s_value: ""), term: false, token_id: 1, nullable: true), Sym.new(id: T::Ident.new(s_value: "program"), alias_name: nil, number: 7, tag: nil, term: false, token_id: 2, nullable: true), @@ -924,7 +924,7 @@ let(:path) { "parameterizing_rules/nonempty_list.y" } it "expands parameterizing rules" do - expect(grammar.nterms.symbols.sort_by(&:number)).to match_symbols([ + expect(grammar.nterms.sort_by(&:number)).to match_symbols([ Sym.new(id: T::Ident.new(s_value: "$accept"), alias_name: nil, number: 5, tag: nil, term: false, token_id: 0, nullable: false), Sym.new(id: T::Ident.new(s_value: "nonempty_list_number"), alias_name: nil, number: 6, tag: nil, term: false, token_id: 1, nullable: false), Sym.new(id: T::Ident.new(s_value: "program"), alias_name: nil, number: 7, tag: nil, term: false, token_id: 2, nullable: false), @@ -1022,7 +1022,7 @@ let(:path) { "parameterizing_rules/list.y" } it "expands parameterizing rules" do - expect(grammar.nterms.symbols.sort_by(&:number)).to match_symbols([ + expect(grammar.nterms.sort_by(&:number)).to match_symbols([ Sym.new(id: T::Ident.new(s_value: "$accept"), alias_name: nil, number: 5, tag: nil, term: false, token_id: 0, nullable: false), Sym.new(id: T::Ident.new(s_value: "list_number"), alias_name: nil, number: 6, tag: nil, term: false, token_id: 1, nullable: true), Sym.new(id: T::Ident.new(s_value: "program"), alias_name: nil, number: 7, tag: nil, term: false, token_id: 2, nullable: true), @@ -1116,7 +1116,7 @@ let(:path) { "parameterizing_rules/separated_nonempty_list.y" } it "expands parameterizing rules" do - expect(grammar.nterms.symbols.sort_by(&:number)).to match_symbols([ + expect(grammar.nterms.sort_by(&:number)).to match_symbols([ Sym.new(id: T::Ident.new(s_value: "$accept"), alias_name: nil, number: 5, tag: nil, term: false, token_id: 0, nullable: false), Sym.new(id: T::Ident.new(s_value: "separated_nonempty_list_','_number"), alias_name: nil, number: 6, tag: nil, term: false, token_id: 1, nullable: false), Sym.new(id: T::Ident.new(s_value: "program"), alias_name: nil, number: 7, tag: nil, term: false, token_id: 2, nullable: false), @@ -1180,7 +1180,7 @@ let(:path) { "parameterizing_rules/separated_list.y" } it "expands parameterizing rules" do - expect(grammar.nterms.symbols.sort_by(&:number)).to match_symbols([ + expect(grammar.nterms.sort_by(&:number)).to match_symbols([ Sym.new(id: T::Ident.new(s_value: "$accept"), alias_name: nil, number: 5, tag: nil, term: false, token_id: 0, nullable: false), Sym.new(id: T::Ident.new(s_value: "option_separated_nonempty_list_','_number"), alias_name: nil, number: 6, tag: nil, term: false, token_id: 1, nullable: true), Sym.new(id: T::Ident.new(s_value: "separated_nonempty_list_','_number"), alias_name: nil, number: 7, tag: nil, term: false, token_id: 2, nullable: false), @@ -1280,7 +1280,7 @@ let(:path) { "parameterizing_rules/nested.y" } it "expands parameterizing rules" do - expect(grammar.nterms.symbols.sort_by(&:number)).to match_symbols([ + expect(grammar.nterms.sort_by(&:number)).to match_symbols([ Sym.new(id: T::Ident.new(s_value: "$accept"), alias_name: nil, number: 4, tag: nil, term: false, token_id: 0, nullable: false), Sym.new(id: T::Ident.new(s_value: "option_constant_number"), alias_name: nil, number: 5, tag: nil, term: false, token_id: 1, nullable: true), Sym.new(id: T::Ident.new(s_value: "constant_number"), alias_name: nil, number: 6, tag: nil, term: false, token_id: 2, nullable: false), @@ -1351,7 +1351,7 @@ let(:path) { "parameterizing_rules/user_defined.y" } it "expands parameterizing rules" do - expect(grammar.nterms.symbols.sort_by(&:number)).to match_symbols([ + expect(grammar.nterms.sort_by(&:number)).to match_symbols([ Sym.new(id: T::Ident.new(s_value: "$accept"), alias_name: nil, number: 6, tag: nil, term: false, token_id: 0, nullable: false), Sym.new(id: T::Ident.new(s_value: "defined_option_number"), alias_name: nil, number: 7, tag: T::Tag.new(s_value: ""), term: false, token_id: 1, nullable: true), Sym.new(id: T::Ident.new(s_value: "program"), alias_name: nil, number: 8, tag: nil, term: false, token_id: 2, nullable: true), @@ -1532,7 +1532,7 @@ let(:path) { "parameterizing_rules/user_defined_with_nest.y" } it "expands parameterizing rules" do - expect(grammar.nterms.symbols.sort_by(&:number)).to match_symbols([ + expect(grammar.nterms.sort_by(&:number)).to match_symbols([ Sym.new(id: T::Ident.new(s_value: "$accept"), alias_name: nil, number: 5, tag: nil, term: false, token_id: 0, nullable: false), Sym.new(id: T::Ident.new(s_value: "option_number"), alias_name: nil, number: 6, tag: nil, term: false, token_id: 1, nullable: true), Sym.new(id: T::Ident.new(s_value: "nested_option_number"), alias_name: nil, number: 7, tag: nil, term: false, token_id: 2, nullable: true), @@ -1731,7 +1731,7 @@ let(:path) { "parameterizing_rules/user_defined_with_recursive.y" } it "expands parameterizing rules" do - expect(grammar.nterms.symbols.sort_by(&:number)).to match_symbols([ + expect(grammar.nterms.sort_by(&:number)).to match_symbols([ Sym.new(id: T::Ident.new(s_value: "$accept"), alias_name: nil, number: 4, tag: nil, term: false, token_id: 0, nullable: false), Sym.new(id: T::Ident.new(s_value: "list_number"), alias_name: nil, number: 5, tag: nil, term: false, token_id: 1, nullable: true), Sym.new(id: T::Ident.new(s_value: "program"), alias_name: nil, number: 6, tag: nil, term: false, token_id: 2, nullable: true), @@ -1880,7 +1880,7 @@ class : keyword_class tSTRING keyword_end { code 1 } grammar.prepare grammar.validate! - expect(grammar.terms.symbols.sort_by(&:number)).to match_symbols([ + expect(grammar.terms.sort_by(&:number)).to match_symbols([ Sym.new(id: T::Ident.new(s_value: "EOI"), alias_name: "\"EOI\"", number: 0, tag: nil, term: true, token_id: 0, nullable: false, precedence: nil), Sym.new(id: T::Ident.new(s_value: "YYerror"), alias_name: "error", number: 1, tag: nil, term: true, token_id: 256, nullable: false, precedence: nil), Sym.new(id: T::Ident.new(s_value: "YYUNDEF"), alias_name: "\"invalid token\"", number: 2, tag: nil, term: true, token_id: 257, nullable: false, precedence: nil), @@ -1939,7 +1939,7 @@ class : keyword_class { code 1 } tSTRING { code 2 } keyword_end { code 3 } grammar.prepare grammar.validate! - expect(grammar.nterms.symbols.sort_by(&:number)).to match_symbols([ + expect(grammar.nterms.sort_by(&:number)).to match_symbols([ Sym.new(id: T::Ident.new(s_value: "$accept"), alias_name: nil, number: 11, tag: nil, term: false, token_id: 0, nullable: false), Sym.new(id: T::Ident.new(s_value: "program"), alias_name: nil, number: 12, tag: nil, term: false, token_id: 1, nullable: false), Sym.new(id: T::Ident.new(s_value: "$@1"), alias_name: nil, number: 13, tag: nil, term: false, token_id: 2, nullable: true), @@ -2184,7 +2184,7 @@ class : keyword_class tSTRING keyword_end { code 1 } grammar.prepare grammar.validate! - expect(grammar.terms.symbols.sort_by(&:number)).to match_symbols([ + expect(grammar.terms.sort_by(&:number)).to match_symbols([ Sym.new(id: T::Ident.new(s_value: "EOI"), alias_name: "\"EOI\"", number: 0, tag: nil, term: true, token_id: 0, nullable: false), Sym.new(id: T::Ident.new(s_value: "YYerror"), alias_name: "error", number: 1, tag: nil, term: true, token_id: 256, nullable: false), Sym.new(id: T::Ident.new(s_value: "YYUNDEF"), alias_name: "\"invalid token\"", number: 2, tag: nil, term: true, token_id: 257, nullable: false), @@ -2235,7 +2235,7 @@ class : keyword_class tSTRING keyword_end { code 1 } grammar.prepare grammar.validate! - expect(grammar.terms.symbols.sort_by(&:number)).to match_symbols([ + expect(grammar.terms.sort_by(&:number)).to match_symbols([ Sym.new(id: T::Ident.new(s_value: "EOI"), alias_name: "\"EOI\"", number: 0, tag: nil, term: true, token_id: 0, nullable: false, precedence: nil), Sym.new(id: T::Ident.new(s_value: "YYerror"), alias_name: "error", number: 1, tag: nil, term: true, token_id: 256, nullable: false, precedence: nil), Sym.new(id: T::Ident.new(s_value: "YYUNDEF"), alias_name: "\"invalid token\"", number: 2, tag: nil, term: true, token_id: 257, nullable: false, precedence: nil), @@ -2753,7 +2753,7 @@ class : keyword_class tSTRING keyword_end ; grammar = Lrama::Parser.new(y, "parse.y").parse grammar.prepare grammar.validate! - terms = grammar.terms.symbols.sort_by(&:number).map do |term| + terms = grammar.terms.sort_by(&:number).map do |term| [term.id.s_value, term.token_id] end