日期:2014-05-17  浏览次数:20726 次

浏览器内核引擎——渲染引擎续(HTML解析)
html语法分析:

html解析器的工作是解析html到解析树。html的词汇与语法定义在W3C创建的规范中,语法可以用类似的BNF(巴克斯
范式)来定义,下面来看一个概念:
上下文无关文法:

在计算机科学中,若一个形式文法 G = (N, Σ, P, S) 的产生式规则
都取如下的形式:V ->

 w

,則称之为上下文无关的

,其中 V∈N ,w

∈(N∪Σ)* 。上下文无关文法取名为“上下文无关”
的原因就是因为字符 V 总可以被字串 w 自由替换,而无需考虑字符 V 出现的上下文。一个形式语言是上下文无关的,
html无法用解析器所需的上下文无关文法语法来定义,过去的html有格式规范的DTD(dcoument)来定义,但是他
不是一个上下文无关文法。
html DTD


html的定义使用DTD文件,这种格式用来定义SGML族语言,它包含了对所有元素的定义,包括他们的属性和层次关系
DOM


语法分析输出的树是由DOM元素和属性节点组成的,DOM全称是Document Object Model,他是HTML文档对象
对象化表述,也是html元素与外界(javascript)的接口
DOM与标签一一对应,如下面的标签
<html>
	<body>
		<p>
			Hello World
		</p>
		<div> <img src="example.png"/></div>
	</body>
</html>
转换成DOM




?解析算法:
htm无法l使用自上而下或者自下而上语法分析
理由如下:
1.语言的宽容特点
2.浏览器需要对无效的html提供容错的事实
3.解析过程反复,通常解析过程中源码不会变化,但在html中由于脚本的原因,解析过程会改变源码
浏览器创建了自己的解析器来解析html文档,解析器分为两部分:粉刺和构建树,分析属于词法分析,它把输入解析成
符号序列,在html中符号就是开始标签,结束标签,属性标签和属性值
分词识别这些符号并送入熟的构架者,然后继续分析下一个符号,直到输入结束




?分词算法:
算法的输出是HTML符号。算法可以用状态机来描述。 每一个状态从输入流中消费一个或多个字符,并根据它们更新
下一状态。决策受当前符号状态和树的构建状态影响。这意味着同样的字符可能会产生不同的结果,取决于当前的状
态。算法太复杂,我们用一个例子来看看它的原理。

分析下面的标签
<html>
	<body>
		Hello world
	</body>
</html>
     初始状态是“Data state”当遇到“<“时状态改为”Tag open state“吃掉”a-z”字符组成的符号后产生了
”Start tag token”,状态变更为“Tag name state”

。我们一直保持此状态,直到遇到”>”。每个字符都被追加到
新的符号名上。在我们的例子中,解出的符号就是”html”。
     当碰到”>”时,当前符号完成,状态改回“Data state”

。”<body>”标签将会以同样的方式处理。现在”html”
与”body”标签都完成了,我们回到“Data state”

状态。吃掉”H”(”Hello world”第一个字母)时会产生一个字符
符号,直到碰到”</body>”的”<”符号,我们就完成了一个字符符号”Hello world”
      现在我们回到“Tag open state”

状态。吃掉下一个输入”/”时会产生一个”end tag token”并变更为
“Tag name state”

状态。同样,此状态保持到我们碰到”>”时。这时新标签符号完成,我们又回到“Data state”

。
同样”</html>”也会被这样处理。

如下图所示:




?树的构建算法:
构建书这一阶段的输入是符号识别阶段生成的符号序列
构建时“initial mode”,接受到html符号后转换为”before html“ 模式,但是这个模式对这个符号进行再处理,此时,
创建了一个HTMLHtmlElement元素,并将其附加到跟Document对象上
状态变为”before head “,接收到body符号时,这里即使没有head符号,也将自动创建一个HTMLBodyElement
元素,并附加到树上
现在,转到”in head“模式,然后是”after head“,到这里,body会再次处理,将创建一个htmlBodyElement
元素附加到树上,同时转移到”in body“模式
然后,接收到字符串”hello world“第一个字符将导致创建并插入一个text节点,其他字符将附加到该节点
接收到body的结束符时,
接收到body结束符时,转移到”after body“模式,接着接收到html结束符符号,这个节点意味着转移到了”after after
body“模式,当接收到文件结束符时,整个解析过程结束



?解析结束后的动作
这一阶段浏览器会把文档标记为交互模式,并开始解析deferred模式中的script。“deferred”意味着脚本应该在文档
解析完成后执行,脚本处理完成进入“complete“状态,load事件发生