天天看點

對于Html的解析思路記錄前言html要素最終要達成的形态詞法分析文法分析

前言

最近在學習編譯原理,是以,想搞點事情,另外我工作中也涉及到爬蟲,爬蟲就免不了要對html的解析,雖然正規表達式能解決問題,但是,為了練手,也想寫一個html解析器(後來想想也廢棄了,因為html的解析感覺和編譯原理還是有差別的,但是,讀過一些思路,我也在這裡記錄下來)

html要素

1.标簽

在此次解析中,隻要遇到"<",我們就認為是标簽的開頭,調用對标簽分析的子產品

2.标簽中間内容

在此次解析中,隻要不是遇到"<",我們就認為它是标簽中間的文本内容,調用對文本資訊進行分析的子產品

最終要達成的形态

1.需要一個整個網頁标簽組成的樹狀資料結構,表現出标簽間的嵌套關系

2.需要一個索引,索引name和id的标簽,友善查找

(這是我暫時想到的)

詞法分析

詞法分析需要達到的效果

舉例子:

<html>
	<img src='http://test.png' id='test' />
	<a href='http://baidu.com'>百度</a>
</html>
           

效果:

對于Html的解析思路記錄前言html要素最終要達成的形态詞法分析文法分析

圖中淺藍色部分為标簽主線,白色部分為屬性,黃色部分為值,就這樣,建構一個連結清單,

怎麼建構這樣一個連結清單呢?

1.逐個字元讀入詞法分析器
2.遇到"<"開頭,就認為是标簽,則調用标簽分析程式
3.在标簽分析程式中,跟在"<"後面的就是标簽名稱,逐個字元讀取,知道遇到"空格"結束,然後繼續讀取,遇到的都是屬性名,以及屬性值,同樣是以遇到空格或者"="為一個機關,如果遇到'/"開頭,則是剛剛讀取完成的屬性名對應的屬性值,将其添加到此屬性名的連結清單後面,知道遇到">"結束,并且将指針,即string的下标移動到這個字元的下标位置
4.如果不是"<"開頭,則認為是文字,就别管那麼多,一直到遇到"<"為止
           

大緻的分析過程就是這樣,當然還有一些細節需要處理

文法分析

文法分析最終需要生成一顆文法樹,是以需要對html的連結清單進行解析,另外我還需要在生成文法樹的過程中,為id以及name添加索引,友善查找

首先需要一個存放每個标簽的資料結構

我這裡用一個對象進行存放,設為Tag,同時這個對象也是樹形結構中的一個屬性,我這裡設樹形結構為Node

最終,需要達成的結構是

對于Html的解析思路記錄前言html要素最終要達成的形态詞法分析文法分析

要怎麼做到這個效果呢,我能想到就是把改分析的資料壓到棧中,分析完成就出棧,舉例子:

1.首先,需要一個分析使用的棧
2.我拿到連結清單的頭<html>标簽,然後将html壓到棧中,然後樹的根節點增加一個html的Tag對象,裡面存放你想存放的資訊
3.然後再講<img/>放到棧中,然後在html的根節點下生成一個img的葉節點,并且将src,以及id,放到img的Tag對象中,将tag對象放到新增的葉節點中
4.由于img為單标簽(因為以“/>”結束),是以分析完img标簽後就将分析棧中的img彈出
5.将&lt;a>标簽壓到分析棧中,分析,将屬性記錄,再将text壓到棧中,記錄,并且将text彈出棧
6.将&lt;/a>标簽壓到棧中,遇到了</,為結尾符号,将</a>彈出棧,彈出棧後,檢測棧頂标簽是否為&lt;a>标簽,如果是,就彈出棧,否則,不做處理
7.然後就是遇到</html>标簽,同理,檢測是否<html>标簽,是,就出棧,否則不處理