はじめに
久石奏さん、お誕生日おめでとうございます。さいごのソリスト、胸を打つ...😭
nikkieです。
RustでPythonのASTを扱う、小さな小さな一歩の素振りをしました。
目次
- はじめに
- 目次
- PythonでASTをdumpする
- rustpython-parser crate
- Ruffのリポジトリに見つけたprint-ast
- 『Rustの練習帳』で見たところだ!
- rustpython-parserによるASTをpretty-print
- 終わりに
PythonでASTをdumpする
標準ライブラリast
を使います。
https://docs.python.org/ja/3/library/ast.html#command-line-usage
% python -m ast <<"EOF" if True: pass # comment EOF Module( body=[ If( test=Constant(value=True), body=[ Pass()], orelse=[])], type_ignores=[])
rustpython-parser crate
https://crates.io/crates/rustpython-parser
偶然知りました。
ソースコードがあるのは、RustPython/Parserというリポジトリ
The parser is one of the core part of RustPython and Ruff project.
Ruffでも使われている(使われていた?1)ようです
Ruffのリポジトリに見つけたprint-ast
Contributingのページの「cargo dev
」の項目。
https://docs.astral.sh/ruff/contributing/#cargo-dev
cargo dev print-ast <file>
が紹介されています。
ここを見て、rustpython-parserを使ってもprint-ast
相当のことができるのではないかと思いつきました。
crates.ioの「How to use」のコードでVec
が返ってきます。
これをprint-ast
のように表示してみたくなったのです。
パクるために、print-ast
の実装を確認します。
https://github.com/astral-sh/ruff/blob/0.8.6/crates/ruff_dev/src/print_ast.rs
println!("{python_ast:#?}");
『Rustの練習帳』で見たところだ!
{:#?}
を見て『Rustの練習帳』を思い出しました2。
{:?}
を使うことで、構造体をデバッグ用の形式(リンク省略)で表示できます。(2.2.1)今回は
{:#?}
を使って、改行とインデントを入れて出力を読みやすくしています。これは、整形表示(pretty-printing)と呼ばれています。(2.2.3)
Ruffのprint-ast
でやっているのは、整形表示(pretty-print)!
この機にドキュメントも確認
?
formatting.When used with the alternate format specifier
#?
, the output is pretty-printed.
rustpython-parserによるASTをpretty-print
% cargo init hello-ast % cd hello-ast % cargo add rustpython-parser
インストールされたrustpython-parserは0.4.0です。
% cargo run -q [ If( StmtIf { range: 0..13, test: Constant( ExprConstant { range: 3..7, value: Bool( true, ), kind: None, }, ), body: [ Pass( StmtPass { range: 9..13, }, ), ], orelse: [], }, ), ]
できた!!
Ruffのドキュメントのprint-ast
の出力例と一致するように思われます。
(なお、ファイルからの読み込みは後回しにしています)
終わりに
ごくごく短いPythonコード片をrustpython-parserでASTに変換し、それをpretty-printしました。
Pythonのastモジュールと比べると、できあがるASTは全然違うのですね。
例えばRuffはこんなASTを扱っているのか〜
- https://github.com/astral-sh/ruff を検索したところ、現在はCargo.tomlに依存の記載はなさそうでした。Ruffのリポジトリ内にもparserのcrateがあります↩
- 取り組んだことがあります ↩