Class: Ibex::Codegen::Ruby

Inherits:
Object
  • Object
show all
Includes:
RubyAST, RubyActions, RubyErrorMessages, RubyLexer, RubySyntax, RubyTableMetadata, RubyValuePrinters
Defined in:
lib/ibex/codegen/ruby.rb

Overview

Generates a standalone Ruby parser class from Automaton IR. rubocop:disable Metrics/ClassLength -- generation stages are split into focused mixins.

Instance Method Summary collapse

Constructor Details

#initialize(automaton, table: :compact, embedded: false, line_convert: true, debug: false, line_convert_all: false, omit_action_call: nil, superclass: nil, executable: nil, cst_trivia: :leading, runtime_require: "ibex/runtime", error_messages: {}) ⇒ Ruby

Returns a new instance of Ruby.



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/ibex/codegen/ruby.rb', line 46

def initialize(automaton, table: :compact, embedded: false, line_convert: true, debug: false,
               line_convert_all: false, omit_action_call: nil, superclass: nil, executable: nil,
               cst_trivia: :leading, runtime_require: "ibex/runtime", error_messages: {})
  @automaton = automaton
  @grammar = automaton.grammar
  @table_format = table.to_sym
  @embedded = embedded
  @line_convert = line_convert
  @line_convert_all = line_convert_all
  @debug = debug
  @omit_action_call = omit_action_call.nil? ? @grammar.options[:omit_action_call] : omit_action_call
  @superclass = superclass || @grammar.superclass || "Ibex::Runtime::Parser"
  @executable = executable
  @cst_trivia = cst_trivia.to_sym
  @generated_action_abi = GeneratedActionABI::Cache.new
  @runtime_require = runtime_require
  @cst_trivia = :leading if @cst_trivia == :attach
  unless %i[leading balanced drop].include?(@cst_trivia)
    raise ArgumentError, "cst_trivia must be :leading, :balanced, or :drop"
  end

  @error_messages = error_messages.sort.to_h.freeze
end

Instance Method Details

#generateObject



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/ibex/codegen/ruby.rb', line 71

def generate
  lines = [] #: Array[String]
  lines << "#!#{@executable}" if @executable
  lines.push("# frozen_string_literal: true", "# Generated by Ibex #{grammar_digest_comment}", "")
  append_user_code(lines, "header")
  append_runtime(lines)
  modules, class_name = class_parts
  modules.each { |name| lines << "module #{name}" }
  lines << "class #{class_name} < #{@superclass}"
  append_ast(lines)
  append_syntax(lines)
  append_tables(lines)
  append_parameter_initializer(lines)
  append_entry_methods(lines)
  append_lexer(lines)
  append_value_printers(lines)
  append_actions(lines)
  append_user_code(lines, "inner", indent: 2)
  lines << "end"
  modules.reverse_each { lines << "end" }
  append_user_code(lines, "footer")
  "#{lines.join("\n")}\n"
end