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
25
係り受け解析を用いた法律文書中の略称規定の解析についての報告
puripuri2100
0
1.9k
気胸の胸部CTデータの可視化
puripuri2100
0
230
SATySFiで作成する構文解析器
puripuri2100
0
180
SATySFiの開発についての要望
puripuri2100
0
370
研究の場においてのRust 製ソフトウェアのバージョン管理について
puripuri2100
0
520
法律文書の自動解析
puripuri2100
1
610
ユーザーがカスタマイズできるクラスファイル ―v0.0.x と v0.1.x それぞれでの実装 ―
puripuri2100
0
310
mdbook-satysfiを作成しました
puripuri2100
0
550
Other Decks in Technology
See All in Technology
使えそうで使われないCloudHSM
maikamibayashi
1
250
最速最小からはじめるデータプロダクト / Data Product MVP
amaotone
5
770
生成AIとAWS CDKで実現! 自社ブログレビューの効率化
ymae
2
410
Product Engineer Night #6プロダクトエンジニアを育む仕組み・施策
hacomono
PRO
1
510
ZOZOTOWNでの推薦システム活用事例の紹介
f6wbl6
0
220
IaC運用を楽にするためにCDK Pipelinesを導入したけど、思い通りにいかなかった話
smt7174
1
120
Autify Company Deck
autifyhq
1
39k
AWS CodePipelineでコンテナアプリをデプロイした際に、古いイメージを自動で削除する
smt7174
1
130
10分でわかるfreee エンジニア向け会社説明資料
freee
18
520k
生成AIと知識グラフの相互利用に基づく文書解析
koujikozaki
1
150
AWS re:Inventを徹底的に楽しむためのTips / Tips for thoroughly enjoying AWS re:Invent
yuj1osm
1
660
物価高なラスベガスでの過ごし方
zakky
0
470
Featured
See All Featured
Build The Right Thing And Hit Your Dates
maggiecrowley
32
2.4k
Java REST API Framework Comparison - PWX 2021
mraible
PRO
28
8k
The Cost Of JavaScript in 2023
addyosmani
45
6.6k
Ruby is Unlike a Banana
tanoku
96
11k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
167
49k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
42
9.2k
Typedesign – Prime Four
hannesfritz
39
2.4k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
228
52k
Stop Working from a Prison Cell
hatefulcrawdad
267
20k
The Pragmatic Product Professional
lauravandoore
31
6.3k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
131
33k
How STYLIGHT went responsive
nonsquared
95
5.2k
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 という組版用言語のフォーマッタを作成 してみた 構文解析器からコードの情報を組み立てる作業にのみ集中すればよくなり、コー ドフォーマッタの作成のコストが低下する効果を得ることができた