3.解析和DOM树建设
3.1 一般解析
由于解析在渲染引擎中是一个很重要的过程,我们将更加深刻的讲解。让我们开始一个有关解析的简要介绍。
解析文档意味着将其转换成一些有意义的结构----代码可以理解和使用。解析的结果通常是一个树的节点表示文档的结构,它被称为解析树或语法树。
范例 - 解析表达式2 + 3 - 1,可以返回此树:
图5:数学表达式树节点
3.1.1 文法
解析是基于文档所遵循的语法规则 ---- 所写文档的语言或格式。每次解析你可以的格式必须具有确定性的词汇和语法规则的语法。这就是所谓的上下文无关文法。人类的语言是没有这样的语言,因此不能用传统的解析技术解析。
3.1.2 词法分析器 - 组合
解析可分为两个子过程 ---- 词法分析和语法分析。
词法分析是分解成记号输入的过程。记号是语言词汇 ---- 收集的有效的积木。在人类语言中,它将包括所有的在该语言字典中出现的词汇。
句法分析采用的是语法规则。
分析器通常把要做的工作分解为两个部分----词法分析(有时也叫做记号分析)负责分成输入有效的记号;解析器负责分析文档的结构,根据语言的语法规则,构造解析树。词法分析器知道如何去掉无关的字符,例如空格和换行符。
图6:从源文件解析的树
解 析过程是迭代的。解析器通常会要求词法分析器一个新的记号,尝试用语法规则来匹配记号。如果规则匹配,一个节点对应的记号将被添加到该解析树,解析器会请 求另一个记号。如果没有匹配的规则,解析器将内部存储记号,并不断请求记号,直到在所有内部存储的记号中找到一个规则匹配的。如果发现没有规则,解析器将 抛出一个异常。这意味着该文件是无效的,并包含语法错误。
3.1.3 翻译
解析树很多时候,是不是最终产品。解析中经常使用翻译 ---- 转换为另一种格式的输入文件。编译就是一个例子。编译器的源代码编译成机器代码首先解析成语法树,然后翻译成机器代码文件树。
图7:编译流程
3.1.4 解析示例
在图5中,我们建立了一个数学表达式的解析树。让我们试着定义一个简单的数学语言和解析过程。
词汇:我们的语言可以包括整数,加号和减号。
语法:
1、语言语法构造块是表达式、 条件和操作。
2、我们的语言可以包含任意数量的表达式。
3、表达式定义为一个"术语"跟着"操作"跟着另一个术语
4、操作是加号或减号
5、术语是一个整数标记或表达式
让我们来分析 2+3-1这个输入。
与 规则相匹配的第一个子字符串是 2,根据规则 #5 是一个术语。第二种匹配是 2 + 3 ,这个匹配是第三个规则-----一个术语后跟着一个操作再跟着另一个术语。下一个匹配,将只会在输入结束时命中。2+3-1是一个表达式,因为我们已经 知道 2+3 是一个术语,所以我们必须术语后跟着操作再跟着另一个术语。2++ 不会与任何规则相匹配,因此是无效的输入。
3.1.5 词汇和语法的正式定义
词汇是通常由正则表达式表示。例如,我们的语言经常会做如下的定义:
INTEGER :0|[1-9][0-9]*PLUS : +MINUS: -
如你所见,整数已经定义为一个正则表达式。
语法通常被称为 格式定义。我们的语言将定义如下:
expression := term operation termoperation := PLUS | MINUSterm := INTEGER | expression
我们说一种语言如果是一个上下文无关语法,则可以通过有规律的分析器解析其语法。上下文无关文法的直观的定义是可以完全在BNF 表示法表示的语法。正式的定义请参阅。
3.1.6 解析器的类型
有两种基本类型的解析器-自上而下解析器和自下而上的解析器。自上而下解析器的一个直观的解释是,看到高层次结构的语法,并尝试匹配其中之一。自下而上解析器开始输入并逐渐将它转换为语法规则,从低级别规则开始,直到满足高层次规则。
让我们看看这两种类型的解析器将如何解析我们的示例:自上而下的解析器将开始从更高级别规则 — — 它将确定 2 + 3 作为表达式。它然后将标识 2 + 3-1 作为表达式 (确定表达式的过程演变匹配其他规则,但起点是最高级别规则)。
自下而上的解析器会扫描输入,然后将替换匹配输入规则,直到匹配规则,这将继续下去,直到输入的结束,部分匹配的表达式放置在解析堆栈上。
Stack | Input |
---|---|
2 + 3 - 1 | |
term | + 3 - 1 |
term operation | 3 - 1 |
expression | - 1 |
expression operation | 1 |
expression |
这种自下而上的解析器的称为转移减少分析器,,因为其向右移动的输入 (想象一下一个指针,指向首先输入开始和向右移动) 和语法规则逐渐减少。
3.1.7 自动生成解析器
有 些可以为您生成的解析器的工具,他们被称为解析生成器。你给它们您的语言的语法 — — 它的词汇和语法规则 — — 他们生成工作解析器。创建一个解析器需要深入了解的解析和其不容易用手创建一个优化的解析器,因此解析生成器可能非常有用。Webkit 使用两个众所周知的解析生成器-Flex 创建分析器 和Bison创建一个词法分析器(您可能会遇到他们的名字 Lex 和 Yacc)。Flex 的输入是一个包含正则表达式定义的标记的文件.Bison的输入是 BNF 格式的语言语法规则。