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
- #mode ⇒ grammar_mode readonly
- #options ⇒ grammar_options readonly
- #parser_contract ⇒ ParserContract 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, source_provenance: nil, expect_rr: nil, parser_parameters: [], value_printers: [], grammar_tests: [], recovery: nil, lexer: nil, mode: :default, starts: nil, parser_contract: ParserContract.new) ⇒ Grammar
constructor
rubocop:disable Metrics/AbcSize, Metrics/ParameterLists Immutable current IR is constructed from explicit public fields.
- #initialize_current(class_name:, superclass:, start:, expect:, options:, symbols:, productions:, user_code:, conversions:, warnings:, user_code_chunks:, source_provenance:, expect_rr:, parser_parameters:, value_printers:, grammar_tests:, recovery:, lexer:, mode:, starts:, parser_contract:) ⇒ void
- #nonterminals ⇒ Array[GrammarSymbol]
- #symbol(name) ⇒ GrammarSymbol?
- #symbol_by_id(id) ⇒ GrammarSymbol?
- #terminals ⇒ Array[GrammarSymbol]
- #to_h ⇒ Hash[Symbol, Object?]
- #validate_current_metadata(parser_contract) ⇒ void
- #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, source_provenance: nil, expect_rr: nil, parser_parameters: [], value_printers: [], grammar_tests: [], recovery: nil, lexer: nil, mode: :default, starts: nil, parser_contract: ParserContract.new) ⇒ Grammar
rubocop:disable Metrics/AbcSize, Metrics/ParameterLists Immutable current IR is constructed from explicit public fields.
193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/ibex/ir/grammar_ir.rb', line 193 def initialize(class_name:, superclass:, start:, expect:, options:, symbols:, productions:, user_code:, conversions:, warnings:, user_code_chunks: nil, source_provenance: nil, expect_rr: nil, parser_parameters: [], value_printers: [], grammar_tests: [], recovery: nil, lexer: nil, mode: :default, starts: nil, parser_contract: ParserContract.new) initialize_current( class_name: class_name, superclass: superclass, start: start, expect: expect, options: , symbols: symbols, productions: productions, user_code: user_code, conversions: conversions, warnings: warnings, user_code_chunks: user_code_chunks, source_provenance: source_provenance, expect_rr: expect_rr, parser_parameters: parser_parameters, value_printers: value_printers, grammar_tests: grammar_tests, recovery: recovery, lexer: lexer, mode: mode, starts: starts, parser_contract: parser_contract ) end |
Instance Attribute Details
#class_name ⇒ String (readonly)
159 160 161 |
# File 'lib/ibex/ir/grammar_ir.rb', line 159 def class_name @class_name end |
#conversions ⇒ Hash[String, String] (readonly)
176 177 178 |
# File 'lib/ibex/ir/grammar_ir.rb', line 176 def conversions @conversions end |
#expect ⇒ Integer (readonly)
164 165 166 |
# File 'lib/ibex/ir/grammar_ir.rb', line 164 def expect @expect end |
#expect_rr ⇒ Integer? (readonly)
165 166 167 |
# File 'lib/ibex/ir/grammar_ir.rb', line 165 def expect_rr @expect_rr end |
#grammar_tests ⇒ Array[grammar_test] (readonly)
168 169 170 |
# File 'lib/ibex/ir/grammar_ir.rb', line 168 def grammar_tests @grammar_tests end |
#lexer ⇒ Lexer? (readonly)
169 170 171 |
# File 'lib/ibex/ir/grammar_ir.rb', line 169 def lexer @lexer end |
#mode ⇒ grammar_mode (readonly)
163 164 165 |
# File 'lib/ibex/ir/grammar_ir.rb', line 163 def mode @mode end |
#options ⇒ grammar_options (readonly)
171 172 173 |
# File 'lib/ibex/ir/grammar_ir.rb', line 171 def @options end |
#parser_contract ⇒ ParserContract (readonly)
180 181 182 |
# File 'lib/ibex/ir/grammar_ir.rb', line 180 def parser_contract @parser_contract end |
#parser_parameters ⇒ Array[parser_parameter] (readonly)
166 167 168 |
# File 'lib/ibex/ir/grammar_ir.rb', line 166 def parser_parameters @parser_parameters end |
#productions ⇒ Array[Production] (readonly)
173 174 175 |
# File 'lib/ibex/ir/grammar_ir.rb', line 173 def productions @productions end |
#recovery ⇒ recovery_policy (readonly)
170 171 172 |
# File 'lib/ibex/ir/grammar_ir.rb', line 170 def recovery @recovery end |
#schema_version ⇒ Integer (readonly)
178 179 180 |
# File 'lib/ibex/ir/grammar_ir.rb', line 178 def schema_version @schema_version end |
#source_provenance ⇒ source_provenance? (readonly)
179 180 181 |
# File 'lib/ibex/ir/grammar_ir.rb', line 179 def source_provenance @source_provenance end |
#start ⇒ String (readonly)
161 162 163 |
# File 'lib/ibex/ir/grammar_ir.rb', line 161 def start @start end |
#starts ⇒ Array[String] (readonly)
162 163 164 |
# File 'lib/ibex/ir/grammar_ir.rb', line 162 def starts @starts end |
#superclass ⇒ String? (readonly)
160 161 162 |
# File 'lib/ibex/ir/grammar_ir.rb', line 160 def superclass @superclass end |
#symbols ⇒ Array[GrammarSymbol] (readonly)
172 173 174 |
# File 'lib/ibex/ir/grammar_ir.rb', line 172 def symbols @symbols end |
#user_code ⇒ Hash[String, String] (readonly)
174 175 176 |
# File 'lib/ibex/ir/grammar_ir.rb', line 174 def user_code @user_code end |
#user_code_chunks ⇒ user_code_chunks (readonly)
175 176 177 |
# File 'lib/ibex/ir/grammar_ir.rb', line 175 def user_code_chunks @user_code_chunks end |
#value_printers ⇒ Array[value_printer] (readonly)
167 168 169 |
# File 'lib/ibex/ir/grammar_ir.rb', line 167 def value_printers @value_printers end |
#warnings ⇒ Array[grammar_warning] (readonly)
177 178 179 |
# File 'lib/ibex/ir/grammar_ir.rb', line 177 def warnings @warnings end |
Instance Method Details
#append_optional_metadata(value) ⇒ void
This method returns an undefined value.
292 293 294 295 296 297 298 299 |
# File 'lib/ibex/ir/grammar_ir.rb', line 292 def (value) (value) (value) value[:user_code_chunks] = @user_code_chunks.transform_values { |chunks| chunks.map(&:to_h) } \ unless @user_code_chunks.empty? value[:source_provenance] = @source_provenance value[:parser_contract] = @parser_contract.to_h end |
#append_parser_metadata(value) ⇒ void
This method returns an undefined value.
302 303 304 305 306 307 308 309 310 |
# File 'lib/ibex/ir/grammar_ir.rb', line 302 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? value[:lexer] = @lexer.to_h if @lexer end |
#append_recovery_metadata(value) ⇒ void
This method returns an undefined value.
313 314 315 316 317 |
# File 'lib/ibex/ir/grammar_ir.rb', line 313 def (value) return if @recovery[:sync_tokens].empty? && @recovery[:on_error_reduce].empty? value[:recovery] = @recovery end |
#initialize_current(class_name:, superclass:, start:, expect:, options:, symbols:, productions:, user_code:, conversions:, warnings:, user_code_chunks:, source_provenance:, expect_rr:, parser_parameters:, value_printers:, grammar_tests:, recovery:, lexer:, mode:, starts:, parser_contract:) ⇒ void
This method returns an undefined value.
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 |
# File 'lib/ibex/ir/grammar_ir.rb', line 214 def initialize_current(class_name:, superclass:, start:, expect:, options:, symbols:, productions:, user_code:, conversions:, warnings:, user_code_chunks:, source_provenance:, expect_rr:, parser_parameters:, value_printers:, grammar_tests:, recovery:, lexer:, mode:, starts:, parser_contract:) validate_mode(mode) normalized_starts = validate_starts(start, starts, mode) (parser_contract) @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) @parser_contract = IR.deep_freeze(parser_contract) @symbols_by_name = @symbols.to_h { |symbol| [symbol.name, symbol] }.freeze @symbols_by_id = @symbols.to_h { |symbol| [symbol.id, symbol] }.freeze freeze end |
#nonterminals ⇒ Array[GrammarSymbol]
259 |
# File 'lib/ibex/ir/grammar_ir.rb', line 259 def nonterminals = @symbols.select(&:nonterminal?) |
#symbol(name) ⇒ GrammarSymbol?
253 254 |
# File 'lib/ibex/ir/grammar_ir.rb', line 253 def symbol(name) = @symbols_by_name[name] # @rbs (Integer? id) -> GrammarSymbol? |
#symbol_by_id(id) ⇒ GrammarSymbol?
255 256 |
# File 'lib/ibex/ir/grammar_ir.rb', line 255 def symbol_by_id(id) = @symbols_by_id[id] # @rbs () -> Array[GrammarSymbol] |
#terminals ⇒ Array[GrammarSymbol]
257 258 |
# File 'lib/ibex/ir/grammar_ir.rb', line 257 def terminals = @symbols.select(&:terminal?) # @rbs () -> Array[GrammarSymbol] |
#to_h ⇒ Hash[Symbol, Object?]
262 263 264 265 266 267 268 269 270 271 |
# File 'lib/ibex/ir/grammar_ir.rb', line 262 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(&:to_h), productions: @productions.map(&:to_h), user_code: @user_code, conversions: @conversions, warnings: @warnings } #: Hash[Symbol, Object?] (value) value end |
#validate_current_metadata(parser_contract) ⇒ void
This method returns an undefined value.
329 330 331 332 333 |
# File 'lib/ibex/ir/grammar_ir.rb', line 329 def (parser_contract) return if parser_contract.is_a?(ParserContract) raise ArgumentError, "parser_contract must be a ParserContract" end |
#validate_mode(mode) ⇒ void
This method returns an undefined value.
276 277 278 |
# File 'lib/ibex/ir/grammar_ir.rb', line 276 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]
281 282 283 284 285 286 287 288 289 |
# File 'lib/ibex/ir/grammar_ir.rb', line 281 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.
320 321 322 323 324 325 326 |
# File 'lib/ibex/ir/grammar_ir.rb', line 320 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 |