Class: Ibex::Frontend::GeneratedParserBase

Inherits:
Runtime::Parser
  • Object
show all
Includes:
GeneratedParserIncludes, GeneratedParserMetadata, GeneratedParserParameters
Defined in:
lib/ibex/frontend/generated_parser_base.rb,
sig/ibex/frontend/generated_parser_base.rbs

Overview

Semantic support and token delivery for the generated grammar parser. rubocop:disable Metrics/ClassLength -- generated grammar semantics share one parser support surface.

Direct Known Subclasses

GeneratedParser

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from GeneratedParserParameters

#build_parameterized_reference, #build_rule, #build_rule_parameters, #require_adjacency!

Methods included from GeneratedParserIncludes

#build_fragment, #build_include, #fragment_root_declaration_name, #reject_fragment_root_declarations

Methods included from GeneratedParserMetadata

#build_display_name, #build_semantic_type, #build_symbol_metadata, #decode_metadata_value

Constructor Details

#initialize(tokens, mode: :default) ⇒ GeneratedParserBase

Returns a new instance of GeneratedParserBase.

RBS:

  • (Array[Token] tokens, ?mode: Symbol) -> void

Parameters:

  • tokens (Array[Token])
  • mode: (Symbol) (defaults to: :default)


22
23
24
25
26
27
28
# File 'lib/ibex/frontend/generated_parser_base.rb', line 22

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

  super()
  @adapter = TokenAdapter.new(tokens, extended: mode == :extended)
  @mode = mode
end

Instance Attribute Details

#diagnostic_tokenToken? (readonly)

Signature:

  • Token?

Returns:



16
17
18
# File 'lib/ibex/frontend/generated_parser_base.rb', line 16

def diagnostic_token
  @diagnostic_token
end

Instance Method Details

#append_user_code(blocks, token) ⇒ AST::user_code

RBS:

  • (AST::user_code blocks, Token token) -> AST::user_code

Parameters:

  • blocks (AST::user_code)
  • token (Token)

Returns:

  • (AST::user_code)


351
352
353
354
355
# File 'lib/ibex/frontend/generated_parser_base.rb', line 351

def append_user_code(blocks, token)
  value = token_user_code(token)
  blocks[value[:name]] << AST::UserCode.new(name: value[:name], code: value[:code], loc: token.location)
  blocks
end

#apply_suffixes(item, suffixes) ⇒ AST::item

RBS:

  • (AST::item item, Array[Token] suffixes) -> AST::item

Parameters:

  • item (AST::item)
  • suffixes (Array[Token])

Returns:

  • (AST::item)


338
339
340
341
342
343
344
345
346
347
348
# File 'lib/ibex/frontend/generated_parser_base.rb', line 338

def apply_suffixes(item, suffixes)
  suffixes.reduce(item) do |wrapped, suffix|
    extended_only!(suffix.location, "EBNF suffixes")
    case token_string(suffix)
    when "?" then AST::Optional.new(item: wrapped, loc: suffix.location)
    when "*" then AST::Star.new(item: wrapped, loc: suffix.location)
    when "+" then AST::Plus.new(item: wrapped, loc: suffix.location)
    else raise Ibex::Error, "#{suffix.location}: unknown EBNF suffix #{suffix.value.inspect}"
    end
  end
end

#build_action(token) ⇒ AST::InlineAction

RBS:

  • (Token token) -> AST::InlineAction

Parameters:

Returns:



320
321
322
# File 'lib/ibex/frontend/generated_parser_base.rb', line 320

def build_action(token)
  AST::InlineAction.new(code: token_string(token), loc: token.location)
end

#build_alternative(items, precedence, node_annotation) ⇒ AST::Alternative

RBS:

  • (Array[AST::item] items, Token? precedence, AST::NodeAnnotation? node_annotation) -> AST::Alternative

Parameters:

Returns:



260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
# File 'lib/ibex/frontend/generated_parser_base.rb', line 260

def build_alternative(items, precedence, node_annotation)
  last_token = @adapter.last_token
  location = item_start_location(items.first) || precedence&.location || last_token&.location
  raise Ibex::Error, "missing alternative location" unless location

  action = nil #: AST::InlineAction?
  last_item = items.last
  if last_item.is_a?(AST::InlineAction)
    items.pop
    action = last_item
  end
  AST::Alternative.new(
    items: items, action: action, precedence: precedence && token_string(precedence),
    node_annotation: node_annotation, loc: location
  )
end

#build_conversion(name_token, literal_token) ⇒ AST::Conversion

RBS:

  • (Token name_token, Token literal_token) -> AST::Conversion

Parameters:

Returns:



243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
# File 'lib/ibex/frontend/generated_parser_base.rb', line 243

def build_conversion(name_token, literal_token)
  unless name_token.location.line == literal_token.location.line
    fail_at(name_token.location, "expected a quoted Ruby conversion expression")
  end

  literal = token_string(literal_token)
  expression = if literal.start_with?('"')
                 literal.undump
               else
                 (literal[1...-1] || "").gsub("\\'", "'").gsub("\\\\", "\\")
               end
  AST::Conversion.new(name: token_string(name_token), expression: expression, loc: name_token.location)
rescue RuntimeError => e
  fail_at(name_token.location, "invalid conversion expression: #{e.message}")
end

#build_convert(keyword, pairs) ⇒ AST::Convert

RBS:

  • (Token keyword, Array[AST::Conversion] pairs) -> AST::Convert

Parameters:

Returns:



238
239
240
# File 'lib/ibex/frontend/generated_parser_base.rb', line 238

def build_convert(keyword, pairs)
  AST::Convert.new(pairs: pairs, loc: keyword.location)
end

#build_empty(token) ⇒ AST::Empty

RBS:

  • (Token token) -> AST::Empty

Parameters:

Returns:



286
287
288
289
# File 'lib/ibex/frontend/generated_parser_base.rb', line 286

def build_empty(token)
  extended_only!(token.location, "%empty")
  AST::Empty.new(loc: token.location)
end

#build_expect(keyword, integer) ⇒ AST::Expect

RBS:

  • (Token keyword, Token integer) -> AST::Expect

Parameters:

Returns:



154
155
156
# File 'lib/ibex/frontend/generated_parser_base.rb', line 154

def build_expect(keyword, integer)
  AST::Expect.new(conflicts: token_integer(integer), loc: keyword.location)
end

#build_expect_rr(keyword, integer) ⇒ AST::ExpectRR

RBS:

  • (Token keyword, Token integer) -> AST::ExpectRR

Parameters:

Returns:



159
160
161
162
# File 'lib/ibex/frontend/generated_parser_base.rb', line 159

def build_expect_rr(keyword, integer)
  extended_only!(keyword.location, "expect-rr declarations")
  AST::ExpectRR.new(conflicts: token_integer(integer), loc: keyword.location)
end

#build_grammar_test(keyword, expectation, source) ⇒ AST::GrammarTest

RBS:

  • (Token keyword, Token expectation, Token source) -> AST::GrammarTest

Parameters:

Returns:



204
205
206
207
208
209
210
211
212
213
214
215
# File 'lib/ibex/frontend/generated_parser_base.rb', line 204

def build_grammar_test(keyword, expectation, source)
  extended_only!(keyword.location, "%test")
  expected = token_string(expectation)
  fail_at(expectation.location, "expected accept or reject, got #{expected}") unless
    %w[accept reject].include?(expected)
  literal = token_string(source)
  fail_at(source.location, "%test source must use a double-quoted string") unless literal.start_with?('"')

  AST::GrammarTest.new(expectation: expected.to_sym, source: literal.undump, loc: keyword.location)
rescue RuntimeError => e
  fail_at(source.location, "invalid %test source: #{e.message}")
end

#build_group(opening, alternatives, suffixes) ⇒ AST::item

RBS:

  • (Token opening, Array[Array[AST::item]] alternatives, Array[Token] suffixes) -> AST::item

Parameters:

  • opening (Token)
  • alternatives (Array[Array[AST::item]])
  • suffixes (Array[Token])

Returns:

  • (AST::item)


325
326
327
328
# File 'lib/ibex/frontend/generated_parser_base.rb', line 325

def build_group(opening, alternatives, suffixes)
  extended_only!(opening.location, "EBNF groups")
  apply_suffixes(AST::Group.new(alternatives: alternatives, loc: opening.location), suffixes)
end

#build_lexer(keyword, entries) ⇒ AST::Lexer

RBS:

  • (Token keyword, Array[AST::lexer_entry] entries) -> AST::Lexer

Parameters:

  • keyword (Token)
  • entries (Array[AST::lexer_entry])

Returns:



218
219
220
221
# File 'lib/ibex/frontend/generated_parser_base.rb', line 218

def build_lexer(keyword, entries)
  extended_only!(keyword.location, "lexer declarations")
  AST::Lexer.new(definitions: entries, loc: keyword.location)
end

#build_lexer_rule(kind, name, pattern, action, marker) ⇒ AST::LexerRule

RBS:

  • (Symbol kind, Token? name, Token pattern, Token? action, Token marker) -> AST::LexerRule

Parameters:

Returns:



224
225
226
227
228
229
230
# File 'lib/ibex/frontend/generated_parser_base.rb', line 224

def build_lexer_rule(kind, name, pattern, action, marker)
  fail_at(marker.location, "on lexer rules require an action") if kind == :on && !action
  AST::LexerRule.new(
    kind: kind, token: name && token_string(name), pattern: token_string(pattern),
    pattern_kind: pattern.type, action: action && token_string(action), loc: marker.location
  )
end

#build_lexer_state(marker, name, entries) ⇒ AST::LexerState

RBS:

  • (Token marker, Token name, Array[AST::lexer_entry] entries) -> AST::LexerState

Parameters:

  • marker (Token)
  • name (Token)
  • entries (Array[AST::lexer_entry])

Returns:



233
234
235
# File 'lib/ibex/frontend/generated_parser_base.rb', line 233

def build_lexer_state(marker, name, entries)
  AST::LexerState.new(name: token_string(name), definitions: entries, loc: marker.location)
end

#build_node_annotation(marker, name, fields) ⇒ AST::NodeAnnotation

RBS:

  • (Token marker, Token name, Array[Token] fields) -> AST::NodeAnnotation

Parameters:

Returns:



278
279
280
281
282
283
# File 'lib/ibex/frontend/generated_parser_base.rb', line 278

def build_node_annotation(marker, name, fields)
  extended_only!(marker.location, "@node")
  AST::NodeAnnotation.new(
    name: token_string(name), fields: fields.map { |field| token_string(field) }, loc: marker.location
  )
end

#build_on_error_reduce(keyword, names) ⇒ AST::OnErrorReduce

RBS:

  • (Token keyword, Array[String] names) -> AST::OnErrorReduce

Parameters:

  • keyword (Token)
  • names (Array[String])

Returns:



197
198
199
200
201
# File 'lib/ibex/frontend/generated_parser_base.rb', line 197

def build_on_error_reduce(keyword, names)
  extended_only!(keyword.location, "%on_error_reduce")
  fail_at(keyword.location, "%on_error_reduce requires at least one nonterminal") if names.empty?
  AST::OnErrorReduce.new(names: names, loc: keyword.location)
end

#build_options(keyword, names) ⇒ AST::Options

RBS:

  • (Token keyword, Array[String] names) -> AST::Options

Parameters:

  • keyword (Token)
  • names (Array[String])

Returns:



149
150
151
# File 'lib/ibex/frontend/generated_parser_base.rb', line 149

def build_options(keyword, names)
  AST::Options.new(names: names, loc: keyword.location)
end

#build_parameter(keyword, name, type) ⇒ AST::Parameter

RBS:

  • (Token keyword, Token name, Token? type) -> AST::Parameter

Parameters:

Returns:



165
166
167
168
169
170
171
172
173
# File 'lib/ibex/frontend/generated_parser_base.rb', line 165

def build_parameter(keyword, name, type)
  extended_only!(keyword.location, "%param")
  if type && (keyword.location.line != name.location.line || name.location.line != type.location.line)
    fail_at(keyword.location, "%param declaration must be written on one line")
  end

  semantic_type = type && (type, "%param")
  AST::Parameter.new(name: token_string(name), semantic_type: semantic_type, loc: keyword.location)
end

#build_precedence(keyword, direction, levels) ⇒ AST::Precedence

RBS:

  • (Token keyword, Symbol direction, Array[AST::PrecedenceLevel] levels) -> AST::Precedence

Parameters:

Returns:



135
136
137
# File 'lib/ibex/frontend/generated_parser_base.rb', line 135

def build_precedence(keyword, direction, levels)
  AST::Precedence.new(direction: direction, levels: levels, loc: keyword.location)
end

#build_precedence_level(association, symbols) ⇒ AST::PrecedenceLevel

RBS:

  • (Token association, Array[String] symbols) -> AST::PrecedenceLevel

Parameters:

  • association (Token)
  • symbols (Array[String])

Returns:



140
141
142
143
144
145
146
# File 'lib/ibex/frontend/generated_parser_base.rb', line 140

def build_precedence_level(association, symbols)
  fail_at(association.location, "expected at least one precedence symbol") if symbols.empty?
  extended_only!(association.location, "%precedence") if token_string(association) == "precedence"

  AST::PrecedenceLevel.new(associativity: token_string(association).to_sym, symbols: symbols,
                           loc: association.location)
end

#build_printer(keyword, symbol, action) ⇒ AST::Printer

RBS:

  • (Token keyword, Token symbol, Token action) -> AST::Printer

Parameters:

Returns:



176
177
178
179
# File 'lib/ibex/frontend/generated_parser_base.rb', line 176

def build_printer(keyword, symbol, action)
  extended_only!(keyword.location, "%printer")
  AST::Printer.new(name: token_string(symbol), code: token_string(action), loc: keyword.location)
end

#build_recovery(keyword, kind, sync_tokens) ⇒ AST::Recovery

RBS:

  • (Token keyword, Token kind, Array[String] sync_tokens) -> AST::Recovery

Parameters:

  • keyword (Token)
  • kind (Token)
  • sync_tokens (Array[String])

Returns:



189
190
191
192
193
194
# File 'lib/ibex/frontend/generated_parser_base.rb', line 189

def build_recovery(keyword, kind, sync_tokens)
  extended_only!(keyword.location, "%recover")
  fail_at(kind.location, "expected sync, got #{kind.value}") unless token_string(kind) == "sync"
  fail_at(keyword.location, "%recover sync requires at least one token") if sync_tokens.empty?
  AST::Recovery.new(sync_tokens: sync_tokens, loc: keyword.location)
end

#build_root(class_token, class_parts, superclass, declarations, rules, user_code) ⇒ AST::Root

RBS:

  • (Token class_token, Array[String] class_parts, Array[String]? superclass, Array[AST::declaration] declarations, Array[AST::Rule] rules, AST::user_code user_code) -> AST::Root

Parameters:

  • class_token (Token)
  • class_parts (Array[String])
  • superclass (Array[String], nil)
  • declarations (Array[AST::declaration])
  • rules (Array[AST::Rule])
  • user_code (AST::user_code)

Returns:



106
107
108
109
110
111
# File 'lib/ibex/frontend/generated_parser_base.rb', line 106

def build_root(class_token, class_parts, superclass, declarations, rules, user_code)
  AST::Root.new(class_name: class_parts.join("::"), superclass: superclass&.join("::"),
                declarations: declarations, rules: rules, user_code: user_code, loc: class_token.location,
                extended: @mode == :extended || @adapter.extended_pragma? || @adapter.cst_pragma?,
                cst: @adapter.cst_pragma?)
end

#build_separated_list(function, item, separator) ⇒ AST::SeparatedList

RBS:

  • (Token function, AST::item item, AST::item separator) -> AST::SeparatedList

Parameters:

  • function (Token)
  • item (AST::item)
  • separator (AST::item)

Returns:



331
332
333
334
335
# File 'lib/ibex/frontend/generated_parser_base.rb', line 331

def build_separated_list(function, item, separator)
  extended_only!(function.location, "separated lists")
  AST::SeparatedList.new(item: item, separator: separator,
                         nonempty: function.value == "separated_nonempty_list", loc: function.location)
end

#build_start(keyword, names) ⇒ AST::Start

RBS:

  • (Token keyword, Array[String] names) -> AST::Start

Parameters:

  • keyword (Token)
  • names (Array[String])

Returns:



182
183
184
185
186
# File 'lib/ibex/frontend/generated_parser_base.rb', line 182

def build_start(keyword, names)
  fail_at(keyword.location, "start declaration requires at least one symbol") if names.empty?
  extended_only!(keyword.location, "multiple start symbols") if names.length > 1
  AST::Start.new(names: names, loc: keyword.location)
end

#build_symbol_reference(token, named_reference, suffixes) ⇒ AST::item

RBS:

  • (Token token, [Token, Token]? named_reference, Array[Token] suffixes) -> AST::item

Parameters:

Returns:

  • (AST::item)


303
304
305
306
307
308
# File 'lib/ibex/frontend/generated_parser_base.rb', line 303

def build_symbol_reference(token, named_reference, suffixes)
  item = AST::SymbolReference.new(
    name: token_string(token), named_reference: named_reference_value(named_reference), loc: token.location
  )
  apply_suffixes(item, suffixes)
end

#build_token_alias(name, value) ⇒ [ String, String ]

RBS:

  • (Token name, Token value) -> [String, String]

Parameters:

Returns:

  • ([ String, String ])


125
126
127
128
129
130
131
132
# File 'lib/ibex/frontend/generated_parser_base.rb', line 125

def build_token_alias(name, value)
  extended_only!(name.location, "token aliases")
  unless name.location.line == value.location.line
    fail_at(name.location, "token alias must be written on one line")
  end

  [token_string(name), (value, "token alias")]
end

#build_token_entry(token) ⇒ [ String, nil ]

RBS:

  • (Token token) -> [String, nil]

Parameters:

Returns:

  • ([ String, nil ])


120
121
122
# File 'lib/ibex/frontend/generated_parser_base.rb', line 120

def build_token_entry(token)
  [token_string(token), nil]
end

#build_tokens(keyword, entries) ⇒ AST::Tokens

RBS:

  • (Token keyword, Array[[String, String?]] entries) -> AST::Tokens

Parameters:

  • keyword (Token)
  • entries (Array[[ String, String? ]])

Returns:



114
115
116
117
# File 'lib/ibex/frontend/generated_parser_base.rb', line 114

def build_tokens(keyword, entries)
  aliases = entries.filter_map { |name, value| [name, value] if value }.to_h
  AST::Tokens.new(names: entries.map(&:first), aliases: aliases.empty? ? nil : aliases, loc: keyword.location)
end

#empty_user_codeAST::user_code

RBS:

  • () -> AST::user_code

Returns:

  • (AST::user_code)


365
366
367
# File 'lib/ibex/frontend/generated_parser_base.rb', line 365

def empty_user_code
  Hash.new { |hash, key| hash[key] = [] } #: AST::user_code
end

#expected_description(token) ⇒ String

RBS:

  • (Token? token) -> String

Parameters:

Returns:

  • (String)


86
87
88
89
90
91
92
# File 'lib/ibex/frontend/generated_parser_base.rb', line 86

def expected_description(token)
  expectation = @adapter.expectation(token)
  return expectation if expectation
  return ")" if %i[separated parameter].include?(@adapter.open_delimiter_kind)

  structural_expectation(token)
end

#extended_only!(location, feature) ⇒ void

This method returns an undefined value.

RBS:

  • (Location location, String feature) -> void

Parameters:



370
371
372
373
374
# File 'lib/ibex/frontend/generated_parser_base.rb', line 370

def extended_only!(location, feature)
  return if @mode == :extended || @adapter.extended_pragma? || @adapter.cst_pragma?

  fail_at(location, "#{feature} require extended mode")
end

#fail_at(location, message) ⇒ bot

RBS:

  • (Location location, String message) -> bot

Parameters:

Returns:

  • (bot)


377
378
379
# File 'lib/ibex/frontend/generated_parser_base.rb', line 377

def fail_at(location, message)
  raise Ibex::Error, "#{location}: #{message}"
end

#item_start_location(item) ⇒ Location?

RBS:

  • (AST::item? item) -> Location?

Parameters:

  • item (AST::item, nil)

Returns:



292
293
294
295
296
297
298
299
300
# File 'lib/ibex/frontend/generated_parser_base.rb', line 292

def item_start_location(item)
  return unless item

  if item.is_a?(AST::Optional) || item.is_a?(AST::Star) || item.is_a?(AST::Plus)
    return item_start_location(item.item)
  end

  item.loc
end

#named_reference_value(named_reference) ⇒ String?

RBS:

  • ([Token, Token]? named_reference) -> String?

Parameters:

Returns:

  • (String, nil)


311
312
313
314
315
316
317
# File 'lib/ibex/frontend/generated_parser_base.rb', line 311

def named_reference_value(named_reference)
  return unless named_reference

  colon, name = named_reference
  extended_only!(colon.location, "named references")
  token_string(name)
end

#next_token[ external_token, Token ], false

RBS:

  • () -> ([external_token, Token] | false)

Returns:

  • ([ external_token, Token ], false)


36
37
38
39
40
41
42
43
# File 'lib/ibex/frontend/generated_parser_base.rb', line 36

def next_token
  delivered = @adapter.next_token
  @diagnostic_token = delivered ? delivered.fetch(1) : @adapter.eof_token
  delivered
rescue Ibex::Error
  @diagnostic_token = @adapter.last_token || @adapter.eof_token
  raise
end

#on_error(_token_id, value, _value_stack) ⇒ bot

RBS:

  • (Integer? _token_id, Token? value, Array[untyped] _value_stack) -> bot

Parameters:

  • _token_id (Integer, nil)
  • value (Token, nil)
  • _value_stack (Array[untyped])

Returns:

  • (bot)


46
47
48
49
50
51
52
53
54
55
# File 'lib/ibex/frontend/generated_parser_base.rb', line 46

def on_error(_token_id, value, _value_stack)
  token = value || @adapter.eof_token
  @diagnostic_token = token
  raise_contextual_error(token)

  received = token&.value || token&.type || :eof
  location = token&.location || Location.new(file: "(grammar)", line: 1, column: 1)
  expected = expected_description(token)
  raise Ibex::Error, "#{location}: expected #{expected}, got #{received}"
end

#parseAST::Root, AST::Fragment

RBS:

  • () -> (AST::Root | AST::Fragment)

Returns:



31
32
33
# File 'lib/ibex/frontend/generated_parser_base.rb', line 31

def parse
  do_parse
end

#prepend_user_code(token, blocks) ⇒ AST::user_code

RBS:

  • (Token token, AST::user_code blocks) -> AST::user_code

Parameters:

  • token (Token)
  • blocks (AST::user_code)

Returns:

  • (AST::user_code)


358
359
360
361
362
# File 'lib/ibex/frontend/generated_parser_base.rb', line 358

def prepend_user_code(token, blocks)
  result = append_user_code(empty_user_code, token)
  blocks.each { |name, chunks| result[name].concat(chunks) }
  result
end

#raise_contextual_error(token) ⇒ void

This method returns an undefined value.

RBS:

  • (Token? token) -> void

Parameters:



60
61
62
63
# File 'lib/ibex/frontend/generated_parser_base.rb', line 60

def raise_contextual_error(token)
  raise_group_contextual_error(token)
  raise_conversion_contextual_error
end

#raise_conversion_contextual_errorvoid

This method returns an undefined value.

RBS:

  • () -> void



77
78
79
80
81
82
83
# File 'lib/ibex/frontend/generated_parser_base.rb', line 77

def raise_conversion_contextual_error
  conversion_name = @adapter.conversion_name
  return unless @adapter.declaration == :convert
  return unless conversion_name

  fail_at(conversion_name.location, "expected a quoted Ruby conversion expression")
end

#raise_group_contextual_error(token) ⇒ void

This method returns an undefined value.

RBS:

  • (Token? token) -> void

Parameters:



66
67
68
69
70
71
72
73
74
# File 'lib/ibex/frontend/generated_parser_base.rb', line 66

def raise_group_contextual_error(token)
  group_opening = @adapter.group_opening
  if group_opening && token && token.type == :action
    fail_at(token.location, "actions inside EBNF groups are not supported")
  end
  group_unterminated = @adapter.open_delimiter_kind == :group &&
                       (token.nil? || token.type == :eof || token.value == "end")
  fail_at(group_opening.location, "unterminated EBNF group") if group_unterminated && group_opening
end

#structural_expectation(token) ⇒ String

RBS:

  • (Token? token) -> String

Parameters:

Returns:

  • (String)


95
96
97
98
99
100
101
102
# File 'lib/ibex/frontend/generated_parser_base.rb', line 95

def structural_expectation(token)
  return "rule" if @adapter.section == :declarations
  return "at least one rule" if @adapter.section == :user_code && token&.value == "end"
  return "eof" if @adapter.section == :user_code
  return "end" if @adapter.section == :rules && @adapter.eof_token

  "grammar syntax"
end

#token_integer(token) ⇒ Integer

RBS:

  • (Token token) -> Integer

Parameters:

Returns:

  • (Integer)


390
391
392
393
394
395
# File 'lib/ibex/frontend/generated_parser_base.rb', line 390

def token_integer(token)
  value = token.value
  return value if value.is_a?(Integer)

  fail_at(token.location, "expected integer token")
end

#token_string(token) ⇒ String

RBS:

  • (Token token) -> String

Parameters:

Returns:

  • (String)


382
383
384
385
386
387
# File 'lib/ibex/frontend/generated_parser_base.rb', line 382

def token_string(token)
  value = token.value
  return value if value.is_a?(String)

  fail_at(token.location, "expected text token")
end

#token_user_code(token) ⇒ user_code_token

RBS:

  • (Token token) -> user_code_token

Parameters:

Returns:

  • (user_code_token)


398
399
400
401
402
403
# File 'lib/ibex/frontend/generated_parser_base.rb', line 398

def token_user_code(token)
  value = token.value
  return value if value.is_a?(Hash)

  fail_at(token.location, "expected user-code token")
end