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
31
係り受け解析を用いた法律文書中の略称規定の解析についての報告
puripuri2100
0
2.1k
気胸の胸部CTデータの可視化
puripuri2100
0
240
SATySFiで作成する構文解析器
puripuri2100
0
190
SATySFiの開発についての要望
puripuri2100
0
380
研究の場においてのRust 製ソフトウェアのバージョン管理について
puripuri2100
0
530
法律文書の自動解析
puripuri2100
1
650
ユーザーがカスタマイズできるクラスファイル ―v0.0.x と v0.1.x それぞれでの実装 ―
puripuri2100
0
320
mdbook-satysfiを作成しました
puripuri2100
0
580
Other Decks in Technology
See All in Technology
5分でわかるDuckDB
chanyou0311
10
3.2k
re:Invent をおうちで楽しんでみた ~CloudWatch のオブザーバビリティ機能がスゴい!/ Enjoyed AWS re:Invent from Home and CloudWatch Observability Feature is Amazing!
yuj1osm
0
120
Postman と API セキュリティ / Postman and API Security
yokawasa
0
200
NilAway による静的解析で「10 億ドル」を節約する #kyotogo / Kyoto Go 56th
ytaka23
3
370
10個のフィルタをAXI4-Streamでつなげてみた
marsee101
0
160
LINEスキマニにおけるフロントエンド開発
lycorptech_jp
PRO
0
330
サイボウズフロントエンドエキスパートチームについて / FrontendExpert Team
cybozuinsideout
PRO
5
38k
複雑性の高いオブジェクト編集に向き合う: プラガブルなReactフォーム設計
righttouch
PRO
0
110
小学3年生夏休みの自由研究「夏休みに Copilot で遊んでみた」
taichinakamura
0
140
社外コミュニティで学び社内に活かす共に学ぶプロジェクトの実践/backlogworld2024
nishiuma
0
250
10分で学ぶKubernetesコンテナセキュリティ/10min-k8s-container-sec
mochizuki875
3
320
成果を出しながら成長する、アウトプット駆動のキャッチアップ術 / Output-driven catch-up techniques to grow while producing results
aiandrox
0
180
Featured
See All Featured
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
356
29k
Testing 201, or: Great Expectations
jmmastey
40
7.1k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
169
50k
Designing Experiences People Love
moore
138
23k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
48
2.2k
Embracing the Ebb and Flow
colly
84
4.5k
Site-Speed That Sticks
csswizardry
2
190
Intergalactic Javascript Robots from Outer Space
tanoku
270
27k
Navigating Team Friction
lara
183
15k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
6
510
Fantastic passwords and where to find them - at NoRuKo
philnash
50
2.9k
Code Reviewing Like a Champion
maltzj
520
39k
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 という組版用言語のフォーマッタを作成 してみた 構文解析器からコードの情報を組み立てる作業にのみ集中すればよくなり、コー ドフォーマッタの作成のコストが低下する効果を得ることができた