いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Goメモ-605 (Tree-sitterメモ-05)(ノードタイプ)

関連記事

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)(シンタックスエラーの出力) - いろいろ備忘録日記

概要

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

今回は、ノードタイプについて。

tree-sitterで処理を書いていると自ずとノードのタイプ毎に処理を分岐することになります。

このノードタイプは、Node.Kindの値から取得出来ます。

例えば、C言語のパーサーを利用した場合は以下のようなノードタイプが現れます。

  • comment
  • function_declaration
  • identifier

これらのノードタイプは、言語ごとに異なっており、それぞれの言語用のリポジトリにある nodetypes.json ファイルに定義されています。

なので、このファイルを見てノートタイプ毎の分岐を書いて処理するようにします。

各言語用にリポジトリは以下のようになっており、リポジトリ名が tree-sitter-言語 となっています。

(逆にバインディングライブラリの方は 言語-tree-sitter というネーミングになっています。)

一例として

のようになります。フルリストは Parses にあります。

サンプル

main.go

package main

import (
    "log"

    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>
int main(void) {
  int x = 10;
  printf("%d\n", x);
  return 0;
}`
)

var (
    code = []byte(C_CODE)
)

func main() {
    log.SetFlags(0)

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

func run() error {
    p := tree_sitter.NewParser()
    defer p.Close()

    _ = p.SetLanguage(tree_sitter.NewLanguage(tree_sitter_c.Language()))

    t := p.Parse(code, nil)
    r := t.RootNode()

    //
    // C言語のパーサーを使っているため
    //   https://github.com/tree-sitter/tree-sitter-c/blob/master/src/node-types.json
    // に定義されている要素が Node.Kind() の値として登場する
    //
    log.Printf("RootNode=%s", r.Kind())
    for i := uint(0); i < r.NamedChildCount(); i++ {
        log.Printf("\tChildNode=%s", r.NamedChild(i).Kind())
    }

    return nil
}

実行結果

$ task
task: [default] go run .
RootNode=translation_unit
        ChildNode=preproc_include
        ChildNode=function_definition

参考情報

tree-sitter.github.io

github.com

Goのおすすめ書籍


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

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