Class: Ibex::Frontend::Formatter

Inherits:
Object
  • Object
show all
Defined in:
lib/ibex/frontend/formatter.rb

Overview

Deterministically formats grammar trivia and rejects any semantic change. rubocop:disable Metrics/ClassLength -- token layout policy stays together so adjacency rules remain auditable.

Constant Summary collapse

DECLARATION_STARTS =
%i[
  PRAGMA INCLUDE IMPORT TOKEN PRECHIGH PRECLOW OPTIONS EXPECT EXPECT_RR START RECOVER ON_ERROR_REDUCE TEST LEXER
  CONVERT DISPLAY TYPE PARAM PRINTER RULE
].freeze
ASSOCIATIONS =

: Array

%i[LEFT RIGHT NONASSOC].freeze
CALLABLES =

: Array

%i[LHS PARAMETERIZED_REFERENCE SEPARATED_LIST SEPARATED_NONEMPTY_LIST].freeze
SUFFIXES =

: Array

%w[? * +].freeze
CLOSERS =

: Array

%w[) , ;].freeze
ADJACENT_AFTER =

: Array

["::", "("].freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(mode: :default) ⇒ Formatter

Returns a new instance of Formatter.

Raises:

  • (ArgumentError)


32
33
34
35
36
# File 'lib/ibex/frontend/formatter.rb', line 32

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

  @mode = mode
end

Class Method Details

.format(source, file: "(grammar)", mode: :default) ⇒ Object



27
28
29
# File 'lib/ibex/frontend/formatter.rb', line 27

def self.format(source, file: "(grammar)", mode: :default)
  new(mode: mode).format(source, file: file)
end

Instance Method Details

#format(source, file: "(grammar)") ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/ibex/frontend/formatter.rb', line 39

def format(source, file: "(grammar)")
  document = Parser.new(source, file: file, mode: @mode).parse_source_document
  formatted = render(document)
  reparsed = Parser.new(formatted, file: file, mode: @mode).parse_source_document
  unless same_semantic_projection?(document.ast, reparsed.ast)
    raise Ibex::Error, "#{file}: formatting would change grammar semantics"
  end

  formatted
rescue Ibex::Error
  raise
rescue StandardError => e
  raise Ibex::Error, "#{file}: formatting failed: #{e.message}"
end