##前言
此篇为翻译内容,原篇地址:在这里。
##解析——介绍
因为解析是渲染引擎中非常重要的一个过程,我们将进一步深入地了解它。 我们先来看一下关于解析的一点介绍。
解析文档意味着将其转换为有意义的结构 —— 代码可以理解和使用。解析的结果通常是表示文档结构的节点树,它被称为解析树或语法树。
例如——解析一个表达式“2+3-1”,就会返回下面这个树:
语法
解析是基于文档遵循的语法规则 —— 其中使用的语言或格式进行的。你可以解析的每种格式都必须具有由词汇和语法规则组成的确定性语法。它被称为上下文无关语法。人类语言不是这样的语言,因此不能用传统的解析技术进行解析。
##解析——词法分析器组合
解析可以分为两个子过程 -——词法分析和语法分析。
词汇分析是将输入打破令牌(tokens)的过程。令牌(token)是语言词汇 -——有效构建块的集合。在人类语言中,它将包含出现在该语言字典中的所有单词。
语法分析是语言语法规则的应用。
解析器通常将工作分给两个组件——词法分析器(有时也叫标记生成器),负责将输入分成有效的令牌,而解析器则负责根据语言语法规则分析文档结构来构建解析树。词法分析器知道如何去除不相关的字符,如空格和换行符。
从源文档到解析树的过程:
解析过程是迭代的,解析器通常会询问词法分析器新令牌,并尝试将令牌与语法规则之一相匹配。
如果规则匹配,则与令牌相对应的节点将被添加到解析树中,并且解析器将要求另一个令牌。
如果没有规则匹配,解析器将在内部存储令牌,并继续请求令牌,直到找到与所有内部存储的令牌匹配的规则。
如果没有找到规则,则解析器将引发异常。 这意味着文档是无效的并包含语法错误。
##编译
很多时候,解析树不是最终产品。解析通常用于翻译 -——将输入文档转换为另一种格式。这个例子就是编译。编译器就是将源代码编译成机器码。这个过程的第一步就是将源代码解析成解析树,然后再把解析树转换成机器代码文档。
下面是编译流程:
##解析示例
在前面,我们为一个数学表达式创建了一个解析树,下面,让我们尝试定义一个简单的数学语言来了解一下解析过程。
词汇:我们的语言可以包括整数,加号和减号。
语法:
- 语言语法构建块是表达式,术语和操作。
- 我们的语言可以包含任意数量的表达式。
- 表达式定义为“术语”,后跟“操作”,后跟另一术语。
- 操作是加号或减号。
- 术语是整数标记或表达式。
让我们来分析一下输入的“2+3-1”。
与规则匹配的第一个子字符串是“2”,根据规则5,它是一个“术语”,与规则第二个匹配的是“2+3”——符合规则3,一个“术语”后跟“操作”,后跟另一个“术语”。下一个匹配是在输入结束之后。“2+3-1”是一个表达式,因为我们已经知道了“2+3”是一个“术语”,而“术语”后跟一个“操作”,再跟一个“术语”是符合规则的。而“2++”将不会匹配任何一条规则,因此是无效的输入。
##词汇和语法的正式定义
词汇通常由正则表达式表达。
例如,我们的语言可以被定义为:
INTEGER :0|[1-9][0-9]*
PLUS : +
MINUS: -
语法通常以称为BNF的格式定义。我们的语言将被定义为:
expression := term operation term
operation := PLUS | MINUS
term := INTEGER | expression
我们说一种语言可以由常规解析器解析,如果其语法是上下文无关语法。上下文无关语法的直观定义是可以在BNF中完全表达的语法。正式定义请参见:这里。
##解析器的类型
有两种基本的解析器——自顶向下的解析器和自下而上的解析器。直观的解释是,自顶向下的解析器会看到语法的高级结构,并尝试匹配其中的一个。底层解析器从输入开始,并逐渐将其转换为语法规则,从低级别规则开始,直到满足高级规则。
让我们看看两种类型的解析器将如何解析我们的例子:
自上而下的解析器将从较高级别的规则开始——它会“2+3”定义成一个表达式。把“2+3-1”定义为另一个表达式(识别表达式的过程演变与其他规则匹配,但起点是最高级规则)。
自下而上的解析器将扫描输入,直到匹配规则,然后将匹配的输入与规则替换。这个过程将会继续,直到输入结束。被匹配的表达式将会被放到解析栈里。
stack | input |
---|---|
2+3-1 | |
term | +3-1 |
trem operation | 3-1 |
expression | -1 |
expression operation | 1 |
expression |
这种类型的自下而上的解析器被称为移位减少解析器,因为输入向右移动(想象一个指针首先指向输入开始并向右移动),并逐渐减少语法规则。
##自动生成解析器
这里有可以为您生成解析器的工具,它们被称为解析器生成器(generator)。你可以把你的语言的语法——词汇和语法规则,输送给它们,它们会自动生成一个解析器。创建一个解析器需要对解析有深刻理解,并且也不容易用手创建一个优化的解析器。所以解析器生成器非常有用。
Webkit使用两个很有名的解析器生成器——用于创建词法解析器的Flex和用于创建解析器的Bison。Flex输入是包含令牌的正则表达式定义的文件,Bison的输入是BNF格式的语言语法规则。
关于解析器的介绍就到这里了,下一篇文章将会像大家介绍解析HTML的过程。