日期:2014-05-17 浏览次数:20726 次
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事件发生