以下の内容はhttps://devlights.hatenablog.com/entry/2025/08/19/073000より取得しました。


Goメモ-606 (Tree-sitterメモ-06)(ノードテキスト)

関連記事

GitHub - devlights/blog-summary: ブログ「いろいろ備忘録日記」のまとめ

Goメモ-597 (Tree-sitterメモ-01)(下準備, Goバインディングのインストール) - いろいろ備忘録日記

Goメモ-598 (Tree-sitterメモ-02)(パーサーの生成と言語の設定) - いろいろ備忘録日記

Goメモ-599 (Tree-sitterメモ-03)(解析処理の実行とツリーの取得) - いろいろ備忘録日記

Goメモ-600 (Tree-sitterメモ-04)(シンタックスエラーの出力) - いろいろ備忘録日記

Goメモ-605 (Tree-sitterメモ-05)(ノードタイプ) - いろいろ備忘録日記

概要

以下、自分用のメモです。前回までのメモは関連記事にかかれている ブログ記事まとめ よりどうぞ。

今回は、ノードテキストについて。

ノードのテキスト情報は、tree-sitterを使っていて一番欲しい情報の一つですね。

特定のソースコードを構文解析して何かをしたいわけですので、該当箇所のテキストは一番欲しいものです。

ですが、tree-sitter自身は、ノード自身は元のテキスト上でのポジションしか保持していないため、実際のテキストとして復元するには元データが必要です。

開始位置を取得する StartByte() と終了位置を取得する EndByte() を使ってテキストを抽出する必要があります。

こんな感じ。

sourceCode[node.StartByte():node.EndByte()]

サンプル

main.go

package main

import (
    "errors"
    "fmt"
    "log"
    "strings"

    tree_sitter "github.com/tree-sitter/go-tree-sitter"
    tree_sitter_c "github.com/tree-sitter/tree-sitter-c/bindings/go"
)

const (
    C_CODE = `#include <stdio.h>
#include <stdlib.h>

int add(int x, int y) {
  // ADD
  return x+y;
}

int main(void) {
  int z = add(1, 2);
  if (z < 10) {
      printf("%d\n", z);
  }

  for (int i = 0; i < z; i++) {
      switch (i) {
      case 0:
          printf("first\n");
          return;
      default:
          printf("other\n");
          return;
      }
  }

  return EXIT_SUCCESS;
}
  `
)

func main() {
    log.SetFlags(0)

    if err := run(); err != nil {
        log.Fatal(err)
    }
}

func run() error {
    var (
        p   = tree_sitter.NewParser()
        l   = tree_sitter.NewLanguage(tree_sitter_c.Language())
        err error
    )
    defer p.Close()
    if err = p.SetLanguage(l); err != nil {
        return err
    }

    var (
        code = []byte(C_CODE)
        tree = p.Parse(code, nil)
    )
    if tree == nil {
        return errors.New("構文解析に失敗: Parse()")
    }
    defer tree.Close()

    var (
        root     = tree.RootNode()
        callback = func(node *tree_sitter.Node, depth int) {
            var (
                k = node.Kind()
                s = node.StartByte()
                e = node.EndByte()
            )
            fmt.Printf("%s%-25s%s%s\n", strings.Repeat(" ", depth*2), k, strings.Repeat(" ", 10), C_CODE[s:e])
        }
    )
    walk(root, 0, callback)

    return nil
}

func walk(node *tree_sitter.Node, depth int, callback func(*tree_sitter.Node, int)) {
    if node.Kind() != "translation_unit" {
        callback(node, depth)
    }

    for i := uint(0); i < node.NamedChildCount(); i++ {
        walk(node.NamedChild(i), depth+1, callback)
    }
}

実行結果

$ task
task: [default] go run .
  preproc_include                    #include <stdio.h>

    system_lib_string                  <stdio.h>
  preproc_include                    #include <stdlib.h>

    system_lib_string                  <stdlib.h>
  function_definition                int add(int x, int y) {
    // ADD
    return x+y;
}
    primitive_type                     int
    function_declarator                add(int x, int y)
      identifier                         add
      parameter_list                     (int x, int y)
        parameter_declaration              int x
          primitive_type                     int
          identifier                         x
        parameter_declaration              int y
          primitive_type                     int
          identifier                         y
    compound_statement                 {
    // ADD
    return x+y;
}
      comment                            // ADD
      return_statement                   return x+y;
        binary_expression                  x+y
          identifier                         x
          identifier                         y
  function_definition                int main(void) {
    int z = add(1, 2);
    if (z < 10) {
        printf("%d\n", z);
    }

    for (int i = 0; i < z; i++) {
        switch (i) {
        case 0:
            printf("first\n");
            return;
        default:
            printf("other\n");
            return;
        }
    }

    return EXIT_SUCCESS;
}
    primitive_type                     int
    function_declarator                main(void)
      identifier                         main
      parameter_list                     (void)
        parameter_declaration              void
          primitive_type                     void
    compound_statement                 {
    int z = add(1, 2);
    if (z < 10) {
        printf("%d\n", z);
    }

    for (int i = 0; i < z; i++) {
        switch (i) {
        case 0:
            printf("first\n");
            return;
        default:
            printf("other\n");
            return;
        }
    }

    return EXIT_SUCCESS;
}
      declaration                        int z = add(1, 2);
        primitive_type                     int
        init_declarator                    z = add(1, 2)
          identifier                         z
          call_expression                    add(1, 2)
            identifier                         add
            argument_list                      (1, 2)
              number_literal                     1
              number_literal                     2
      if_statement                       if (z < 10) {
        printf("%d\n", z);
    }
        parenthesized_expression           (z < 10)
          binary_expression                  z < 10
            identifier                         z
            number_literal                     10
        compound_statement                 {
        printf("%d\n", z);
    }
          expression_statement               printf("%d\n", z);
            call_expression                    printf("%d\n", z)
              identifier                         printf
              argument_list                      ("%d\n", z)
                string_literal                     "%d\n"
                  string_content                     %d
                  escape_sequence                    \n
                identifier                         z
      for_statement                      for (int i = 0; i < z; i++) {
        switch (i) {
        case 0:
            printf("first\n");
            return;
        default:
            printf("other\n");
            return;
        }
    }
        declaration                        int i = 0;
          primitive_type                     int
          init_declarator                    i = 0
            identifier                         i
            number_literal                     0
        binary_expression                  i < z
          identifier                         i
          identifier                         z
        update_expression                  i++
          identifier                         i
        compound_statement                 {
        switch (i) {
        case 0:
            printf("first\n");
            return;
        default:
            printf("other\n");
            return;
        }
    }
          switch_statement                   switch (i) {
        case 0:
            printf("first\n");
            return;
        default:
            printf("other\n");
            return;
        }
            parenthesized_expression           (i)
              identifier                         i
            compound_statement                 {
        case 0:
            printf("first\n");
            return;
        default:
            printf("other\n");
            return;
        }
              case_statement                     case 0:
            printf("first\n");
            return;
                number_literal                     0
                expression_statement               printf("first\n");
                  call_expression                    printf("first\n")
                    identifier                         printf
                    argument_list                      ("first\n")
                      string_literal                     "first\n"
                        string_content                     first
                        escape_sequence                    \n
                return_statement                   return;
              case_statement                     default:
            printf("other\n");
            return;
                expression_statement               printf("other\n");
                  call_expression                    printf("other\n")
                    identifier                         printf
                    argument_list                      ("other\n")
                      string_literal                     "other\n"
                        string_content                     other
                        escape_sequence                    \n
                return_statement                   return;
      return_statement                   return EXIT_SUCCESS;
        identifier                         EXIT_SUCCESS

参考情報

tree-sitter.github.io

github.com

Goのおすすめ書籍


過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。




以上の内容はhttps://devlights.hatenablog.com/entry/2025/08/19/073000より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14