学习内容来自于HTML5Rocks网站,《浏览器的工作原理:现代浏览器幕后揭秘》,简单输入输出一下读后笔记。
解析
解析文档是指将文档转化成有意义的结构,也就是可让代码理解和使用的结构。
解析得到的结果通常是代表了文档结构的节点树,它称作解析树或者语法树。
HTML解析
HTML语法定义
常规解析器都不适用于HTML,HTML并不能很容易地用解析器所需的的上下文无关的语法来定义。
有一种可以定义HTML的正规格式:DTD(Document Type Definition,文档类型定义),但它还是与上下文无关的语法。原因是HTML的语法处理很宽容,允许省略某些隐匿添加的标记,有时还能省略一些起始或者结束标记等等。
DOM
解析器输出的“解析树”是由DOM元素与属性节点构成的树结构。DOM是文档对象模型(Document Object Model)的缩写。它是HTML文档的对象表示,同时也是外部内容与HTML元素之间的接口。
HTML5规范详细地打描述了解析算法。此算法由两个阶段组成:标记化和树构建。
![HTML解析流程][fig9]
[fig9]:http://1-ps.googleusercontent.com/x/s.html5rocks-hrd.appspot.com/www.html5rocks.com/zh/tutorials/internals/howbrowserswork/308x400ximage017.png.pagespeed.ic.BGy2jYmiQr.jpg "HTML5规范中的解析流程"
解析算法
我们在之前章节已经说过,HTML 无法用常规的自上而下或自下而上的解析器进行解析。
原因在于:
- 语言的宽容本质。
- 浏览器历来对一些常见的无效 HTML 用法采取包容态度。
- 解析过程需要不断地反复。源内容在解析过程中通常不会改变,但是在 HTML 中,脚本标记如果包含 document.write,就会添加额外的标记,这样解析过程实际上就更改了输入内容。
HTML的解析算法由两个阶段组成:标记化和树构建
标记化算法
Hello world
初始状态是数据状态,当遇到字符<
时,状态更改为“标记打开状态”。接收一个a-z
字符会创建“起始标记”,状态更改为“标记名称状态”。这个状态会一直保持到接收>
。在此期间接收的每个字符都会附加到新的标记名称上。在本例中,我们创建的标记是html
标记。
遇到>
标记时,会发送当前的标记,状态发回“数据状态”。标记也会进行同样的处理。目前
html
和body
标记均已发出。现在我们回到“数据状态”。接收到Hello world
中的H
字符时,将创建并发送字符标记,直到接收中的
<
。我们将为Hello world
中的每个字符都发送一个字符标记。
现在我们回到“标记打开状态”。接收下一个输入字符/
时,会创建end tag token
并改为“标记名称状态”。我们会再次保持这个状态,直到接收>
。然后将发送新的标记,并回到“数据状态”。