Class: TreeHaver::Backends::Citrus::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/tree_haver/backends/citrus.rb

Overview

Citrus parser wrapper

Wraps Citrus grammar modules to provide a tree-sitter-like API.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeParser

Create a new Citrus parser instance

Raises:



209
210
211
212
213
214
# File 'lib/tree_haver/backends/citrus.rb', line 209

def initialize
  raise TreeHaver::NotAvailable, 'citrus gem not available' unless Citrus.available?

  @grammar = nil
  @backend = :citrus
end

Instance Attribute Details

#backendObject (readonly)

Returns the value of attribute backend.



216
217
218
# File 'lib/tree_haver/backends/citrus.rb', line 216

def backend
  @backend
end

Instance Method Details

#language=(grammar) ⇒ void

This method returns an undefined value.

Set the grammar for this parser

Accepts either a Citrus::Language wrapper or a raw Citrus grammar module. When passed a Language wrapper, extracts the grammar_module from it. When passed a raw grammar module, uses it directly.

This flexibility allows both patterns:

parser.language = TreeHaver::Backends::Citrus::Language.new(TomlRB::Document)
parser.language = TomlRB::Document  # Also works

Parameters:

  • grammar (Language, Module)

    Citrus Language wrapper or grammar module



230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
# File 'lib/tree_haver/backends/citrus.rb', line 230

def language=(grammar)
  # Accept Language wrapper or raw grammar module
  actual_grammar = case grammar
                   when Language
                     grammar.grammar_module
                   else
                     grammar
                   end

  unless actual_grammar.respond_to?(:parse)
    raise ArgumentError,
          'Expected Citrus grammar module with parse method or Language wrapper, ' \
            "got #{grammar.class}"
  end
  @grammar = actual_grammar
end

#parse(source) ⇒ Tree

Parse source code

Parameters:

  • source (String)

    the source code to parse

Returns:

  • (Tree)

    raw backend tree (wrapping happens in TreeHaver::Parser)

Raises:



253
254
255
256
257
258
259
260
261
262
263
264
# File 'lib/tree_haver/backends/citrus.rb', line 253

def parse(source)
  raise TreeHaver::NotAvailable, 'No grammar loaded' unless @grammar

  begin
    citrus_match = @grammar.parse(source)
    # Return raw Citrus::Tree - TreeHaver::Parser will wrap it
    Tree.new(citrus_match, source)
  rescue ::Citrus::ParseError => e
    # Re-raise with more context
    raise TreeHaver::Error, "Parse error: #{e.message}"
  end
end

#parse_string(old_tree, source) ⇒ Tree

Parse source code (compatibility with tree-sitter API)

Citrus doesn't support incremental parsing, so old_tree is ignored.

Parameters:

  • old_tree (TreeHaver::Tree, nil)

    ignored (no incremental parsing support)

  • source (String)

    the source code to parse

Returns:

  • (Tree)

    raw backend tree (wrapping happens in TreeHaver::Parser)



273
274
275
# File 'lib/tree_haver/backends/citrus.rb', line 273

def parse_string(old_tree, source) # rubocop:disable Lint/UnusedMethodArgument
  parse(source) # Citrus doesn't support incremental parsing
end