Rustコンパイラの処理の流れ(1)
2 min readMay 13, 2018
Rustのプログラムは以下のようなステップから構成されており、上から順に処理されている。
.rs
ファイルをパースし、ASTを生成- マクロの展開、名前解決、
#[cfg]
アトリビュートの解釈 - ASTをHIRに変換
- 型推論、型解析
- HIRをMIRに変換
- MIRをLLVM IRに変換、最適化
.o
ファイルをリンク
.rs
ファイルのパース
パーサはlibsyntax crateにまとまっている。一般的なパーサと同じく、字句を解析しASTを作る。
rust/src/libsysntax/codemap.rsでもともとのソースコードの位置の情報とASTのノードをマッピングしている。CodeMapのフィールドの1つであるfilesにファイルの情報がFileMapというデータ構造で入っている。また、CodeMapの先頭からの絶対的な位置がSpanというデータ構造に格納される。StringReader がFileMapをもとに、文字列の情報を次々に読んでいき、TokenStream 生成する。TokenStreamはTokenTreeのシーケンスであり、TokenTreeはTokenと区切り文字で構成されている。
Parser がTokenStreamをもとにASTを生成している。parse_
から始まるいくつかの関数がパースする際のエントリーポイントになっている。また、ASTはrust/src/libsysntax/ast.rs で定義されている。
ASTの内容を確認したい場合、rustc -Z ast-json ファイル名
を実行すれば、ASTがJSON形式で表示される。
また、StringReaderとParserはパース中に必要な情報を保持する ParseSess に紐付いており、無駄なコピーが発生しないようになっている。