python语法分析图_Python的抽象语法树(二)

时间:2024-11-18 07:58:41

Python的抽象语法树(二)

在之前的Python 的抽象语法树(一),我们阐述了一个字符串表达式是如何按照Python的文法定义生成对应的抽象语法书的。

今天我们就借助一个简单的小例子,来感受下Python生成抽象语法书的具体过程:

k = 5

print k

这个例子的词法分析过程在之前的文章已经分析过,读者可自行查阅。

从Token到CST

Python的语法解析相关代码依然是在parsetok,整个程序的逻辑大致如下:

一个循环,不断解析输入的字符串

从字符串中解析初对应的Token

每解析出一个Token,就通过PyParse_AddToken进入CST的创建过程。

这里有两点是需要特别注意的: 在Python中词法分析并不是全部做完再进入词法分析环节。

词法分析默认衔接的是CST

那什么是CST呢?就是与抽象语法书对应的具体语法树。为什么要有这两者之分呢?

读者朋友可以回忆下在上一篇语法分析我曾经画的两幅图:

在具体语法树中, 树的内部节点表示非终结符, 叶子节点全部为终结符, 这些终结符构成了可以对应的产生式推导出来的输入串,就是我们之前看到的Grammer文件。

抽象语法树AST是一种数据结构, 在表达式的AST中, 每个节点代表一个操作符, 而内部节点的子节点代表该操作符的操作数.

对比AST和CST可知, AST省略了很多出现在CST中的辅助符号, 这使得AST显得更简洁, 在编译器实现语法分析时, 处理AST显得更高效。

CST的具体定义

CST的解析其实本质上和我们之前分析的语法书构建没有本质区别,表征树节点的结构叫做node,定义如下:

typedef struct _node {

short n_type;

char *n_str;

int n_lineno;

int n_col_offset;

int n_nchildren;

struct _node *n_child;

} node;

n_type,节点种类

n_str,节点如果是字符串之类的,保留的字符串内容

n_lineno,所在行号

n_col_offset,所在列

n_nchildren,子节点个数

n_child,子节点数组

其实从这个数据结构中,我们就能看出,根节点node已经自发形成了一棵树的结构,如果对此有怀疑的话,我们可以参考PyNode_ListTree,自行解析CST的数据结构:

static void

list1node(FILE *fp, node *n)

{

if (n == 0)

return;

if (ISNONTERMINAL(TYPE(n))) {

int i;

for (i = 0; i < NCH(n); i++)

list1node(fp, CHILD(n, i));

}

else if (ISTERMINAL(TYPE(n))) {

switch (TYPE(n)) {

case INDENT:

++level;

break;

相关文章