Class: Ibex::IR::Grammar

Inherits:
Object
  • Object
show all
Defined in:
lib/ibex/ir/grammar_ir.rb,
sig/ibex/ir/grammar_ir.rbs

Overview

Immutable normalized grammar exchanged between pipeline stages.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(class_name:, superclass:, start:, expect:, options:, symbols:, productions:, user_code:, conversions:, warnings:, user_code_chunks: nil, schema_version: SCHEMA_VERSION, source_provenance: nil, migration: nil, expect_rr: nil, parser_parameters: [], value_printers: [], grammar_tests: [], recovery: nil, lexer: nil, mode: :default, starts: nil) ⇒ Grammar

rubocop:disable Metrics/AbcSize, Metrics/ParameterLists Immutable versioned IR is constructed from explicit public fields.

RBS:

  • (class_name: String, superclass: String?, start: String, expect: Integer, ?expect_rr: Integer?, options: grammar_options, symbols: Array[GrammarSymbol], productions: Array[Production], user_code: Hash[String, String], conversions: Hash[String, String], warnings: Array[grammar_warning], ?user_code_chunks: user_code_chunks?, ?schema_version: Integer, ?source_provenance: source_provenance?, ?migration: migration_metadata?, ?parser_parameters: Array[parser_parameter], ?value_printers: Array[value_printer], ?grammar_tests: Array[grammar_test], ?recovery: recovery_policy?, ?lexer: Lexer?, ?mode: grammar_mode, ?starts: Array[String]?) -> void

Parameters:

  • class_name: (String)
  • superclass: (String, nil)
  • start: (String)
  • expect: (Integer)
  • options: (grammar_options)
  • symbols: (Array[GrammarSymbol])
  • productions: (Array[Production])
  • user_code: (Hash[String, String])
  • conversions: (Hash[String, String])
  • warnings: (Array[grammar_warning])
  • expect_rr: (Integer, nil) (defaults to: nil)
  • user_code_chunks: (user_code_chunks, nil) (defaults to: nil)
  • schema_version: (Integer) (defaults to: SCHEMA_VERSION)
  • source_provenance: (source_provenance, nil) (defaults to: nil)
  • migration: (migration_metadata, nil) (defaults to: nil)
  • parser_parameters: (Array[parser_parameter]) (defaults to: [])
  • value_printers: (Array[value_printer]) (defaults to: [])
  • grammar_tests: (Array[grammar_test]) (defaults to: [])
  • recovery: (recovery_policy, nil) (defaults to: nil)
  • lexer: (Lexer, nil) (defaults to: nil)
  • mode: (grammar_mode) (defaults to: :default)
  • starts: (Array[String], nil) (defaults to: nil)


190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
# File 'lib/ibex/ir/grammar_ir.rb', line 190

def initialize(class_name:, superclass:, start:, expect:, options:, symbols:, productions:, user_code:,
               conversions:, warnings:, user_code_chunks: nil, schema_version: SCHEMA_VERSION,
               source_provenance: nil, migration: nil, expect_rr: nil, parser_parameters: [], value_printers: [],
               grammar_tests: [], recovery: nil, lexer: nil, mode: :default, starts: nil)
  validate_mode(mode)
  normalized_starts = validate_starts(start, starts, mode)

  @class_name = class_name.freeze
  @superclass = superclass&.freeze
  @start = start.freeze
  @starts = normalized_starts.map(&:freeze).freeze
  @mode = mode
  @expect = expect
  @expect_rr = expect_rr
  @parser_parameters = IR.deep_freeze(parser_parameters)
  @value_printers = IR.deep_freeze(value_printers)
  @grammar_tests = IR.deep_freeze(grammar_tests)
  @lexer = lexer
  @recovery = IR.deep_freeze(recovery || { sync_tokens: [], on_error_reduce: [] })
  @options = IR.deep_freeze(options)
  @symbols = symbols.freeze
  @productions = productions.freeze
  @user_code = IR.deep_freeze(user_code)
  @user_code_chunks = IR.deep_freeze(user_code_chunks || {})
  validate_user_code_chunks
  @conversions = IR.deep_freeze(conversions)
  @warnings = IR.deep_freeze(warnings)
  @schema_version = schema_version
  @source_provenance = IR.deep_freeze(source_provenance)
  @migration = IR.deep_freeze(migration)
  @symbols_by_name = @symbols.to_h { |symbol| [symbol.name, symbol] }.freeze
  @symbols_by_id = @symbols.to_h { |symbol| [symbol.id, symbol] }.freeze
  freeze
end

Instance Attribute Details

#class_nameString (readonly)

Signature:

  • String

Returns:

  • (String)


156
157
158
# File 'lib/ibex/ir/grammar_ir.rb', line 156

def class_name
  @class_name
end

#conversionsHash[String, String] (readonly)

Signature:

  • Hash[String, String]

Returns:

  • (Hash[String, String])


173
174
175
# File 'lib/ibex/ir/grammar_ir.rb', line 173

def conversions
  @conversions
end

#expectInteger (readonly)

Signature:

  • Integer

Returns:

  • (Integer)


161
162
163
# File 'lib/ibex/ir/grammar_ir.rb', line 161

def expect
  @expect
end

#expect_rrInteger? (readonly)

Signature:

  • Integer?

Returns:

  • (Integer, nil)


162
163
164
# File 'lib/ibex/ir/grammar_ir.rb', line 162

def expect_rr
  @expect_rr
end

#grammar_testsArray[grammar_test] (readonly)

Signature:

  • Array[grammar_test]

Returns:

  • (Array[grammar_test])


165
166
167
# File 'lib/ibex/ir/grammar_ir.rb', line 165

def grammar_tests
  @grammar_tests
end

#lexerLexer? (readonly)

Signature:

  • Lexer?

Returns:



166
167
168
# File 'lib/ibex/ir/grammar_ir.rb', line 166

def lexer
  @lexer
end

#migrationmigration_metadata? (readonly)

Signature:

  • migration_metadata?

Returns:

  • (migration_metadata, nil)


177
178
179
# File 'lib/ibex/ir/grammar_ir.rb', line 177

def migration
  @migration
end

#modegrammar_mode (readonly)

Signature:

  • grammar_mode

Returns:

  • (grammar_mode)


160
161
162
# File 'lib/ibex/ir/grammar_ir.rb', line 160

def mode
  @mode
end

#optionsgrammar_options (readonly)

Signature:

  • grammar_options

Returns:

  • (grammar_options)


168
169
170
# File 'lib/ibex/ir/grammar_ir.rb', line 168

def options
  @options
end

#parser_parametersArray[parser_parameter] (readonly)

Signature:

  • Array[parser_parameter]

Returns:

  • (Array[parser_parameter])


163
164
165
# File 'lib/ibex/ir/grammar_ir.rb', line 163

def parser_parameters
  @parser_parameters
end

#productionsArray[Production] (readonly)

Signature:

  • Array[Production]

Returns:



170
171
172
# File 'lib/ibex/ir/grammar_ir.rb', line 170

def productions
  @productions
end

#recoveryrecovery_policy (readonly)

Signature:

  • recovery_policy

Returns:

  • (recovery_policy)


167
168
169
# File 'lib/ibex/ir/grammar_ir.rb', line 167

def recovery
  @recovery
end

#schema_versionInteger (readonly)

Signature:

  • Integer

Returns:

  • (Integer)


175
176
177
# File 'lib/ibex/ir/grammar_ir.rb', line 175

def schema_version
  @schema_version
end

#source_provenancesource_provenance? (readonly)

Signature:

  • source_provenance?

Returns:



176
177
178
# File 'lib/ibex/ir/grammar_ir.rb', line 176

def source_provenance
  @source_provenance
end

#startString (readonly)

Signature:

  • String

Returns:

  • (String)


158
159
160
# File 'lib/ibex/ir/grammar_ir.rb', line 158

def start
  @start
end

#startsArray[String] (readonly)

Signature:

  • Array[String]

Returns:

  • (Array[String])


159
160
161
# File 'lib/ibex/ir/grammar_ir.rb', line 159

def starts
  @starts
end

#superclassString? (readonly)

Signature:

  • String?

Returns:

  • (String, nil)


157
158
159
# File 'lib/ibex/ir/grammar_ir.rb', line 157

def superclass
  @superclass
end

#symbolsArray[GrammarSymbol] (readonly)

Signature:

  • Array[GrammarSymbol]

Returns:



169
170
171
# File 'lib/ibex/ir/grammar_ir.rb', line 169

def symbols
  @symbols
end

#user_codeHash[String, String] (readonly)

Signature:

  • Hash[String, String]

Returns:

  • (Hash[String, String])


171
172
173
# File 'lib/ibex/ir/grammar_ir.rb', line 171

def user_code
  @user_code
end

#user_code_chunksuser_code_chunks (readonly)

Signature:

  • user_code_chunks

Returns:



172
173
174
# File 'lib/ibex/ir/grammar_ir.rb', line 172

def user_code_chunks
  @user_code_chunks
end

#value_printersArray[value_printer] (readonly)

Signature:

  • Array[value_printer]

Returns:

  • (Array[value_printer])


164
165
166
# File 'lib/ibex/ir/grammar_ir.rb', line 164

def value_printers
  @value_printers
end

#warningsArray[grammar_warning] (readonly)

Signature:

  • Array[grammar_warning]

Returns:

  • (Array[grammar_warning])


174
175
176
# File 'lib/ibex/ir/grammar_ir.rb', line 174

def warnings
  @warnings
end

Instance Method Details

#append_optional_metadata(value) ⇒ void

This method returns an undefined value.

RBS:

  • (Hash[Symbol, untyped] value) -> void

Parameters:

  • value (Hash[Symbol, untyped])


266
267
268
269
270
271
272
273
274
275
# File 'lib/ibex/ir/grammar_ir.rb', line 266

def (value)
  (value)
  (value)
  value[:user_code_chunks] = @user_code_chunks.transform_values { |chunks| chunks.map(&:to_h) } \
    unless @user_code_chunks.empty?
  return unless @schema_version >= 2

  value[:source_provenance] = @source_provenance
  value[:migration] = @migration
end

#append_parser_metadata(value) ⇒ void

This method returns an undefined value.

RBS:

  • (Hash[Symbol, untyped] value) -> void

Parameters:

  • value (Hash[Symbol, untyped])


278
279
280
281
282
283
284
285
286
# File 'lib/ibex/ir/grammar_ir.rb', line 278

def (value)
  value[:expect_rr] = @expect_rr unless @expect_rr.nil?
  value[:mode] = @mode if @mode == :extended
  value[:starts] = @starts if @starts.length > 1
  value[:params] = @parser_parameters unless @parser_parameters.empty?
  value[:printers] = @value_printers unless @value_printers.empty?
  value[:tests] = @grammar_tests unless @grammar_tests.empty? || @schema_version < 2
  value[:lexer] = @lexer.to_h if @lexer && @schema_version >= 2
end

#append_recovery_metadata(value) ⇒ void

This method returns an undefined value.

RBS:

  • (Hash[Symbol, untyped] value) -> void

Parameters:

  • value (Hash[Symbol, untyped])


289
290
291
292
293
# File 'lib/ibex/ir/grammar_ir.rb', line 289

def (value)
  return if @recovery[:sync_tokens].empty? && @recovery[:on_error_reduce].empty?

  value[:recovery] = @recovery
end

#nonterminalsArray[GrammarSymbol]

RBS:

  • () -> Array[GrammarSymbol]

Returns:



233
# File 'lib/ibex/ir/grammar_ir.rb', line 233

def nonterminals = @symbols.select(&:nonterminal?)

#symbol(name) ⇒ GrammarSymbol?

RBS:

  • (String name) -> GrammarSymbol?

Parameters:

  • name (String)

Returns:



227
228
# File 'lib/ibex/ir/grammar_ir.rb', line 227

def symbol(name) = @symbols_by_name[name]
# @rbs (Integer? id) -> GrammarSymbol?

#symbol_by_id(id) ⇒ GrammarSymbol?

RBS:

  • (Integer? id) -> GrammarSymbol?

Parameters:

  • id (Integer, nil)

Returns:



229
230
# File 'lib/ibex/ir/grammar_ir.rb', line 229

def symbol_by_id(id) = @symbols_by_id[id]
# @rbs () -> Array[GrammarSymbol]

#terminalsArray[GrammarSymbol]

RBS:

  • () -> Array[GrammarSymbol]

Returns:



231
232
# File 'lib/ibex/ir/grammar_ir.rb', line 231

def terminals = @symbols.select(&:terminal?)
# @rbs () -> Array[GrammarSymbol]

#to_hHash[Symbol, untyped]

RBS:

  • () -> Hash[Symbol, untyped]

Returns:

  • (Hash[Symbol, untyped])


236
237
238
239
240
241
242
243
244
245
# File 'lib/ibex/ir/grammar_ir.rb', line 236

def to_h
  value = { ibex_ir: "grammar", schema_version: @schema_version, class_name: @class_name, superclass: @superclass,
            start: @start, expect: @expect, options: @options,
            symbols: @symbols.map { |symbol| symbol.to_h(schema_version: @schema_version) },
            productions: @productions.map { |production| production.to_h(schema_version: @schema_version) },
            user_code: @user_code, conversions: @conversions,
            warnings: @warnings } #: Hash[Symbol, untyped]
  (value)
  value
end

#validate_mode(mode) ⇒ void

This method returns an undefined value.

RBS:

  • (grammar_mode mode) -> void

Parameters:

  • mode (grammar_mode)


250
251
252
# File 'lib/ibex/ir/grammar_ir.rb', line 250

def validate_mode(mode)
  raise ArgumentError, "mode must be :default or :extended" unless %i[default extended].include?(mode)
end

#validate_starts(start, starts, mode) ⇒ Array[String]

RBS:

  • (String start, Array[String]? starts, grammar_mode mode) -> Array[String]

Parameters:

  • start (String)
  • starts (Array[String], nil)
  • mode (grammar_mode)

Returns:

  • (Array[String])


255
256
257
258
259
260
261
262
263
# File 'lib/ibex/ir/grammar_ir.rb', line 255

def validate_starts(start, starts, mode)
  values = starts || [start]
  raise ArgumentError, "starts must contain the primary start symbol" if values.empty?
  raise ArgumentError, "start must be the first entry in starts" unless values.first == start
  raise ArgumentError, "starts must be unique" unless values.uniq.length == values.length
  raise ArgumentError, "multiple start symbols require extended mode" if values.length > 1 && mode != :extended

  values
end

#validate_user_code_chunksvoid

This method returns an undefined value.

RBS:

  • () -> void



296
297
298
299
300
301
302
# File 'lib/ibex/ir/grammar_ir.rb', line 296

def validate_user_code_chunks
  @user_code_chunks.each do |name, chunks|
    next if chunks.map(&:code).join == @user_code.fetch(name, "")

    raise Ibex::Error, "(ir):1:1: user-code chunks do not match the concatenated #{name} section"
  end
end