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

Taipei.rb 寫一個送禮自用兩相宜的 Compiler

蒼時弦や
February 14, 2018

Taipei.rb 寫一個送禮自用兩相宜的 Compiler

蒼時弦や

February 14, 2018
Tweet

More Decks by 蒼時弦や

Other Decks in Programming

Transcript

  1. 用 Ruby 寫一個送禮自用
    兩相宜的 Compiler

    View Slide



  2. 䓛⛳
    @elct9620
    WEB DEVELOPER
    GAME DEVELOPER

    View Slide

  3. View Slide

  4. View Slide

  5. #I_feel_border
    ⼤大家都在寫 Compier 作業

    View Slide

  6. C4 不夠⽤用就⽤用 C5 啊!
    https://github.com/elct9620/5compiler
    Demo First Talk

    View Slide

  7. Lexer
    Tokenizer
    Parser
    Source Code
    AST

    View Slide

  8. 簡單說就是照規則把字串串切開來來
    Lexer

    View Slide

  9. Lexer.new("count = 1 if reset")
    # ['count', '=', '1', 'if', 'reset']
    Lexer

    View Slide

  10. class Lexer < Array
    KEYWORDS =
    %w[if else end puts].freeze
    KEYWORD_RULE =
    /(?#{KEYWORDS.join('|')})/
    end
    Lexer

    View Slide

  11. RULE = Regexp.union(
    LINEFEED_RULE,
    SYMBOL_RULE,
    KEYWORD_RULE,
    STRING_RULE,
    NUMBER_RULE,
    WORD_RULE
    )
    Lexer

    View Slide

  12. script.scan(RULE).flatten.compact
    # ['count', '=', '1', 'if', 'reset']
    Lexer

    View Slide

  13. 把 Lexer 切好的⽂文字片段做簡單的分類
    Tokenizer

    View Slide

  14. Tokeinzer.new(['if', 'reset'])
    # [
    # # @value="if">
    # # @value="reset">
    # ]
    Tokenizer

    View Slide

  15. MATCH_RULES.each do |type, rule|
    if word.match?(rule)
    return Token.new(type, word)
    end
    end
    Token.new(:literal, word)
    Tokenizer

    View Slide

  16. class Token
    # ...
    def symbol?
    type == :symbol
    end
    # ...
    end
    Tokenizer

    View Slide

  17. 依照 Token 的狀狀況轉換成⽤用樹狀狀的⽅方式表⽰示程式運作
    Parser

    View Slide

  18. IF
    TRUE FALSE
    BLOCK BLOCK

    View Slide

  19. class Parser
    def parse
    tokens = @tokenizer.to_enum
    @context =
    Node::Context.new(tokens)
    @ast = context.ast
    end
    end
    Parser

    View Slide

  20. loop do
    break if t.peek.else? || #...
    #…
    if t.peek.fn?
    next @ast << Node::Function.new(t)
    end
    #...
    end
    Parser

    View Slide

  21. Context
    Parser
    Function
    Enter
    Context State
    Exit State
    Next token is ‘else’
    Enter
    Function State
    Exit State
    Next token is ‘end’

    View Slide

  22. 基於 Parser ⽣生成的 Abstract Syntax Tree 執⾏行行程式
    Virtual Machine

    View Slide

  23. 將 AST 轉換為機器碼或者 VM 可以直接讀取的規格
    Bytecode

    View Slide

  24. 借⽤用 Ruby VM 直接執⾏行行 `Kernel.send(‘puts’, ‘Hello World’)`
    5Compiler’s VM

    View Slide

  25. 在 Router 中可以⽤用來來判斷⽬目前請求的網址對應的 Controller
    Rails’s AST

    View Slide

  26. 在 ActiveRecord (Arel) 可以⽤用來來組成 SQL 語法
    Rails’s AST

    View Slide

  27. ⽤用來來動態執⾏行行 ActiveRecord 相關的動作 Ex. JSON Query, Update …
    Tamashii::TLang’s AST

    View Slide

  28. 很可惜困難的是 VM 怎麼動起來來喔⋯⋯
    聽起來來好像很簡單,對吧?

    View Slide

  29. View Slide