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

Day25. 如何解析 HTML 語法

Kalan
October 04, 2020

Day25. 如何解析 HTML 語法

Kalan

October 04, 2020
Tweet

More Decks by Kalan

Other Decks in Programming

Transcript

  1. 第 12 屆 IT 鐵⼈賽
    30 天從 0 到 1 學 Svelte
    Day25 - 如何解析 HTML(svelte)語法?

    View full-size slide

  2. 第 12 屆 IT 鐵⼈賽
    解析 HTML 的⽬的
    將語法轉成比較容易給程式處理的語法樹(AST)

    View full-size slide

  3. 第 12 屆 IT 鐵⼈賽
    流程概覽
    詞法分析
    (Lexer)
    語法分析 ⽣成抽象語法樹 ⽣成程式碼

    View full-size slide

  4. 第 12 屆 IT 鐵⼈賽
    流程概覽
    詞法分析
    (Lexer)
    語法分析 ⽣成抽象語法樹 ⽣成程式碼

    View full-size slide

  5. 第 12 屆 IT 鐵⼈賽
    如何將語法轉為語法樹
    div
    p p p
    Hello text text


    Hello"

    text"

    text"

    "

    View full-size slide

  6. 第 12 屆 IT 鐵⼈賽
    有限狀態機
    tag_open tag_name
    <
    read_text
    attribute tag_close
    />
    attribute_name =
    data-toggle attribute_value
    " "

    View full-size slide

  7. 第 12 屆 IT 鐵⼈賽
    範例 1
    Hello
    讀取 "<": 進入 tag_open 狀態,開始讀取 tag_name
    讀取 "d":進入 tag_name 狀態,name += "d"
    讀取 "i":tag_name 狀態,name += "i"
    讀取 "v":tag_name 狀態,name += "v"
    讀取 ">":回到初始狀態,保存當前 tag_name

    View full-size slide

  8. 第 12 屆 IT 鐵⼈賽
    範例 1
    Hello
    讀取 "H":進入 text 狀態,讀取 text += "H"
    讀取 "e":text 狀態,讀取 text += "e"
    讀取 "l":text 狀態,讀取 text += "l"
    讀取 "l":text 狀態,讀取 text += "l"
    讀取 "o":text 狀態,讀取 text += "o"
    讀取 "<":進入 tag_open 狀態
    讀取:"/":進入 tag_close 狀態
    讀取 "div":將 tag_name 設為 div
    讀取 ">":回到初始狀態,完成解析

    View full-size slide

  9. 第 12 屆 IT 鐵⼈賽
    解析後產⽣的資料
    type: Element
    tag_name: div
    children: [{ type: 'Text', data: 'Hello' }]

    View full-size slide

  10. 第 12 屆 IT 鐵⼈賽
    範例 2
    Hello
    讀取 "<": 進入 tag_open 狀態,開始讀取 tag_name
    讀取 "p":進入 tag_name 狀態,name += "p"
    讀取 " ":忽略
    讀取 "r":進入 attribute_name 狀態,attr += "r"
    讀取 "o":attribute_name 狀態,attr += "o"
    讀取 "l":attribute_name 狀態,attr += "l"
    讀取 "e":attribute_name 狀態,attr += "e"

    View full-size slide

  11. 第 12 屆 IT 鐵⼈賽
    範例 2
    Hello
    讀取 "=": 進入 attribute_value 狀態,開始讀取 value
    讀取 """:attribute_value_double_quote 狀態
    讀取 "s":attribute_value 狀態,attr += "s"
    讀取 "t":attribute_value 狀態,attr += "t"
    讀取 "a":attribute_value 狀態,attr += "a"
    讀取 "t":attribute_value 狀態,attr += "t"
    讀取 "u":attribute_value 狀態,attr += "u"
    讀取 "s":attribute_value 狀態,attr += "s"

    View full-size slide

  12. 第 12 屆 IT 鐵⼈賽
    範例 2
    Hello
    讀取 """: 退出 attribute_value 狀態
    讀取 ">":進入 tag_close 狀態
    讀取...:流程省略

    View full-size slide

  13. 第 12 屆 IT 鐵⼈賽
    解析後產⽣的資料
    type: Element
    tag_name: p
    attrs: { role: "status" }
    children: [{ type: 'Text', data: 'Hello' }]

    View full-size slide

  14. 第 12 屆 IT 鐵⼈賽
    HTML 是可遞迴的標記語⾔
    例如:

    Text 1

    1234
    45567


    View full-size slide

  15. 第 12 屆 IT 鐵⼈賽
    遞迴下降解析器

    View full-size slide

  16. 第 12 屆 IT 鐵⼈賽
    為什麼 Svelte 要⾃⼰寫解析器?
    ⽀援 svelte 語法如 bind, on, if block 等等
    解析後可以在編譯時做到依賴追蹤、變數宣告與否、警告等

    View full-size slide

  17. 第 12 屆 IT 鐵⼈賽
    ⼀些要注意的事情
    HTML 可⽀援某些無 close 的標籤
    ⼤⼩寫
    省略了像是 CDATA、comment 等處理
    https://html.spec.whatwg.org/multipage/parsing.html

    View full-size slide