Ruby作为一门动态语言,它在你及纳入irb或者是运行ruby example.rb的时候是如何,读懂并执行Ruby代码的呢,我们本文就是来说说这一部分的内容。
我们来看一下Ruby执行代码的流程,首先Ruby会逐行的读取文件中的代码,接着在将这些代码进行分词(tokenize),将它们转换成词条(token),其次Ruby会对词条进行语法分析(parse),分析之后,就会生成Ruby能够读懂的AST结构,最后再通过编译,转换成Ruby虚拟机的指令,这样代码就可以在Ruby虚拟机上运行了。
Ruby 处理代码的工序分词
Ruby在分词的时候,是通过对代码文本进行,逐个字符的处理,然后将他们按照规则继续分词匹配,例如我们有下面这个程序:
10.times do |n|
puts n
end
这个程序在被Ruby执行的时候,它的第一行文本会被转换成如下的词条
第一行文本 Ruby 完成了第一行文本的分词我们可以看到,上面的分词结果,Ruby分词器将 10这个字符转换成立 tINTEGER ,然后又识别times为一个标识符,紧接着识别了do为Ruby的关键字。就这样Ruby一行一行的使用它的规则将字符转化成词条,需要注意到是,在分词过程中,分词程序是不会检查代码文件是否含有语法错误。
在Ruby的分词程序中所以的分词过程都是在一个名为parser_yylex函数中完成的,这个函数中包含着一个超长的switch语句,用于分支判断当前读取的字符符合哪些规则,有意思的是如果遇到了空格字符,它们使用goto 语言调整回switch语句开始的地方。
语法解析
经历过了上一步骤的流程,我们的Ruby处理程序终于到了,可以识别语法错误的阶段了,在语法解析的这个步骤上,实际上Ruby是使用了解析器生成器,它根据Ruby定义的解析规则,生成解析器代码,然后再由这个解析器去解析Ruby词条。Ruby的解析规则文件是(parse.y) 使用的解析器生成器是 Bison 生成器,它可以根据给定的语法规则生成解析器,下面就是Ruby使用Bison的过程:
Ruby 构建过程会提前运行 Bison可以看到Ruby是在程序构建的过程中,使用Bison生成解析代码的,然后我们上面讲到的分词函数parser_yylex就是在这时被一起创建的,所以我们看到图中的两个箭头,指的就是分词和解析是同时进行的。
解析器代码是通过LALR算法根据parse.y文件的规则去匹配对应的词条。然后再做完语法规则检查后,它会生成AST(抽象语法树)。
10.times do |n|
puts n
end
还是上面这段代码,在被解析器成立后它会转化成下面的AST
AST可以从AST看出来,程序最开始生成的词条,在AST中被表示成为一个节点,并且这些节点中包含在程序如何被解析的元数据和规则,分词过程只是让Ruby知道了程序中写了上面,解析过程之后的AST才会告诉Ruby的这段程序的真正含义。
网友评论