Jsoup代碼解讀之五-parser(中)

代碼結構

先介紹以下parser包裏的主要類:

  • Parser

Jsoup parser的入口facade,封裝了常用的parse靜態方法。可以設置maxErrors,用於收集錯誤記錄,默認是0,即不收集。與之相關的類有ParseError,ParseErrorList。基於這個功能,我寫了一個PageErrorChecker來對頁面做語法檢查,並輸出語法錯誤。

  • Token

保存單個的詞法分析結果。Token是一個抽象類,它的實現有Doctype,StartTag,EndTag,Comment,Character,EOF6種,對應6種詞法類型。

  • Tokeniser

保存詞法分析過程的狀態及結果。比較重要的兩個字段是state和emitPending,前者保存狀態,後者保存輸出。其次還有tagPending/doctypePending/commentPending,保存還沒有填充完整的Token。

  • CharacterReader

對讀取字符的邏輯的封裝,用於Tokenize時候的字符輸入。CharacterReader包含了類似NIO裏ByteBuffer的consume()、unconsume()、mark()、rewindToMark(),還有高級的consumeTo()這樣的用法。

  • TokeniserState

用枚舉實現的詞法分析狀態機。

  • HtmlTreeBuilder

語法分析,通過token構建DOM樹的類。

  • HtmlTreeBuilderState

語法分析狀態機。

  • TokenQueue

雖然披了個Token的馬甲,其實是在query的時候用到,留到select部分再講。

詞法分析狀態機

現在我們來講講HTML的詞法分析過程。這裏借用一下http://ued.ctrip.com/blog/?p=3295裏的圖,圖中描述了一個Tag標籤的狀態轉移過程,

這裏忽略了HTML註釋、實體以及屬性,只保留基本的開始/結束標籤,例如下面的HTML:

<div>test</div>

Jsoup裏詞法分析比較複雜,我從裏面抽取出了對應的部分,就成了我們的miniSoupLexer(這裏省略了部分代碼,完整代碼可以看這裏MiniSoupTokeniserState):

參考這個程序,可以看到Jsoup的詞法分析的大致思路。分析器本身的編寫是比較繁瑣的過程,涉及屬性值(區分單雙引號)、DocType、註釋、HTML實體,以及一些錯誤情況。不過了解了其思路,代碼實現也是按部就班的過程。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章