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
nanopass-compiler-frameworkを使ってみました
Search
Niyarin
March 25, 2021
Programming
0
430
nanopass-compiler-frameworkを使ってみました
nanopass-compiler-frameworkを使ってみたので、それがどういうものかを紹介した。
Niyarin
March 25, 2021
Tweet
Share
More Decks by Niyarin
See All by Niyarin
Scheme用nREPLの開発(エラー出力の改善)
niyarin
0
150
bel lispの紹介
niyarin
0
740
Gorgos-parser-combinator-written-in-scheme
niyarin
0
390
outputting-beautiful-s-expression
niyarin
0
390
Serialisp
niyarin
1
670
Mongo DBとS式検索
niyarin
0
320
goodbye-python-repl
niyarin
0
360
SchemeのEphemeronとWeak Pairの説明
niyarin
0
1k
red-paren-scheme-rev-macro.pdf
niyarin
0
420
Other Decks in Programming
See All in Programming
MCPで実現するAIエージェント駆動のNext.jsアプリデバッグ手法
nyatinte
6
840
State of CSS 2025
benjaminkott
1
120
レガシープロジェクトで最大限AIの恩恵を受けられるようClaude Codeを利用する
tk1351
2
1.1k
Scale out your Claude Code ~自社専用Agentで10xする開発プロセス~
yukukotani
9
2.6k
CSC305 Summer Lecture 04
javiergs
PRO
1
110
Terraform やるなら公式スタイルガイドを読もう 〜重要項目 10選〜
hiyanger
13
3.2k
学習を成果に繋げるための個人開発の考え方 〜 「学習のための個人開発」のすすめ / personal project for leaning
panda_program
1
110
The state patternの実践 個人開発で培ったpractice集
miyanokomiya
0
150
UbieのAIパートナーを支えるコンテキストエンジニアリング実践
syucream
2
700
物語を動かす行動"量" #エンジニアニメ
konifar
14
5.4k
AI OCR API on Lambdaを Datadogで可視化してみた
nealle
0
180
ゲームの物理
fadis
5
1.5k
Featured
See All Featured
BBQ
matthewcrist
89
9.8k
Fantastic passwords and where to find them - at NoRuKo
philnash
51
3.4k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.8k
Unsuck your backbone
ammeep
671
58k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
46
7.6k
Navigating Team Friction
lara
189
15k
Thoughts on Productivity
jonyablonski
69
4.8k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
31
2.2k
It's Worth the Effort
3n
187
28k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
10
1k
Done Done
chrislema
185
16k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
131
19k
Transcript
Nanopass compiler framework を使ってみました Niyarin
Nanopass compiler frameworkとは - コンパイラを書くためのフレームワーク - コンパイラの中間表現の記述とその変換方法を楽に書け る枠組みを提供してくれる。 - ただし、S式言語
→ S式言語 正確には、Schemeの外部表現で記述できる言語? - Chez Scheme の実装に使われている? - Indiana大(Chezの開発元)のAndy Keepさんのプロダクト
前提知識:Multi-pass compiler - いくつかのフェーズからなるコンパイラ - ↔ one-pass compiler - 部品として切り出せるのが利点
- 入力言語が複数ある場合、Parserの次だけ共通にするとか 一例
前提知識:nano-pass compiler - 1フェーズを最小単位にしたmulti-pass compiler - 利点: 手を入れやすくなる バグ発見が容易になる
- 欠点: 時間、空間計算量の増加
前提知識:nano-pass compilerの各パスに必要なもの 入出力言語とその変換方法
nano-pass compiler framework 各言語定義と変換の方法を容易にする枠組みの提供 - 各パスでの入出力言語の定義を容易にする枠組み - 各パスの変換を容易にする枠組み 入出力はS式 -
字句解析や構文解析は別でやる必要がある(非S式言語の場合)
例 説明に使うコンパイルパスの例 - Piyo言語と名付けたSchemeからほとんどの機能を削った言語 次のページで詳細を書く - Piyo言語lambda式のbodyに複数の式が含まれる形式を消す beginでbody包む (lambda (x)
(display x) (newline) (+ x 1)) → (lambda (x) (begin (display x) (newline) (+ x 1)))
拡張BNFでPiyo言語の文法を記述する <expression> :: = <primitive-procedure> | <boolean> |
<symbol> | (lambda (<symbol> ...) <expression> <expression> ...) | (begin <expression> <expression> ...) | (<expression> ...) - 拡張BNF: 0回以上の繰り返しを “...” で表記したBNF プリミティブ手続き(cons, car, cdr, display) シンボル、ブーリアン lambda式 begin式 手続き適用 左辺に出てこないやつ ( <primitive-procedure> 、 <boolean> 、 <symbol> ) を終端記号と呼ぶ 左辺に出てくるやつ (<expression>)を非終端記号と呼ぶ
Nanopass compiler frameworkでPiyo言語を表現する1 言語の文法をS式の拡張BNFで記述する (define-language piyo-lang (terminals (primitive-procedure (proc)) (boolean
(b)) (symbol (x))) (Expression (e) proc b x (lambda (x ...) e e* ...) (begin e e* ... ) (e e* ...)))
Nanopass compiler frameworkでPiyo言語を表現する1 言語の文法をS式の拡張BNFで記述する (define-language piyo-lang (terminals (primitive-procedure (proc)) (boolean
(b)) (symbol (x))) (Expression (e) proc b x (lambda (x ...) e e* ...) (begin e e* ... ) (e e* ...))) ・終端記号の定義 非終端記号名とメタ変数のリストを並べる メタ変数とは、非終端記号の定義で使われる 変数のようなもの 例えば、symbolのメタ変数はxとして定義している
Nanopass compiler frameworkでPiyo言語を表現する1 言語の文法をS式の拡張BNFで記述する (define-language piyo-lang (terminals (primitive-procedure (proc)) (boolean
(b)) (symbol (x))) (Expression (e) proc b x (lambda (x ...) e e* ...) (begin e e* ... ) (e e* ...))) 非終端記号の定義 非終端記号とメタ変数のリストと定義を書く 拡張BNFをS式にしただけ あるメタ変数に”*”や数字を付けても同じように使える
Nanopass compiler frameworkでPiyo言語を表現する2 終端記号の定義も必要 ・ primitive-procedureやsymbol、booleanについて ・終端記号名に”?”を付けた名前の述語を終端記号の定義としている symbol?とboolean?はSchemeがすでに提供している (define (primitive-procedure?
x) (or (eq? x 'cons) (eq? x 'car) (eq? x 'cdr) (eq? x 'display)))
lambdaから複数bodyが消えたPiyo言語を表現する (define-language single-body-lambda-piyo-lang (extends piyo-lang) (Expression (e) (- (lambda (x
...) e e* ...)) (+ (lambda (x ...) e)))) Piyo言語との差分を書くだけで済む
lambdaから複数bodyが消えたPiyo言語を表現する (define-language single-body-lambda-piyo-lang (extends piyo-lang) (Expression (e) (- (lambda (x
...) e e* ...)) (+ (lambda (x ...) e)))) Piyo言語との差分を書くだけで済む 拡張したい言語名を指定する
lambdaから複数bodyが消えたPiyo言語を表現する (define-language single-body-lambda-piyo-lang (extends piyo-lang) (Expression (e) (- (lambda (x
...) e e* ...)) (+ (lambda (x ...) e)))) Piyo言語との差分を書くだけで済む “-”を頭に付けると削除できる “+”を頭に付けると追加できる
beginでbodyを包む部分を書く syntax-case風の構文で変換規則を書く パターンに当てはまった構文を指定した方法で展開する (define-pass remove-multi-body-lambda : piyo-lang (e) -> single-body-lambda-piyo-lang
() (Expression : Expression (ir) -> Expression () ((lambda (,x ...) ,(e) ,(e*) ...) `(lambda (,x ...) (begin ,e ,e* ...)))))
beginでbodyを包む部分を書く syntax-case風の構文で変換規則を書く (define-pass remove-multi-body-lambda : piyo-lang (e) -> single-body-lambda-piyo-lang ()
(Expression : Expression (ir) -> Expression () ((lambda (,x ...) ,(e) ,(e*) ...) `(lambda (,x ...) (begin ,e ,e* ...))))) 本体 パターン ・ 与えた式の外側から見ていき、パターンにマッチしたものを展開部で置き換え る ・パターン内のメタ変数にマッチしたものは、本体部で参照できる ・この展開を再帰的に行うには、パターンのその部分をリストで囲う
beginでbodyを包む部分を書く syntax-case風の構文で変換規則を書く (define-pass remove-multi-body-lambda : piyo-lang (e) -> single-body-lambda-piyo-lang ()
(Expression : Expression (ir) -> Expression () ((lambda (,x ...) ,(e) ,(e*) ...) `(lambda (,x ...) (begin ,e ,e* ...))))) この辺のごたっとしたのは自信がないのでまた今度。 途中まで書いているので、ブログ等でそれを説明するつもり
不正な入力に対して怒ってくれる(その他の良い点) 入出力言語の文法を定めているため、間違いは指摘してくれる コンパイラの変換規則の記述の間違い コンパイラへの入力の間違い とても親切というほどではないが。 例えば、Piyo言語は数値を受理しないが、それを入れたら怒ってくれ る Exception in parse-piyo-lang:
invalid syntax 3
コンパイルする 変換器に渡すにはパーサーを使って内部表現に変換する必要がある (※ここでのパーサーは、構文解析器のことではない) 言語名とパーサ名を与えれば、パーサとアンパーサができる アンパーサは、パーサ名の頭にunがついたもの (例: un-parse-piyo-lang) (define-parser parse-piyo-lang piyo-lang)
(define input '(cons (lambda (x y) (display x) (lambda (z) (cons x y))) foo ))) (unparse-single-body-lambda-piyo-lang (remove-multi-body-lambda (parse-piyo-lang input)) ; → (cons (lambda (x y) (begin (display x) (lambda (z) (begin (cons x y))))) foo)
おわり ・Nanopass compiler frameworkはすごくよいソフトウェアでした 構文を楽に書ける記法 +とか-とかで拡張できる点 syntax-case風の変換方法 コンパイラの記述やあるパスへの入力が間違っていれば怒ってくれる 入出力言語の文法を与えているため