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

コンパイラをつくってみよう / How to make a compiler

DQNEO
August 30, 2019

コンパイラをつくってみよう / How to make a compiler

Builderscon 2019 の発表資料です。
ライブコーディングでフルスクラッチでコンパイラを書くというのをやりました。

コンパイラのソースコードはこちらです
https://github.com/DQNEO/HowToWriteACompiler

DQNEO

August 30, 2019
Tweet

More Decks by DQNEO

Other Decks in Programming

Transcript

  1. コンパイラを
    つくってみよう
    @DQNEO (ドキュネオ)
    builderscon 2019.8

    View Slide

  2. コンパイラ書いてみたいと
    思ったことありますか?

    View Slide

  3. 本日のゴール
    ● 「コンパイラやってみよう!」
    と思ってもらうこと

    View Slide

  4. はじめに
    ● 今日はライブコーディングをします
    ● フルスクラッチでコンパイラ作ります
    ● 失敗したらごめんなさい
    ○ (成功したら拍手お願いします)

    View Slide

  5. はじめに
    ● 文字が見づらい場合は教えてください
    ○ 特に後部座席の方
    ● タイポ/エンバグしてたら教えてください

    View Slide

  6. はじめに
    ● 手が震えてたらそれは仕様です

    View Slide

  7. 今日つくるコンパイラ

    View Slide

  8. 今日つくるコンパイラは
    履歴つきで公開しています
    https://github.com/DQNEO/HowToWriteACompiler

    View Slide

  9. 今日つくるコンパイラ(環境)
    ● ターゲット環境:
    ○ Linux
    ○ x86-64: 一般的なPCのCPU (Intel, AMD)
    ○ アセンブリ(GNU Assembler)を吐く

    View Slide

  10. 今日つくるコンパイラ(仕様)
    ● 足し算引き算をコンパイルできる
    ● 結果の数値でexit
    ○ 例 ‘ 30 + 12 ‘ → 42 でexit
    ● ソースコードを標準入力から受け取る
    ● アセンブリを標準出力に吐く

    View Slide

  11. ゴール
    30 + 12 .global main
    main:
    movq $30, %rax
    movq $12, %rcx
    addq %rcx, %rax
    ret
    ソース言語 ターゲット言語
    足し算は実行時に行う

    View Slide

  12. 使用する言語
    ● Go言語で書く
    ○ slice, map, for-rangeなどが便利
    ○ 標準ライブラリが便利
    ● 何言語で書いてもよいです

    View Slide

  13. つくってみよう!!

    View Slide

  14. 素のアセンブリを
    書いて実行
    STEP 0

    View Slide

  15. CPU内にある超高速な一時記憶装置
    CPU
    ← レジスタ
    レジスタ
    出典: http://ftp.procmail.org/~sskulrat/Courses/2006F-170/lectures/chap14/part1.html

    View Slide

  16. 自作スクリプトの説明

    View Slide

  17. Goプログラムから
    アセンブリを吐く
    STEP 1

    View Slide

  18. 標準入力から
    ソースコードを受け取る
    STEP 2

    View Slide

  19. 現状確認
    ソース
    コード
    アセンブリ
    ほぼ仕事してない

    View Slide

  20. ソースコードを
    「解釈」
    するとは

    View Slide

  21. 3つの視点
    全てはByte列
    全てはトークン列
    全ては構造

    View Slide

  22. I say I write a compiler
    この英文をどう解釈するか?

    View Slide

  23. I say I write a compiler
    “I” “ “ “s”
    0x49, 0x20, 0x73...
    ByteReaderさん

    View Slide

  24. I say I write a compiler
    “I”, “say”, “I” ...
    Tokenizerさん(字句解析)

    View Slide

  25. I say I write a compiler
    say
    I write a compiler


    Parserさん(構文解析)
    I
    主語 動詞

    View Slide

  26. -12
    ソースコード

    View Slide

  27. ByteReaderさん
    Byteが
    3個並んでいる
    0x2d 0x31 0x32
    - 1 2
    -12

    View Slide

  28. Tokenizerさん
    - 12
    演算子トークン 数値トークン
    トークンが
    2個並んでいる
    -12

    View Slide

  29. Parserさん
    単項演算子 数値リテラル式
    式の中に式がある
    12
    -
    単項式
    -12

    View Slide

  30. それぞれのフェーズの成果物
    ソースコード
    バイト列
    トークン列 文法構造(式・文)
    バイト列
    トークン列

    View Slide

  31. コード生成さん
    文法構造
    (式・文)
    文法構造を
    アセンブリに変換
    アセンブリ

    View Slide

  32. Unix パイプのように連携
    ソース
    コード
    アセンブリ

    View Slide

  33. Token分割する
    STEP 3

    View Slide

  34. 現状確認
    ソース
    コード
    トークン列

    View Slide

  35. Parse (構文解析)する
    STEP 4

    View Slide

  36. 数値リテラル式
    STEP 5
    42
    int literal expression

    View Slide

  37. 現状確認
    ソース
    コード
    アセンブリ

    View Slide

  38. 単項式 (Unary Expression)
    STEP 6
    1
    -
    operand
    operator
    unary expression

    View Slide

  39. 二項式 (Binary Expression)
    STEP 7
    30
    +
    left
    operator
    binary expression
    12
    right

    View Slide

  40. View Slide

  41. この勢いで1万行書けば、
    コンパイラ自身を
    コンパイルできる!

    View Slide

  42. 自己紹介
    @DQNEO ドキュネオ
    ● アメリカ版メルカリを開発しています
    ● 趣味でGoコンパイラ自作
    https://github.com/DQNEO/minigo

    View Slide

  43. minigoの最初の7コミットを
    丁寧に再現したのが
    今日の内容です
    https://github.com/DQNEO/HowToWriteACompiler

    View Slide

  44. コンパイラを書けると何がいいのか
    ● プログラミング言語が動く仕組みがわかる
    ● 既存のコンパイラが読めるようになる
    ● コンピュータの動きがチョットわかる

    View Slide

  45. コンパイラづくり最大の壁
    ● 「はじめ方がわからない」
    →  これを解決したかった

    View Slide

  46. まずつくってみよう
    ● 学ぶ → つくる ではなく
    ● つくりながら学ぶ を提唱したい
    ○ 私はそうやって学んだ (8ccの写経・移植)
    ○ 今なら chibicc がオススメ

    View Slide

  47. よくある誤解
    ● C言語で書く必要がある
    → 何言語のコンパイラを何言語で書いても
    OK
    ● 特殊な拡張・ライブラリが必要
    → 不要
    ● コンピュータ・サイエンスの知識がいる
    → なくても始められる

    View Slide

  48. 参考資料: Cコンパイラ
    https://github.com/rui314/8cc
    https://github.com/rui314/chibicc
    Sip
    Special thanks to rui さん

    View Slide

  49. まとめ
    ● コンパイラの学び方
    ● 字句解析、構文解析の初歩
    ● フルスクラッチからコンパイラを書きました

    View Slide

  50. コンパイラはいいぞ

    View Slide

  51. ご清聴
    ありがとう
    ございました

    View Slide