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 Method Summary collapse

Constructor Details

#initializeParser

Create a new Citrus parser instance

Raises:



206
207
208
209
# File 'lib/tree_haver/backends/citrus.rb', line 206

def initialize
  raise TreeHaver::NotAvailable, "citrus gem not available" unless Citrus.available?
  @grammar = nil
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



223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'lib/tree_haver/backends/citrus.rb', line 223

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:



246
247
248
249
250
251
252
253
254
255
256
257
# File 'lib/tree_haver/backends/citrus.rb', line 246

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)



266
267
268
# File 'lib/tree_haver/backends/citrus.rb', line 266

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