$30 off During Our Annual Pro Sale. View Details »

汎用的なコードフォーマットライブラリの作成

 汎用的なコードフォーマットライブラリの作成

筑波大学情報学群情報科学類で開講されている情報科学特別演習という演習講義の最終発表会で使用したスライドです。

puripuri2100

January 17, 2023
Tweet

More Decks by puripuri2100

Other Decks in Technology

Transcript

  1. 汎用的なコードフォーマット
    ライブラリの作成
    筑波大学情報学群情報科学類 1 年 @puripuri2100
    2022/1/17

    View Slide

  2. 1/10
    このスライドについて
    この発表は筑波大学で開講されている情報科学特別演習*1という授業の最終発表会
    での使用したスライドです。
    1 https://kdb.tsukuba.ac.jp/syllabi/2022/GB13332/jpn/0

    View Slide

  3. 2/10
    コードフォーマッタとは
    コードを整形するソフトウェア
    インデントや改行のルールを統一
    複数人で書いても読みやすく統一された書き方ができる
    プログラムの書かれたファイルを受け取って、整形後のコードに書き替える
    例: rustfmt main.rs
    整形前
    1 fn main () {let hoge="s";
    2 // コメント
    3 println! (((hoge))) ;
    4 }
    整形後
    1 fn main() {
    2 let hoge = "s";
    3 // コメント
    4 println!((hoge));
    5 }

    View Slide

  4. 3/10
    課題設定
    コードフォーマッタの難しいところは 2 箇所
    構文解析器の作成
    言語固有の抽象構文木に強く依存
    破壊的変更への対応
    捨てられてしまいがちなコメント情報の取得
    構文解析器は個別に作成するしかない
    行分割・スペーシングの決定
    インデントの増減と一行の長さの制約の両立
    言語に強く依存しない箇所なので括り出せる
    現状は行分割処理をコードフォーマッタ作成者が車輪の再発明をしている状況
    解決したい課題:構文解析器を改造するだけでコードフォーマッタが簡単に作れ
    るようにしたい

    View Slide

  5. 4/10
    作成したコードフォーマットライブラリの設計
    各言語の構文をとても抽象化した中間表現を使用
    中間表現から実際のコード文字列を自動で生成👈今回やったこと
    コードフォーマッタ作成者は個別具体的な構文解析器から中間表現を生成
    中間表現は構造と見た目の情報のみを保持する木構造
    Raw :そのまま出力されるキーワード(例: let ・ = )
    List :同じ階層の要素からなる要素列(例:リスト・複数の import 文)
    Paren :括弧(例:リストの角括弧)
    Column :改行を間の任意の箇所に入れることが可能な要素列(例:関数の定
    義文)
    簡単な再帰関数でコードを生成できるので今回は木構造を採用

    View Slide

  6. 5/10
    実例
    生成したいコード
    1 let t = (0, 4.2)
    Raw :そのまま出力さ
    れるキーワード
    List :同じ階層の要素
    からなる要素列
    Paren :括弧
    Column :改行を間の任
    意の箇所に入れることが
    可能な要素列
    コード生成関数に渡す木構造
    1 Column [
    2 Raw "let";
    3 Raw "t";
    4 Raw "=";
    5 Paren (
    6 "(",
    7 List ("," [Raw "0"; Raw "4.2"]),
    8 ")"
    9 );
    10 ]

    View Slide

  7. 6/10
    コメントの挿入
    実際のコードにはコメントが付く。これを反映するために木構造の各要素に対して
    要素の前に出現する複数行のコメント
    要素の直後に出現するコメント
    の二つの情報を付与して処理するようにする。
    実例
    1 (*
    2 comment1
    3 comment2
    4 *)
    5
    6 f (* comment3 *)
    コメント情報のついた要素
    1 {
    2 before_comments = [
    3 "comment1"; "comment2";
    4 ];
    5 rule = Raw "f";
    6 after_comment = Some "comment3";
    7 }

    View Slide

  8. 7/10
    実装
    実装は Rust と OCaml の 2 つの言語で行った。 for を使うよくある手続き型言語で
    の書き方と、 再帰関数を使う関数型言語での書き方の両方で汎用的に実装できるこ
    とを確認した。
    Rust での実装:https://github.com/puripuri2100/coins_special_seminar_co
    de_format_rs
    OCaml での実装:https://github.com/puripuri2100/coins_special_seminar_co
    de_format_ml
    改行自体は貪欲法で実装できるが、様々な要素との兼ね合いが難しかった。
    難しかった点:
    改行可能位置と強制改行位置のそれぞれの検出
    インデントの深さによって改行が必要かどうかが変わる場合があるなど
    要素の直後に出現するコメントと改行位置の両立

    View Slide

  9. 8/10
    使用例
    作成したこのコードフォーマットライブラリを用いて実際に SATYSFI のコードフォー
    マッタを実装した:https://github.com/puripuri2100/satysfifmt
    実用レベルまでは改行位置・インデントの深さなどの調整がそれなりに必要である
    が、一応動く
    フォーマット前
    1 @require: option
    2 module M :> sig val f 'a :
    3 'a ->
    4 bool
    5 end = struct
    6 val f
    7 x = true %test
    8 end
    フォーマット後
    1 @require: option
    2
    3 module M:>
    4 sig
    5 val f 'a : 'a -> bool
    6 end = struct
    7 val f x = true % test
    8 end

    View Slide

  10. 8/10
    使用例
    作成したこのコードフォーマットライブラリを用いて実際に SATYSFI のコードフォー
    マッタを実装した:https://github.com/puripuri2100/satysfifmt
    実用レベルまでは改行位置・インデントの深さなどの調整がそれなりに必要である
    が、一応動く
    トークン列から抽象構文木を作り上げる既存実装の parser.mly ファイルを、トー
    クン列からコードフォーマット用の木構造を作るように少し改造するだけで作成で
    きたため、コードフォーマッタの実装コストが低下した

    View Slide

  11. 9/10
    Future Works
    中間表現からコードを生成する箇所でカスタマイズ性を上げたい
    中間表現の子要素に応じた改行位置のより柔軟な操作
    スペーシングの調節
    doc comment などへの対応
    別の中間表現からの生成を試してみたい
    ログのようなストリーム方式からの生成
    途中で中身を更新できるような中間表現からの生成

    View Slide

  12. 10/10
    まとめ
    コードの出力に関する情報を保持した木構造から以下のことを自動で行うコード
    フォーマットライブラリを作成した
    改行位置の決定
    コメントの挿入
    インデントの増減
    コードフォーマットライブラリは Rust と OCaml で実装し、
    GitHub で公開して
    いる
    実際にこのライブラリを使って SATYSFI という組版用言語のフォーマッタを作成
    してみた
    構文解析器からコードの情報を組み立てる作業にのみ集中すればよくなり、コー
    ドフォーマッタの作成のコストが低下する効果を得ることができた

    View Slide