日记大全

日记大全 > 句子大全

怎么用C语言写语法分析2(补充几个数据结构)

句子大全 2023-11-05 03:50:01
相关推荐

接上篇怎么用C语言写语法分析,继续介绍剩下的几个数据结构。

语法分析涉及的数据结构,如下图,就这么几个。前一篇类型type、变量var、节点node、运算符operator、作用域scope,接着说下标号label、块block、函数function。

标号,label,在其他语言里用的不多,主要是在C和C++中用于goto语句。

goto语句的目的地址是个标号,可以往前跳,也可以往后跳,特别的灵活。

一般情况下,除了错误处理代码之外,不建议使用goto。

如上图,标号的数据结构还是很简单的。

与变量类似,它也是位于某个作用域内(函数或者语句块)。当在goto语句中使用标号时,为它生成一个node节点。

type类型自然是标号。

scf_lex_word_t* w表示它的单词,单词里存有标号的名字字符串。

scf_node_t* node,为它标记的目的代码的第一个节点。

例如,

if (!p1) goto error1;

if (!p2) goto error2;

error2:

free(p1);

error1:

return -1;

error1中的node就指向return -1语句,error2中的node指向free语句。

块,它是需要直接挂在语法树上的,有scf_node_t类型的节点node。

它下属的语句,都添加在node成员的子节点数组里。

它下属的变量或函数,都添加在它的scope作用域里。

字符串name用于记录它的名字,w_start和w_end记录起始和结束的大括号。

int a; // 1

if (1) {

int a; // 2

for (;;) {

int a; // 3

}

以上代码里的3个a,分别处于3个块里。

使用的时候,首先查找当前块的作用域,然后查找上一级块,一级级的往上查找。所以for循环里使用的a,是注释为3的a,而不是注释为2的a。

如果在同一个块里声明2个a,就出现了数据的重复定义,这是常见的语法错误。在分析变量的定义时,可以查找当前作用域里是否有同名变量,有则报语法错误。

函数的定义还是比较复杂点的,见上图。

它也是需要添加到语法树的,所以也有个scf_node_t node成员。

函数里的语句,也存在node的子节点列表里。

函数里的变量(局部变量),存在它的scope成员里。

它的前几项与块一样,函数也是一个复杂的块。

函数也可以是类的成员函数,它被挂在类类型的scope成员上,所以16行有个链表元素list。非成员函数,则挂在文件块或者全局块的scope上。

18行和20行,分别是返回值ret和形参列表argv。

返回值之所以用变量而不是类型,是因为类型只存储基本类型或类类型,而指针类型需要记录指针的级数,这个值是记录在变量里的。

argv列表,每一个都是scf_variable_t变量的指针,表示该参数的细节。

如果是运算符重载,op_type成员表示原来的运算符类型。

24行以后的内容,都是和中间代码生成、机器码生成有关的内容,不属于语法分析部分。

想了解更多精彩内容,快来关注闲聊代码

阅读剩余内容
网友评论
相关内容
拓展阅读
最近更新