关于结构体tok_state以及结构体parser_state
这两个结构体主要出现在parsetok.c以及tokenizer.c文件中,对于这两个结构体,它们之间的关系应该是承上启下的关系即先生成tok_state然后再生成相应的parser_state.
下图是通过sizeof取得的两个结构体的大小。
可以看出,这两个结构体都比较大,再加上结构体内指针指向的地址空间,结构体包含的实际信息量要更大。其中结构体内部的具体信息在源码里都有详细描述,这里不再写。
先看一下tok_state,通过我的观察,这个主要用在PyTokenizer_Get(struct tok_state *tok, char **p_start, char **p_end)这个函数上,位于tokenizer.c文件中第1838行,通过这个函数,主要用于获取输入的字符串。然后信息通过tok_state保存下来。
这里出现了一个我一直想不通的问题,为啥tok_state使用时必须在前面加一个struct,不加就会报错。
再看一下parser_state,它集中出现在parser.c文件中,这个文件中主要的一个函数是PyParser_AddToken,通过这个函数来进行token的分析。
注意这个for循环,我思考了很久才发现,tok_state与parser_state似乎并没有特别的交集,但是,它们之间其实是通过一个char* str来产生联系的。
type = PyTokenizer_Get(tok, &a, &b);
//。。。。。。。省略一部分代码
len = (a != NULL && b != NULL) ? b - a : 0;
str = (char *) PyObject_MALLOC(len + 1);
if (str == NULL) {
err_ret->error = E_NOMEM;
break;
}
if (len > 0)
strncpy(str, a, len);
str[len] = '\0';
?变量a代表的正是tok_state的前面的那个token,比如输入1+1的话,那么在一个循环中,会是这样的。
然后a的值赋值给str后 ,str又作为变量传给了PyParser_AddToken,然后parser_state又构建了起来。
但是看一下parsetok的返回值,它返回的是一个node指针,也就是说,parser_state作为一个整体并没有全部被返回出来,而是仅返回了它其中的一个成员变量node*,源码上的注释说它是语法分析树的顶指针,实际上就应该是parser.c中要做的事情了
|