Class: Ibex::IR::Grammar
- Inherits:
-
Object
- Object
- Ibex::IR::Grammar
- 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
- #class_name ⇒ String readonly
- #conversions ⇒ Hash[String, String] readonly
- #expect ⇒ Integer readonly
- #expect_rr ⇒ Integer? readonly
- #grammar_tests ⇒ Array[grammar_test] readonly
- #lexer ⇒ Lexer? readonly
- #migration ⇒ migration_metadata? readonly
- #mode ⇒ grammar_mode readonly
- #options ⇒ grammar_options readonly
- #parser_parameters ⇒ Array[parser_parameter] readonly
- #productions ⇒ Array[Production] readonly
- #recovery ⇒ recovery_policy readonly
- #schema_version ⇒ Integer readonly
- #source_provenance ⇒ source_provenance? readonly
- #start ⇒ String readonly
- #starts ⇒ Array[String] readonly
- #superclass ⇒ String? readonly
- #symbols ⇒ Array[GrammarSymbol] readonly
- #user_code ⇒ Hash[String, String] readonly
- #user_code_chunks ⇒ user_code_chunks readonly
- #value_printers ⇒ Array[value_printer] readonly
- #warnings ⇒ Array[grammar_warning] readonly
Instance Method Summary collapse
- #append_optional_metadata(value) ⇒ void
- #append_parser_metadata(value) ⇒ void
- #append_recovery_metadata(value) ⇒ void
-
#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
constructor
rubocop:disable Metrics/AbcSize, Metrics/ParameterLists Immutable versioned IR is constructed from explicit public fields.
- #nonterminals ⇒ Array[GrammarSymbol]
- #symbol(name) ⇒ GrammarSymbol?
- #symbol_by_id(id) ⇒ GrammarSymbol?
- #terminals ⇒ Array[GrammarSymbol]
- #to_h ⇒ Hash[Symbol, untyped]
- #validate_mode(mode) ⇒ void
- #validate_starts(start, starts, mode) ⇒ Array[String]
- #validate_user_code_chunks ⇒ void
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.
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() @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_name ⇒ String (readonly)
156 157 158 |
# File 'lib/ibex/ir/grammar_ir.rb', line 156 def class_name @class_name end |
#conversions ⇒ Hash[String, String] (readonly)
173 174 175 |
# File 'lib/ibex/ir/grammar_ir.rb', line 173 def conversions @conversions end |
#expect ⇒ Integer (readonly)
161 162 163 |
# File 'lib/ibex/ir/grammar_ir.rb', line 161 def expect @expect end |
#expect_rr ⇒ Integer? (readonly)
162 163 164 |
# File 'lib/ibex/ir/grammar_ir.rb', line 162 def expect_rr @expect_rr end |
#grammar_tests ⇒ Array[grammar_test] (readonly)
165 166 167 |
# File 'lib/ibex/ir/grammar_ir.rb', line 165 def grammar_tests @grammar_tests end |
#lexer ⇒ Lexer? (readonly)
166 167 168 |
# File 'lib/ibex/ir/grammar_ir.rb', line 166 def lexer @lexer end |
#migration ⇒ migration_metadata? (readonly)
177 178 179 |
# File 'lib/ibex/ir/grammar_ir.rb', line 177 def migration @migration end |
#mode ⇒ grammar_mode (readonly)
160 161 162 |
# File 'lib/ibex/ir/grammar_ir.rb', line 160 def mode @mode end |
#options ⇒ grammar_options (readonly)
168 169 170 |
# File 'lib/ibex/ir/grammar_ir.rb', line 168 def @options end |
#parser_parameters ⇒ Array[parser_parameter] (readonly)
163 164 165 |
# File 'lib/ibex/ir/grammar_ir.rb', line 163 def parser_parameters @parser_parameters end |
#productions ⇒ Array[Production] (readonly)
170 171 172 |
# File 'lib/ibex/ir/grammar_ir.rb', line 170 def productions @productions end |
#recovery ⇒ recovery_policy (readonly)
167 168 169 |
# File 'lib/ibex/ir/grammar_ir.rb', line 167 def recovery @recovery end |
#schema_version ⇒ Integer (readonly)
175 176 177 |
# File 'lib/ibex/ir/grammar_ir.rb', line 175 def schema_version @schema_version end |
#source_provenance ⇒ source_provenance? (readonly)
176 177 178 |
# File 'lib/ibex/ir/grammar_ir.rb', line 176 def source_provenance @source_provenance end |
#start ⇒ String (readonly)
158 159 160 |
# File 'lib/ibex/ir/grammar_ir.rb', line 158 def start @start end |
#starts ⇒ Array[String] (readonly)
159 160 161 |
# File 'lib/ibex/ir/grammar_ir.rb', line 159 def starts @starts end |
#superclass ⇒ String? (readonly)
157 158 159 |
# File 'lib/ibex/ir/grammar_ir.rb', line 157 def superclass @superclass end |
#symbols ⇒ Array[GrammarSymbol] (readonly)
169 170 171 |
# File 'lib/ibex/ir/grammar_ir.rb', line 169 def symbols @symbols end |
#user_code ⇒ Hash[String, String] (readonly)
171 172 173 |
# File 'lib/ibex/ir/grammar_ir.rb', line 171 def user_code @user_code end |
#user_code_chunks ⇒ user_code_chunks (readonly)
172 173 174 |
# File 'lib/ibex/ir/grammar_ir.rb', line 172 def user_code_chunks @user_code_chunks end |
#value_printers ⇒ Array[value_printer] (readonly)
164 165 166 |
# File 'lib/ibex/ir/grammar_ir.rb', line 164 def value_printers @value_printers end |
#warnings ⇒ Array[grammar_warning] (readonly)
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.
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.
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.
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 |
#nonterminals ⇒ Array[GrammarSymbol]
233 |
# File 'lib/ibex/ir/grammar_ir.rb', line 233 def nonterminals = @symbols.select(&:nonterminal?) |
#symbol(name) ⇒ GrammarSymbol?
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?
229 230 |
# File 'lib/ibex/ir/grammar_ir.rb', line 229 def symbol_by_id(id) = @symbols_by_id[id] # @rbs () -> Array[GrammarSymbol] |
#terminals ⇒ Array[GrammarSymbol]
231 232 |
# File 'lib/ibex/ir/grammar_ir.rb', line 231 def terminals = @symbols.select(&:terminal?) # @rbs () -> Array[GrammarSymbol] |
#to_h ⇒ 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.
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]
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_chunks ⇒ void
This method returns an undefined value.
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 |