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 full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  13. つくってみよう!!

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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


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

    View full-size slide

  26. -12
    ソースコード

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  33. Token分割する
    STEP 3

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  49. コンパイラはいいぞ

    View full-size slide

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

    View full-size slide