Module: Ibex::NormalizeRecoveryDeclarations

Included in:
Normalizer
Defined in:
lib/ibex/normalize/recovery_declarations.rb,
sig/ibex/normalize/recovery_declarations.rbs

Overview

Recovery declaration extraction and post-interning symbol validation.

Instance Method Summary collapse

Instance Method Details

#read_grammar_test(declaration) ⇒ void

This method returns an undefined value.

RBS:

  • (Frontend::AST::GrammarTest declaration) -> void

Parameters:



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/ibex/normalize/recovery_declarations.rb', line 21

def read_grammar_test(declaration)
  # @type self: Normalizer
  fail_at(declaration.loc, "%test requires extended mode") unless @mode == :extended
  unless %i[accept reject].include?(declaration.expectation)
    fail_at(declaration.loc, "unknown %test expectation #{declaration.expectation.inspect}")
  end
  if @grammar_tests.any? do |test|
       test[:expectation] == declaration.expectation && test[:source] == declaration.source
     end
    fail_at(declaration.loc, "duplicate %test #{declaration.expectation} source")
  end

  @grammar_tests << {
    expectation: declaration.expectation,
    source: declaration.source,
    loc: declaration.loc.to_h
  }
end

#read_on_error_reduce_declaration(declaration) ⇒ void

This method returns an undefined value.

RBS:

  • (Frontend::AST::OnErrorReduce declaration) -> void

Parameters:



54
55
56
57
58
59
60
61
62
63
64
# File 'lib/ibex/normalize/recovery_declarations.rb', line 54

def read_on_error_reduce_declaration(declaration)
  # @type self: Normalizer
  fail_at(declaration.loc, "%on_error_reduce requires at least one nonterminal") if declaration.names.empty?
  declaration.names.each do |name|
    fail_at(declaration.loc, "duplicate %on_error_reduce symbol #{name}") if
      @on_error_reduce_locations.key?(name)

    @on_error_reduce_locations[name] = declaration.loc
  end
  @on_error_reduce_groups << declaration.names
end

#read_parser_control_declaration(declaration) ⇒ void

This method returns an undefined value.

RBS:

  • (Frontend::AST::Start | Frontend::AST::Recovery | Frontend::AST::OnErrorReduce | Frontend::AST::GrammarTest declaration) -> void

Parameters:



10
11
12
13
14
15
16
17
18
# File 'lib/ibex/normalize/recovery_declarations.rb', line 10

def read_parser_control_declaration(declaration)
  # @type self: Normalizer
  case declaration
  when Frontend::AST::Start then read_start_declaration(declaration)
  when Frontend::AST::Recovery then read_recovery_declaration(declaration)
  when Frontend::AST::OnErrorReduce then read_on_error_reduce_declaration(declaration)
  when Frontend::AST::GrammarTest then read_grammar_test(declaration)
  end
end

#read_recovery_declaration(declaration) ⇒ void

This method returns an undefined value.

RBS:

  • (Frontend::AST::Recovery declaration) -> void

Parameters:



41
42
43
44
45
46
47
48
49
50
51
# File 'lib/ibex/normalize/recovery_declarations.rb', line 41

def read_recovery_declaration(declaration)
  # @type self: Normalizer
  fail_at(declaration.loc, "duplicate %recover declaration") if @recovery_sync_location
  fail_at(declaration.loc, "%recover sync requires at least one token") if declaration.sync_tokens.empty?
  unless declaration.sync_tokens.uniq.length == declaration.sync_tokens.length
    fail_at(declaration.loc, "%recover sync tokens must be unique")
  end

  @recovery_sync_tokens = declaration.sync_tokens
  @recovery_sync_location = declaration.loc
end

#validate_recovery_declarationsvoid

This method returns an undefined value.

RBS:

  • () -> void



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/ibex/normalize/recovery_declarations.rb', line 67

def validate_recovery_declarations
  # @type self: Normalizer
  @recovery_sync_tokens.each do |name|
    definition = @symbols_by_name[name]
    unless definition&.terminal? && definition.name != "error"
      fail_at(@recovery_sync_location || @ast.loc, "%recover sync references nonterminal or missing token #{name}")
    end
  end
  @on_error_reduce_groups.flatten.each do |name|
    definition = @symbols_by_name[name]
    unless definition&.nonterminal?
      location = @on_error_reduce_locations.fetch(name)
      fail_at(location, "%on_error_reduce references terminal or missing nonterminal #{name}")
    end
  end
end