前言
最近在学习编译原理,因此,想搞点事情,另外我工作中也涉及到爬虫,爬虫就免不了要对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>
效果:
图中浅蓝色部分为标签主线,白色部分为属性,黄色部分为值,就这样,构建一个链表,
怎么构建这样一个链表呢?
1.逐个字符读入词法分析器
2.遇到"<"开头,就认为是标签,则调用标签分析程序
3.在标签分析程序中,跟在"<"后面的就是标签名称,逐个字符读取,知道遇到"空格"结束,然后继续读取,遇到的都是属性名,以及属性值,同样是以遇到空格或者"="为一个单位,如果遇到'/"开头,则是刚刚读取完成的属性名对应的属性值,将其添加到此属性名的链表后面,知道遇到">"结束,并且将指针,即string的下标移动到这个字符的下标位置
4.如果不是"<"开头,则认为是文字,就别管那么多,一直到遇到"<"为止
大致的分析过程就是这样,当然还有一些细节需要处理
语法分析
语法分析最终需要生成一颗语法树,因此需要对html的链表进行解析,另外我还需要在生成语法树的过程中,为id以及name添加索引,方便查找
首先需要一个存放每个标签的数据结构
我这里用一个对象进行存放,设为Tag,同时这个对象也是树形结构中的一个属性,我这里设树形结构为Node
最终,需要达成的结构是
要怎么做到这个效果呢,我能想到就是把改分析的数据压到栈中,分析完成就出栈,举例子:
1.首先,需要一个分析使用的栈
2.我拿到链表的头<html>标签,然后将html压到栈中,然后树的根节点增加一个html的Tag对象,里面存放你想存放的信息
3.然后再讲<img/>放到栈中,然后在html的根节点下生成一个img的叶节点,并且将src,以及id,放到img的Tag对象中,将tag对象放到新增的叶节点中
4.由于img为单标签(因为以“/>”结束),所以分析完img标签后就将分析栈中的img弹出
5.将<a>标签压到分析栈中,分析,将属性记录,再将text压到栈中,记录,并且将text弹出栈
6.将</a>标签压到栈中,遇到了</,为结尾符号,将</a>弹出栈,弹出栈后,检测栈顶标签是否为<a>标签,如果是,就弹出栈,否则,不做处理
7.然后就是遇到</html>标签,同理,检测是否<html>标签,是,就出栈,否则不处理