Module: Ibex::NormalizeDeclarations

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

Overview

Declaration extraction used by Normalizer.

Instance Method Summary collapse

Instance Method Details

#read_conversions(declaration) ⇒ void

This method returns an undefined value.

RBS:

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

Parameters:



141
142
143
144
# File 'lib/ibex/normalize/declarations.rb', line 141

def read_conversions(declaration)
  # @type self: Normalizer
  declaration.pairs.each { |pair| @conversions[pair.name] = pair.expression }
end

#read_declaration(declaration) ⇒ void

This method returns an undefined value.

RBS:

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

Parameters:

  • declaration (Frontend::AST::declaration)


36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/ibex/normalize/declarations.rb', line 36

def read_declaration(declaration) # rubocop:disable Metrics/CyclomaticComplexity
  # @type self: Normalizer
  case declaration
  when Frontend::AST::Tokens then read_tokens(declaration)
  when Frontend::AST::Precedence then read_precedence(declaration)
  when Frontend::AST::Options then read_options(declaration)
  when Frontend::AST::Expect then @expected_conflicts = declaration.conflicts
  when Frontend::AST::ExpectRR then @expected_rr_conflicts = declaration.conflicts
  when Frontend::AST::Start, Frontend::AST::Recovery, Frontend::AST::OnErrorReduce, Frontend::AST::GrammarTest
    read_parser_control_declaration(declaration)
  when Frontend::AST::Lexer
    fail_at(declaration.loc, "duplicate lexer declaration") if @lexer_declaration
    @lexer_declaration = declaration
  when Frontend::AST::Convert then read_conversions(declaration)
  when Frontend::AST::DisplayName, Frontend::AST::SemanticType, Frontend::AST::Parameter, Frontend::AST::Printer
    read_extended_declaration(declaration)
  when Frontend::AST::Include then fail_at(declaration.loc, "includes must be resolved before normalization")
  end
end

#read_declarationsvoid

This method returns an undefined value.

RBS:

  • () -> void



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/ibex/normalize/declarations.rb', line 9

def read_declarations
  # @type self: Normalizer
  @declared_tokens = {} #: Hash[String, IR::location]
  @precedence = {} #: Hash[String, IR::precedence]
  @precedence_locations = {} #: Hash[String, IR::location]
  @display_names = {} #: Hash[String, String]
  @display_name_locations = {} #: Hash[String, IR::location]
  @semantic_types = {} #: Hash[String, String]
  @semantic_type_locations = {} #: Hash[String, IR::location]
  @options = { result_var: true, omit_action_call: true }
  @options[:cst] = true if @ast.cst
  @expected_conflicts = 0
  @expected_rr_conflicts = nil
  @conversions = {} #: Hash[String, String]
  @parser_parameters = [] #: Array[IR::parser_parameter]
  @value_printers = {} #: Hash[String, IR::value_printer]
  @recovery_sync_tokens = [] #: Array[String]
  @recovery_sync_location = nil #: Frontend::Location?
  @on_error_reduce_groups = [] #: Array[Array[String]]
  @on_error_reduce_locations = {} #: Hash[String, Frontend::Location]
  @grammar_tests = [] #: Array[IR::grammar_test]
  @lexer_declaration = nil #: Frontend::AST::Lexer?
  @node_shapes = {} #: Hash[String, Array[String]]
  @ast.declarations.each { |declaration| read_declaration(declaration) }
end

#read_extended_declaration(declaration) ⇒ void

This method returns an undefined value.

RBS:

  • (Frontend::AST::symbol_metadata | Frontend::AST::Parameter | Frontend::AST::Printer declaration) -> void

Parameters:



73
74
75
76
77
78
79
80
81
# File 'lib/ibex/normalize/declarations.rb', line 73

def read_extended_declaration(declaration)
  if declaration.is_a?(Frontend::AST::Parameter)
    read_parser_parameter(declaration)
  elsif declaration.is_a?(Frontend::AST::Printer)
    read_value_printer(declaration)
  else
    (declaration)
  end
end

#read_option(name, location) ⇒ void

This method returns an undefined value.

RBS:

  • (String name, Frontend::Location location) -> void

Parameters:



182
183
184
185
186
187
188
189
190
191
# File 'lib/ibex/normalize/declarations.rb', line 182

def read_option(name, location)
  # @type self: Normalizer
  case name
  when "no_result_var" then @options[:result_var] = false
  when "result_var" then @options[:result_var] = true
  when "omit_action_call" then @options[:omit_action_call] = true
  when "no_omit_action_call" then @options[:omit_action_call] = false
  else fail_at(location, "unknown option #{name}")
  end
end

#read_options(declaration) ⇒ void

This method returns an undefined value.

RBS:

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

Parameters:



136
137
138
# File 'lib/ibex/normalize/declarations.rb', line 136

def read_options(declaration)
  declaration.names.each { |name| read_option(name, declaration.loc) }
end

#read_parser_parameter(declaration) ⇒ void

This method returns an undefined value.

RBS:

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

Parameters:



108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/ibex/normalize/declarations.rb', line 108

def read_parser_parameter(declaration)
  # @type self: Normalizer
  if @parser_parameters.any? { |parameter| parameter[:name] == declaration.name }
    fail_at(declaration.loc, "duplicate %param declaration for #{declaration.name}")
  end
  unless declaration.name.match?(/\A[a-z_][a-zA-Z0-9_]*\z/)
    fail_at(declaration.loc, "%param name #{declaration.name.inspect} must be a Ruby local identifier")
  end
  if Normalizer::RUBY_KEYWORDS.include?(declaration.name)
    fail_at(declaration.loc, "%param name #{declaration.name.inspect} is a Ruby keyword")
  end

  @parser_parameters << { name: declaration.name, semantic_type: declaration.semantic_type }
end

#read_precedence(declaration) ⇒ void

This method returns an undefined value.

RBS:

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

Parameters:



169
170
171
172
173
174
175
176
177
178
179
# File 'lib/ibex/normalize/declarations.rb', line 169

def read_precedence(declaration)
  # @type self: Normalizer
  count = declaration.levels.length
  declaration.levels.each_with_index do |level, index|
    numeric_level = declaration.direction == :high_to_low ? count - index : index + 1
    level.symbols.each do |name|
      @precedence[name] = { associativity: level.associativity, level: numeric_level }
      @precedence_locations[name] = level.loc.to_h
    end
  end
end

#read_start_declaration(declaration) ⇒ void

This method returns an undefined value.

RBS:

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

Parameters:



57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/ibex/normalize/declarations.rb', line 57

def read_start_declaration(declaration)
  # @type self: Normalizer
  fail_at(declaration.loc, "duplicate start declaration") if @explicit_starts
  if declaration.names.length > 1 && @mode != :extended
    fail_at(declaration.loc, "multiple start symbols require extended mode")
  end
  fail_at(declaration.loc, "start declaration requires at least one symbol") if declaration.names.empty?
  unless declaration.names.uniq.length == declaration.names.length
    fail_at(declaration.loc, "start symbols must be unique")
  end

  @explicit_starts = declaration.names
  @start_location = declaration.loc
end

#read_symbol_metadata(declaration, values, locations, label) ⇒ void

This method returns an undefined value.

RBS:

  • (Frontend::AST::symbol_metadata declaration, Hash[String, String] values, Hash[String, IR::location] locations, String label) -> void

Parameters:

  • declaration (Frontend::AST::symbol_metadata)
  • values (Hash[String, String])
  • locations (Hash[String, IR::location])
  • label (String)


158
159
160
161
162
163
164
165
166
# File 'lib/ibex/normalize/declarations.rb', line 158

def (declaration, values, locations, label)
  # @type self: Normalizer
  if values.key?(declaration.name)
    fail_at(declaration.loc, "duplicate #{label} declaration for #{declaration.name}")
  end

  values[declaration.name] = declaration.value
  locations[declaration.name] = declaration.loc.to_h
end

#read_symbol_metadata_declaration(declaration) ⇒ void

This method returns an undefined value.

RBS:

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

Parameters:

  • declaration (Frontend::AST::symbol_metadata)


147
148
149
150
151
152
153
154
# File 'lib/ibex/normalize/declarations.rb', line 147

def (declaration)
  # @type self: Normalizer
  if declaration.is_a?(Frontend::AST::DisplayName)
    (declaration, @display_names, @display_name_locations, "display")
  else
    (declaration, @semantic_types, @semantic_type_locations, "type")
  end
end

#read_tokens(declaration) ⇒ void

This method returns an undefined value.

RBS:

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

Parameters:



124
125
126
127
128
129
130
131
132
133
# File 'lib/ibex/normalize/declarations.rb', line 124

def read_tokens(declaration)
  # @type self: Normalizer
  declaration.names.each { |name| @declared_tokens[name] = declaration.loc.to_h }
  (declaration.aliases || {}).each do |name, value|
    fail_at(declaration.loc, "duplicate display declaration for #{name}") if @display_names.key?(name)

    @display_names[name] = value
    @display_name_locations[name] = declaration.loc.to_h
  end
end

#read_value_printer(declaration) ⇒ void

This method returns an undefined value.

RBS:

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

Parameters:



84
85
86
87
88
89
90
91
92
93
# File 'lib/ibex/normalize/declarations.rb', line 84

def read_value_printer(declaration)
  # @type self: Normalizer
  if @value_printers.key?(declaration.name)
    fail_at(declaration.loc, "duplicate %printer declaration for #{declaration.name}")
  end

  @value_printers[declaration.name] = {
    symbol: declaration.name, code: declaration.code, loc: declaration.loc.to_h
  }
end

#validate_value_printersvoid

This method returns an undefined value.

RBS:

  • () -> void



96
97
98
99
100
101
102
103
104
105
# File 'lib/ibex/normalize/declarations.rb', line 96

def validate_value_printers
  @value_printers.each_value do |printer|
    next if @symbols_by_name.key?(printer[:symbol])

    location = printer[:loc]
    raise Ibex::Error,
          "#{location[:file]}:#{location[:line]}:#{location[:column]}: " \
          "%printer references missing symbol #{printer[:symbol]}"
  end
end