はじめに
久石奏さん、お誕生日おめでとうございます。さいごのソリスト、胸を打つ...😭
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があります↩
- 取り組んだことがあります ↩