Upgrade to Pro — share decks privately, control downloads, hide ads and more …

nanopass-compiler-frameworkを使ってみました

Niyarin
March 25, 2021

 nanopass-compiler-frameworkを使ってみました

nanopass-compiler-frameworkを使ってみたので、それがどういうものかを紹介した。

Niyarin

March 25, 2021
Tweet

More Decks by Niyarin

Other Decks in Programming

Transcript

  1. Nanopass compiler frameworkとは - コンパイラを書くためのフレームワーク - コンパイラの中間表現の記述とその変換方法を楽に書け る枠組みを提供してくれる。 - ただし、S式言語

    → S式言語 正確には、Schemeの外部表現で記述できる言語? - Chez Scheme の実装に使われている? - Indiana大(Chezの開発元)のAndy Keepさんのプロダクト
  2. 拡張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>)を非終端記号と呼ぶ
  3. 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として定義している
  4. 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式にしただけ  あるメタ変数に”*”や数字を付けても同じように使える
  5. lambdaから複数bodyが消えたPiyo言語を表現する (define-language single-body-lambda-piyo-lang (extends piyo-lang) (Expression (e) (- (lambda (x

    ...) e e* ...)) (+ (lambda (x ...) e)))) Piyo言語との差分を書くだけで済む 拡張したい言語名を指定する
  6. lambdaから複数bodyが消えたPiyo言語を表現する (define-language single-body-lambda-piyo-lang (extends piyo-lang) (Expression (e) (- (lambda (x

    ...) e e* ...)) (+ (lambda (x ...) e)))) Piyo言語との差分を書くだけで済む “-”を頭に付けると削除できる “+”を頭に付けると追加できる
  7. 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* ...))))) 本体 パターン ・ 与えた式の外側から見ていき、パターンにマッチしたものを展開部で置き換え る ・パターン内のメタ変数にマッチしたものは、本体部で参照できる ・この展開を再帰的に行うには、パターンのその部分をリストで囲う
  8. 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* ...))))) この辺のごたっとしたのは自信がないのでまた今度。 途中まで書いているので、ブログ等でそれを説明するつもり