本文说明如何从源程序到一个tree节点的产生过程。
以"Hello,world!\n"字符串为例。
c-parse.tab.c文件中的yylex()函数是gcc编译器的词法分析部分。
这里的一段代码:
else
{
*p = 0;
yylval.ttype = build_string (p - token_buffer, token_buffer + 1);
TREE_TYPE (yylval.ttype) = char_array_type_node;
}
里面的build_string ()函数【tree.c文件中】会调用make_node ( )函数产生一个字符串常量tree节点。
当然只是分配空间和标识code为STRING_CST。
后面的 TREE_STRING_LENGTH (s) = len;
会设置节点的长度。
TREE_STRING_POINTER (s) = obstack_copy0 (saveable_obstack, str, len);
这一句会设置好字符串的指针。
/* Return a newly constructed STRING_CST node whose value is
the LEN characters at STR.
The TREE_TYPE is not initialized. */
tree
build_string (len, str)
int len;
char *str;
{
register tree s = make_node (STRING_CST);
TREE_STRING_LENGTH (s) = len;
TREE_STRING_POINTER (s) = obstack_copy0 (saveable_obstack, str, len);
return s;
}
<string_cst 84014 literal "(null)"
<string_cst 84014 literal "Hello, world!
"
红色的是 make_node (STRING_CST);之后的样子,
而紫色的是
TREE_STRING_LENGTH (s) = len;
TREE_STRING_POINTER (s) = obstack_copy0 (saveable_obstack, str, len);
之后的样子。
STRING -> string
string -> primary
primary:
| string
{ $$ = combine_strings ($1); }
string:
STRING
| string STRING
{ $$ = chainon ($1, $2); }
根据上面的语法来看,规约到primary的时候会执行combine_strings ()函数。
combine_strings ()函数内部开始处加debug_tree ()函数变成了这个样子
<string_cst 84014
type <array_type 88a90
type <integer_type 825bc char permanent QI
size <integer_cst 82638 literal permanent 1
align 8 size_unit 8 sep_unit 8 symtab 0
sep <integer_cst 82608 literal permanent -128 precision 8 min <integer_cst 82608 -128>
max <integer_cst 82620 literal permanent 127
pointer_to_this <pointer_type 88a44> chain <integer_type 826a8* long int>
permanent BLK
size <integer_cst 88ae8 literal permanent 256
align 8 size_unit 8 sep_unit 8 symtab 0 sep <integer_cst 82638 1>
domain <integer_type 88480 unsigned char permanent unsigned QI size <integer_cst 82638 1>
align 8 size_unit 8 sep_unit 8 symtab 0
sep <integer_cst 884cc literal permanent 0 precision 8 min <integer_cst 884cc 0>
max <integer_cst 884e4 literal permanent 255
chain <real_type 88624* float>
chain <pointer_type 88b4c>
literal "Hello, world!
"
combine_strings ()函数内部结束处加debug_tree ()函数变成了这个样子
<string_cst 84014
type <array_type 94ef4
type <integer_type 825bc char permanent QI
size <integer_cst 82638 literal permanent 1
align 8 size_unit 8 sep_unit 8 symtab 0
sep <integer_cst 82608 literal permanent -128 precision 8 min <integer_cst 82608 -128>
max <integer_cst 82620 literal permanent 127
pointer_to_this <pointer_type 88a44> chain <integer_type 826a8* long int>
BLK
size <integer_cst 94f40 literal 15
align 8 size_unit 8 sep_unit 8 symtab 0 sep <integer_cst 82638 1>
domain <integer_type 94ea8 SI
size <integer_cst 8254c literal permanent 4
align 32 size_unit 8 sep_unit 32 symtab 0
sep <integer_cst 84048 literal 0 precision 32 min <integer_cst 84048 0>
max <integer_cst 84078 literal 14
static literal "Hello, world!
"