Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
汎用的なコードフォーマットライブラリの作成
Search
puripuri2100
January 17, 2023
Technology
0
280
汎用的なコードフォーマットライブラリの作成
筑波大学情報学群情報科学類で開講されている情報科学特別演習という演習講義の最終発表会で使用したスライドです。
puripuri2100
January 17, 2023
Tweet
Share
More Decks by puripuri2100
See All by puripuri2100
絵文字は構文解析できるのか
puripuri2100
0
28
係り受け解析を用いた法律文書中の略称規定の解析についての報告
puripuri2100
0
1.9k
気胸の胸部CTデータの可視化
puripuri2100
0
230
SATySFiで作成する構文解析器
puripuri2100
0
190
SATySFiの開発についての要望
puripuri2100
0
370
研究の場においてのRust 製ソフトウェアのバージョン管理について
puripuri2100
0
520
法律文書の自動解析
puripuri2100
1
620
ユーザーがカスタマイズできるクラスファイル ―v0.0.x と v0.1.x それぞれでの実装 ―
puripuri2100
0
310
mdbook-satysfiを作成しました
puripuri2100
0
560
Other Decks in Technology
See All in Technology
個人でもIAM Identity Centerを使おう!(アクセス管理編)
ryder472
3
170
ExaDB-D dbaascli で出来ること
oracle4engineer
PRO
0
3.8k
初心者向けAWS Securityの勉強会mini Security-JAWSを9ヶ月ぐらい実施してきての近況
cmusudakeisuke
0
120
Why does continuous profiling matter to developers? #appdevelopercon
salaboy
0
180
RubyのWebアプリケーションを50倍速くする方法 / How to Make a Ruby Web Application 50 Times Faster
hogelog
3
940
【Startup CTO of the Year 2024 / Audience Award】アセンド取締役CTO 丹羽健
niwatakeru
0
860
Why App Signing Matters for Your Android Apps - Android Bangkok Conference 2024
akexorcist
0
120
開発生産性を上げながらビジネスも30倍成長させてきたチームの姿
kamina_zzz
2
1.6k
ドメインの本質を掴む / Get the essence of the domain
sinsoku
2
150
TypeScript、上達の瞬間
sadnessojisan
46
13k
なぜ今 AI Agent なのか _近藤憲児
kenjikondobai
4
1.3k
インフラとバックエンドとフロントエンドをくまなく調べて遅いアプリを早くした件
tubone24
1
430
Featured
See All Featured
5 minutes of I Can Smell Your CMS
philhawksworth
202
19k
The MySQL Ecosystem @ GitHub 2015
samlambert
250
12k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
229
52k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
10
720
Art, The Web, and Tiny UX
lynnandtonic
297
20k
Build your cross-platform service in a week with App Engine
jlugia
229
18k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
665
120k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
33
1.9k
Building an army of robots
kneath
302
43k
Building Your Own Lightsaber
phodgson
103
6.1k
How to train your dragon (web standard)
notwaldorf
88
5.7k
Adopting Sorbet at Scale
ufuk
73
9.1k
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 という組版用言語のフォーマッタを作成 してみた 構文解析器からコードの情報を組み立てる作業にのみ集中すればよくなり、コー ドフォーマッタの作成のコストが低下する効果を得ることができた