Class: TreeHaver::Backends::Parslet::Language

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/tree_haver/backends/parslet.rb

Overview

Parslet grammar wrapper

Unlike tree-sitter which loads compiled .so files, Parslet uses Ruby classes
that define grammars. This class wraps a Parslet grammar class.

Examples:

# For TOML, use toml gem's grammar
language = TreeHaver::Backends::Parslet::Language.new(TOML::Parslet)

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(grammar_class) ⇒ Language

Returns a new instance of Language.

Parameters:

  • grammar_class (Class)

    A Parslet grammar class (inherits from ::Parslet::Parser)



102
103
104
105
106
107
108
109
110
# File 'lib/tree_haver/backends/parslet.rb', line 102

def initialize(grammar_class)
  unless valid_grammar_class?(grammar_class)
    raise TreeHaver::NotAvailable,
      "Grammar class must be a Parslet::Parser subclass or respond to :new and return a parser with :parse. " \
        "Expected a Parslet grammar class (e.g., TOML::Parslet)."
  end
  @grammar_class = grammar_class
  @backend = :parslet
end

Instance Attribute Details

#backendSymbol (readonly)

The backend this language is for

Returns:

  • (Symbol)


99
100
101
# File 'lib/tree_haver/backends/parslet.rb', line 99

def backend
  @backend
end

#grammar_classClass (readonly)

The Parslet grammar class

Returns:

  • (Class)

    Parslet grammar class (e.g., TOML::Parslet)



95
96
97
# File 'lib/tree_haver/backends/parslet.rb', line 95

def grammar_class
  @grammar_class
end

Class Method Details

.from_library(path = nil, symbol: nil, name: nil) ⇒ Object Also known as: from_path



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/tree_haver/backends/parslet.rb', line 169

def from_library(path = nil, symbol: nil, name: nil)
  # Derive language name from path, symbol, or explicit name
  lang_name = name&.to_sym ||
    symbol&.to_s&.sub(/^tree_sitter_/, "")&.to_sym ||
    path && TreeHaver::LibraryPathUtils.derive_language_name_from_path(path)&.to_sym

  unless lang_name
    raise TreeHaver::NotAvailable,
      "Parslet backend requires a language name. " \
        "Provide name: parameter or register a grammar with TreeHaver.register_language."
  end

  # Look up registered Parslet grammar
  registration = TreeHaver::LanguageRegistry.registered(lang_name, :parslet)

  unless registration
    raise TreeHaver::NotAvailable,
      "No Parslet grammar registered for #{lang_name.inspect}. " \
        "Register one with: TreeHaver.register_language(:#{lang_name}, grammar_class: YourGrammar)"
  end

  grammar_class = registration[:grammar_class]
  new(grammar_class)
end

Instance Method Details

#<=>(other) ⇒ Integer?

Compare languages for equality

Parslet languages are equal if they have the same backend and grammar_class.
Grammar class uniquely identifies a Parslet language.

Parameters:

  • other (Object)

    object to compare with

Returns:

  • (Integer, nil)

    -1, 0, 1, or nil if not comparable



135
136
137
138
139
140
141
# File 'lib/tree_haver/backends/parslet.rb', line 135

def <=>(other)
  return unless other.is_a?(Language)
  return unless other.backend == @backend

  # Compare by grammar_class name (classes are compared by object_id by default)
  @grammar_class.name <=> other.grammar_class.name
end

#hashInteger

Hash value for this language (for use in Sets/Hashes)

Returns:

  • (Integer)


145
146
147
# File 'lib/tree_haver/backends/parslet.rb', line 145

def hash
  [@backend, @grammar_class.name].hash
end

#language_nameSymbol Also known as: name

Get the language name

Derives a name from the grammar class name.

Returns:

  • (Symbol)

    language name



117
118
119
120
121
122
123
# File 'lib/tree_haver/backends/parslet.rb', line 117

def language_name
  # Derive name from grammar class (e.g., TOML::Parslet -> :toml)
  return :unknown unless @grammar_class.respond_to?(:name) && @grammar_class.name

  name = @grammar_class.name.to_s.split("::").first.downcase
  name.to_sym
end