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
460
nanopass-compiler-frameworkを使ってみました
nanopass-compiler-frameworkを使ってみたので、それがどういうものかを紹介した。
Niyarin
March 25, 2021
Tweet
Share
More Decks by Niyarin
See All by Niyarin
Scheme用nREPLの開発(エラー出力の改善)
niyarin
0
160
bel lispの紹介
niyarin
0
770
Gorgos-parser-combinator-written-in-scheme
niyarin
0
400
outputting-beautiful-s-expression
niyarin
0
400
Serialisp
niyarin
1
690
Mongo DBとS式検索
niyarin
0
340
goodbye-python-repl
niyarin
0
380
SchemeのEphemeronとWeak Pairの説明
niyarin
0
1.1k
red-paren-scheme-rev-macro.pdf
niyarin
0
440
Other Decks in Programming
See All in Programming
脳の「省エネモード」をデバッグする ~System 1(直感)と System 2(論理)の切り替え~
panda728
PRO
0
130
AIで開発はどれくらい加速したのか?AIエージェントによるコード生成を、現場の評価と研究開発の評価の両面からdeep diveしてみる
daisuketakeda
1
230
AI時代を生き抜く 新卒エンジニアの生きる道
coconala_engineer
1
500
CSC307 Lecture 02
javiergs
PRO
1
740
Python札幌 LT資料
t3tra
7
1.1k
AI前提で考えるiOSアプリのモダナイズ設計
yuukiw00w
0
210
CSC307 Lecture 03
javiergs
PRO
1
460
ELYZA_Findy AI Engineering Summit登壇資料_AIコーディング時代に「ちゃんと」やること_toB LLMプロダクト開発舞台裏_20251216
elyza
2
920
ローカルLLMを⽤いてコード補完を⾏う VSCode拡張機能を作ってみた
nearme_tech
PRO
0
240
GISエンジニアから見たLINKSデータ
nokonoko1203
0
190
perlをWebAssembly上で動かすと何が嬉しいの??? / Where does Perl-on-Wasm actually make sense?
mackee
0
280
LLM Çağında Backend Olmak: 10 Milyon Prompt'u Milisaniyede Sorgulamak
selcukusta
0
140
Featured
See All Featured
Leo the Paperboy
mayatellez
1
1.3k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
1.7k
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
Building an army of robots
kneath
306
46k
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
1
590
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
10
770
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
870
ラッコキーワード サービス紹介資料
rakko
0
1.9M
svc-hook: hooking system calls on ARM64 by binary rewriting
retrage
1
46
End of SEO as We Know It (SMX Advanced Version)
ipullrank
2
3.8k
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
130
sira's awesome portfolio website redesign presentation
elsirapls
0
110
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風の変換方法 コンパイラの記述やあるパスへの入力が間違っていれば怒ってくれる 入出力言語の文法を与えているため