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
410
nanopass-compiler-frameworkを使ってみました
nanopass-compiler-frameworkを使ってみたので、それがどういうものかを紹介した。
Niyarin
March 25, 2021
Tweet
Share
More Decks by Niyarin
See All by Niyarin
Scheme用nREPLの開発(エラー出力の改善)
niyarin
0
140
bel lispの紹介
niyarin
0
690
Gorgos-parser-combinator-written-in-scheme
niyarin
0
370
outputting-beautiful-s-expression
niyarin
0
360
Serialisp
niyarin
1
640
Mongo DBとS式検索
niyarin
0
290
goodbye-python-repl
niyarin
0
340
SchemeのEphemeronとWeak Pairの説明
niyarin
0
950
red-paren-scheme-rev-macro.pdf
niyarin
0
390
Other Decks in Programming
See All in Programming
신입 안드로이드 개발자의 AI 스타트업 생존기 (+ Native C++ Code를 Android에서 사용해보기)
dygames
0
480
RCPと宣言型ポリシーについてのお話し
kokitamura
2
130
なぜselectはselectではないのか
taiyow
2
280
今から始めるCursor / Windsurf / Cline
kengo_hayano
0
100
php-fpm がリクエスト処理する仕組みを追う / Tracing-How-php-fpm-Handles-Requests
shin1x1
4
760
Kubernetesで実現できるPlatform Engineering の現在地
nwiizo
2
1.6k
Gunma.web #55
tinykitten
0
130
PHPUnit 高速化テクニック / PHPUnit Speedup Techniques
pinkumohikan
1
800
Django for Data Science (Boston Python Meetup, March 2025)
wsvincent
0
190
アプリのビルドを楽にするかわいいスクリプトを作ってみた
reimim
0
120
いまさら聞けない生成AI入門: 「生成AIを高速キャッチアップ」
soh9834
11
3.2k
보일러플레이트 코드가 진짜 나쁜 건가요?
gaeun5744
0
360
Featured
See All Featured
Fantastic passwords and where to find them - at NoRuKo
philnash
51
3.1k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
120k
Facilitating Awesome Meetings
lara
53
6.3k
Code Review Best Practice
trishagee
67
18k
Gamification - CAS2011
davidbonilla
80
5.2k
The Power of CSS Pseudo Elements
geoffreycrofte
75
5.7k
KATA
mclloyd
29
14k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
12k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
4
460
Thoughts on Productivity
jonyablonski
69
4.5k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
28
2k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
40
2k
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風の変換方法 コンパイラの記述やあるパスへの入力が間違っていれば怒ってくれる 入出力言語の文法を与えているため