前言
入口
rb_iseq_compile_with_option 函数是语法分析与中间代码生成的入口,这里仅列出和语法分析 & 中间代码生成相关的代码块
// iseq.c
rb_iseq_compile_with_option(VALUE src, VALUE file, VALUE absolute_path, VALUE line,
const struct rb_block *base_block, VALUE opt) {
...
// 声明一个函数指针 parse
NODE *(*parse)(VALUE parser, VALUE fame, VALUE file, int start);
// 语法分析树根节点
NODE *INITIALIZED node;
if (RB_TYPE_P(src, T_FILE)) {
parse = rb_parser_compile_file_path;
} else {
parse = rb_parser_compile_string_path;
}
// 创建语法分析器对象
const VALUE parser = rb_parser_new();
rb_parser_set_context(parser, base_block, FALSE);
// 调用 parse 函数指针指向的语法分析函数,返回 AST 根节点
node = (*parse)(parser, file, src, ln);
iseq = rb_iseq_new_with_opt(node, label, file, absolute_path, line, parent, type, &option);
return iseq;
}
语法分析
rb_parser_compile_file_path
rb_parser_compile_string_path
该函数用于解析一段包含 Ruby 源代码的字符串:
// ripper.c
NODE* rb_parser_compile_string_path(VALUE vparser, VALUE f, VALUE s, int line)
{
must_be_ascii_compatible(s);
return parser_compile_string(vparser, f, s, line);
}
简单起见,我们直接列出 parser_compile_string 的调用栈
parser_compile_string @ ripper.c
yycompile @ ripper.c
yycompile0 @ ripper.c
yycompile0 会调用 yyparse(实际上是 ruby_yyparse 的宏定义),进入 YACC 语法分析器自动生成的代码
中间代码生成
rb_iseq_new_with_opt
rb_iseq_new_with_opt 函数根据语法分析生成的 AST 生成中间代码并保存在 rb_iseq_t 结构体中,详细部分可以参考Ruby 2.x 源代码分析:语法分析 & 中间代码生成 之 数据结构
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。