python语法分析器(parser)源码阅读(三)

本文探讨了C语言中parsetok.c和tokenizer.c文件中出现的tok_state和parser_state结构体。tok_state主要在PyTokenizer_Get函数中用于保存输入字符串信息,而parser_state在PyParser_AddToken函数中用于进行token分析。二者通过char*str建立联系,但tok_state在使用时需加struct前缀避免报错。解析过程中,tok_state的token信息传递给parser_state构建语法分析树。

关于结构体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_stateparser_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的变化
第一次循环1
第二次循环+
第三次循环1

然后a的值赋值给str后 ,str又作为变量传给了PyParser_AddToken,然后parser_state又构建了起来。

但是看一下parsetok的返回值,它返回的是一个node指针,也就是说,parser_state作为一个整体并没有全部被返回出来,而是仅返回了它其中的一个成员变量node*,源码上的注释说它是语法分析树的顶指针,实际上就应该是parser.c中要做的事情了

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值