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


Goメモ-608 (Tree-sitterメモ-08)(ノードのトラバース(2), TreeCursorの利用)

関連記事

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)(ノードタイプ) - いろいろ備忘録日記

Goメモ-606 (Tree-sitterメモ-06)(ノードテキスト) - いろいろ備忘録日記

Goメモ-607 (Tree-sitterメモ-07)(ノードのトラバース(1), ループとコールバックで実施) - いろいろ備忘録日記

概要

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

今回は、前回に引き続きノードのトラバースについて。

tree_sitterには TreeCursor というオブジェクトが存在します。

このオブジェクトは Tree.WalkNode.Walk から得られます。

このオブジェクトを利用すると配下のノードを再帰的にトラバースすることが可能なのですが、若干利用方法が難しいです。

本サンプルでは、TreeCursorを用いたノードのトラバースを行っています。

サンプル

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 (
        tree = p.Parse([]byte(C_CODE), nil)
    )
    if tree == nil {
        return errors.New("構文解析に失敗: Parse()")
    }
    defer tree.Close()

    var (
        root     = tree.RootNode()
        cursor   = root.Walk()
        callback = func(node *tree_sitter.Node, depth uint32) {
            var (
                k = node.Kind()
                d = int(depth) * 2
            )
            fmt.Printf("%s%-25s\n", strings.Repeat(" ", d), k)
        }
    )
    defer cursor.Close() // *TreeCursorは閉じる必要がある

    walk(cursor, callback)

    return nil
}

// walk は、TreeCursorを利用して指定したノード配下をトラバースする関数です。
func walk(cursor *tree_sitter.TreeCursor, callback func(*tree_sitter.Node, uint32)) {
    var (
        node  = cursor.Node()  // 現在のノード
        depth = cursor.Depth() // 現在の深さ
    )
    // *TreeCursorでは、Namedだけではなく全てのノードが回るのでNamedだけ対象にするには絞り込む必要がある
    if node.IsNamed() {
        callback(node, depth)
    }

    // 子ノードが存在する場合は移動
    if cursor.GotoFirstChild() {
        for {
            walk(cursor, callback)

            // 兄弟ノードが存在すれば移動
            if !cursor.GotoNextSibling() {
                break
            }
        }

        // 親ノードに戻る
        cursor.GotoParent()
    }
}

実行結果

$ task
task: [default] go run .
translation_unit         
  preproc_include          
    system_lib_string        
  preproc_include          
    system_lib_string        
  function_definition      
    primitive_type           
    function_declarator      
      identifier               
      parameter_list           
        parameter_declaration    
          primitive_type           
          identifier               
        parameter_declaration    
          primitive_type           
          identifier               
    compound_statement       
      comment                  
      return_statement         
        binary_expression        
          identifier               
          identifier               
  function_definition      
    primitive_type           
    function_declarator      
      identifier               
      parameter_list           
        parameter_declaration    
          primitive_type           
    compound_statement       
      declaration              
        primitive_type           
        init_declarator          
          identifier               
          call_expression          
            identifier               
            argument_list            
              number_literal           
              number_literal           
      if_statement             
        parenthesized_expression 
          binary_expression        
            identifier               
            number_literal           
        compound_statement       
          expression_statement     
            call_expression          
              identifier               
              argument_list            
                string_literal           
                  string_content           
                  escape_sequence          
                identifier               
      for_statement            
        declaration              
          primitive_type           
          init_declarator          
            identifier               
            number_literal           
        binary_expression        
          identifier               
          identifier               
        update_expression        
          identifier               
        compound_statement       
          switch_statement         
            parenthesized_expression 
              identifier               
            compound_statement       
              case_statement           
                number_literal           
                expression_statement     
                  call_expression          
                    identifier               
                    argument_list            
                      string_literal           
                        string_content           
                        escape_sequence          
                return_statement         
              case_statement           
                expression_statement     
                  call_expression          
                    identifier               
                    argument_list            
                      string_literal           
                        string_content           
                        escape_sequence          
                return_statement         
      return_statement         
        identifier

参考情報

tree-sitter.github.io

github.com

Goのおすすめ書籍


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

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




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

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