Class: Flexr::Source::PrismReader

Inherits:
Object
  • Object
show all
Defined in:
lib/flexr/source/prism_reader.rb

Constant Summary collapse

DSL_NAMES =
%i[rule state all_states on_eof emits backend token_kind encoding option accel].freeze

Instance Method Summary collapse

Constructor Details

#initialize(source, path: nil) ⇒ PrismReader

Returns a new instance of PrismReader.



18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/flexr/source/prism_reader.rb', line 18

def initialize(source, path: nil)
  @source = source
  @path = path
  @constants = {}
  @constant_definitions = []
  @resolved_constant_definitions = {}
  @rules = []
  @spans = []
  @edits = []
  @states = { initial: { inclusive: true } }
  @eof_rules = {}
  @config = { backend: :table, token_kind: :array, encoding: Encoding::UTF_8, declared_tokens: [] }
end

Instance Method Details

#read(allow_dynamic: false) ⇒ Object

Raises:



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/flexr/source/prism_reader.rb', line 32

def read(allow_dynamic: false)
  @allow_dynamic = allow_dynamic
  prism = begin
    require "prism"
    Prism.parse(@source)
  rescue LoadError => e
    diagnostic = Diagnostics.error("FLEXR-E019", "Prism is required for source generation", note: e.message)
    raise CompileError.new(diagnostic.message, diagnostic: diagnostic)
  end
  unless prism.errors.empty?
    error = prism.errors.first
    diagnostic = Diagnostics.error("FLEXR-E010", error.message)
    raise CompileError.new(diagnostic.message, diagnostic: diagnostic)
  end

  klass, class_name = find_lexer_class(prism.value)
  raise CompileError, "no class inheriting from Flexr::Lexer found" unless klass

  @lexer_scope = class_name.to_s.delete_prefix("::").split("::").reject(&:empty?)
  collect_constants(prism.value)
  collect_body(klass.body, [:initial])
  require_spans = flexr_require_spans(prism.value)
  first_dsl_offset = @spans.map(&:first).min || class_body_offset(klass)
  @config[:eof_rules] = @eof_rules
  SpecSource.new(source: @source, path: @path, class_name: class_name, rules: @rules,
                 config: @config, dsl_spans: @spans.uniq(&:first),
                 first_dsl_offset: first_dsl_offset, constants: @constants, states: @states,
                 flexr_require_spans: require_spans, dsl_edits: @edits)
end