Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
汎用的なコードフォーマットライブラリの作成
Search
puripuri2100
January 17, 2023
Technology
0
320
汎用的なコードフォーマットライブラリの作成
筑波大学情報学群情報科学類で開講されている情報科学特別演習という演習講義の最終発表会で使用したスライドです。
puripuri2100
January 17, 2023
Tweet
Share
More Decks by puripuri2100
See All by puripuri2100
法律文書の自動解析2024
puripuri2100
0
57
絵文字は構文解析できるのか
puripuri2100
0
88
係り受け解析を用いた法律文書中の略称規定の解析についての報告
puripuri2100
0
3k
気胸の胸部CTデータの可視化
puripuri2100
0
290
SATySFiで作成する構文解析器
puripuri2100
0
270
SATySFiの開発についての要望
puripuri2100
0
440
研究の場においてのRust 製ソフトウェアのバージョン管理について
puripuri2100
0
620
法律文書の自動解析
puripuri2100
1
920
ユーザーがカスタマイズできるクラスファイル ―v0.0.x と v0.1.x それぞれでの実装 ―
puripuri2100
0
370
Other Decks in Technology
See All in Technology
Kiro Autonomous AgentとKiro Powers の紹介 / kiro-autonomous-agent-and-powers
tomoki10
0
300
最近のLinux普段づかいWaylandデスクトップ元年
penguin2716
1
660
エンジニアリングマネージャー はじめての目標設定と評価
halkt
0
250
Security Diaries of an Open Source IAM
ahus1
0
130
AIと二人三脚で育てた、個人開発アプリグロース術
zozotech
PRO
0
680
Karate+Database RiderによるAPI自動テスト導入工数をCline+GitLab MCPを使って2割削減を目指す! / 20251206 Kazuki Takahashi
shift_evolve
PRO
1
460
乗りこなせAI駆動開発の波
eltociear
1
970
Ruby で作る大規模イベントネットワーク構築・運用支援システム TTDB
taketo1113
1
200
Noを伝える技術2025: 爆速合意形成のためのNICOフレームワーク速習 #pmconf2025
aki_iinuma
2
2k
世界最速級 memcached 互換サーバー作った
yasukata
0
330
ブロックテーマとこれからの WordPress サイト制作 / Toyama WordPress Meetup Vol.81
torounit
0
390
日本Rubyの会の構造と実行とあと何か / hokurikurk01
takahashim
4
910
Featured
See All Featured
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
970
Bash Introduction
62gerente
615
210k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
10
710
Designing for humans not robots
tammielis
254
26k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
22k
Speed Design
sergeychernyshev
33
1.4k
The Language of Interfaces
destraynor
162
25k
It's Worth the Effort
3n
187
29k
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
1
92
The World Runs on Bad Software
bkeepers
PRO
72
12k
VelocityConf: Rendering Performance Case Studies
addyosmani
333
24k
Imperfection Machines: The Place of Print at Facebook
scottboms
269
13k
Transcript
汎用的なコードフォーマット ライブラリの作成 筑波大学情報学群情報科学類 1 年 @puripuri2100 2022/1/17
1/10 このスライドについて この発表は筑波大学で開講されている情報科学特別演習*1という授業の最終発表会 での使用したスライドです。 1 https://kdb.tsukuba.ac.jp/syllabi/2022/GB13332/jpn/0
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 }
3/10 課題設定 コードフォーマッタの難しいところは 2 箇所 構文解析器の作成 言語固有の抽象構文木に強く依存 破壊的変更への対応 捨てられてしまいがちなコメント情報の取得 構文解析器は個別に作成するしかない
行分割・スペーシングの決定 インデントの増減と一行の長さの制約の両立 言語に強く依存しない箇所なので括り出せる 現状は行分割処理をコードフォーマッタ作成者が車輪の再発明をしている状況 解決したい課題:構文解析器を改造するだけでコードフォーマッタが簡単に作れ るようにしたい
4/10 作成したコードフォーマットライブラリの設計 各言語の構文をとても抽象化した中間表現を使用 中間表現から実際のコード文字列を自動で生成👈今回やったこと コードフォーマッタ作成者は個別具体的な構文解析器から中間表現を生成 中間表現は構造と見た目の情報のみを保持する木構造 Raw :そのまま出力されるキーワード(例: let ・
= ) List :同じ階層の要素からなる要素列(例:リスト・複数の import 文) Paren :括弧(例:リストの角括弧) Column :改行を間の任意の箇所に入れることが可能な要素列(例:関数の定 義文) 簡単な再帰関数でコードを生成できるので今回は木構造を採用
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 ]
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 }
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 改行自体は貪欲法で実装できるが、様々な要素との兼ね合いが難しかった。 難しかった点: 改行可能位置と強制改行位置のそれぞれの検出 インデントの深さによって改行が必要かどうかが変わる場合があるなど 要素の直後に出現するコメントと改行位置の両立
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
8/10 使用例 作成したこのコードフォーマットライブラリを用いて実際に SATYSFI のコードフォー マッタを実装した:https://github.com/puripuri2100/satysfifmt 実用レベルまでは改行位置・インデントの深さなどの調整がそれなりに必要である が、一応動く トークン列から抽象構文木を作り上げる既存実装の parser.mly
ファイルを、トー クン列からコードフォーマット用の木構造を作るように少し改造するだけで作成で きたため、コードフォーマッタの実装コストが低下した
9/10 Future Works 中間表現からコードを生成する箇所でカスタマイズ性を上げたい 中間表現の子要素に応じた改行位置のより柔軟な操作 スペーシングの調節 doc comment などへの対応 別の中間表現からの生成を試してみたい
ログのようなストリーム方式からの生成 途中で中身を更新できるような中間表現からの生成
10/10 まとめ コードの出力に関する情報を保持した木構造から以下のことを自動で行うコード フォーマットライブラリを作成した 改行位置の決定 コメントの挿入 インデントの増減 コードフォーマットライブラリは Rust と
OCaml で実装し、 GitHub で公開して いる 実際にこのライブラリを使って SATYSFI という組版用言語のフォーマッタを作成 してみた 構文解析器からコードの情報を組み立てる作業にのみ集中すればよくなり、コー ドフォーマッタの作成のコストが低下する効果を得ることができた