関連記事
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
参考情報
Goのおすすめ書籍
過去の記事については、以下のページからご参照下さい。
サンプルコードは、以下の場所で公開しています。





