编写while循环语句的三步骤(我写的while循环的语法分析)

上篇技术文章说了下我自己给scf编译器写的语法分析框架,在这个基础上给它添加个模块去做while循环的语法分析是很容易的。

以C语言为例,while循环是这样的:

while (条件表达式) {

循环体的代码;

}

循环体是一个顺序代码块,可以是单行或多行代码,其中单行时可以省略大括号{}。

编写while循环语句的三步骤(我写的while循环的语法分析)(1)

while模块的初始化函数

while模块的语法节点只需要5个:while关键字、左小括号lp、右小括号rp、结束end、以及统计左小括号个数的节点lp_stat。

while循环里是可以嵌套下一级while循环的,所以它的模块上下文是一个,用于做while的递归分析。

模块上下文栈s的存放位置,是根据while模块的索引确定的,如上图:

d->module_datas[dfa_module_while.index] = s;

dfa_module_while就是while模块的结构体。

编写while循环语句的三步骤(我写的while循环的语法分析)(2)

while模块的结构体

模块的fini函数是很简单的,释放在初始化时申请的栈就行。

在没有错误的情况下,这个栈在fini时肯定是空栈

编写while循环语句的三步骤(我写的while循环的语法分析)(3)

编辑语法

条件表达式和循环体的具体处理,分别在表达式模块顺序模块进行。

while模块里只需要引用这两个模块的入口节点(dfa语法节点),对应的指针变量分别为expr和block。

具体的语法编辑也非常简单,while循环的源代码写法是 while ( 条件表达式 ) 循环体,按照这个顺序把dfa节点连接起来就行:while -> lp -> expr -> rp -> block。

前面的是父节点,后面的是子节点。

这么一条语法规则,就可以分析while循环的源代码了。

接下来就是实现几个action()函数,以把对应的元素添加到抽象语法树(ast)

编写while循环语句的三步骤(我写的while循环的语法分析)(4)

每个while循环对应一个dfa_while_data_t的上下文

每个while循环对应1个dfa_while_data_t的上下文,嵌套的while循环一层层地存放在模块的上下文栈里。

编写while循环语句的三步骤(我写的while循环的语法分析)(5)

while关键字的action()函数

while关键字的action()函数,代码如上图:

1,申请一个while的ast节点,然后把它添加到抽象语法树ast

2,然后保存一些信息到while的上下文,然后它压入while模块的上下文栈

3,最后,给语法分析框架(dfa)返回NEXT_WORD,通知框架继续分析下一个词。

接下来被分析的下一个词就是左边的小括号,它是条件表达式的开始。

编写while循环语句的三步骤(我写的while循环的语法分析)(6)

左小括号的2个action函数

左小括号的处理函数很简单:

_while_action_lp()函数用于处理while循环的第1个左小括号,它表示条件表达式的开始。

_while_action_lp_stat()函数用于处理其他嵌套的左小括号,只统计个数用于左右小括号的匹配检测,具体的处理在表达式模块里进行。它需要添加到hook上触发。

当遇到右小括号的时候,需要检测条件表达式的分析是否完成,所以也加了1个hook。

这2个hook的添加顺序不能颠倒,因为hook单链表是一个栈(先添加的后处理),所以要按照左右小括号在代码里的出现顺序添加(后出现的先添加)。

while () 敲代码时先打左小括号,然后打右小括号,添加hook的顺序正好相反。

编写while循环语句的三步骤(我写的while循环的语法分析)(7)

右小括号的action 函数

右小括号的action函数,既统计个数又检查小括号的左右匹配

如果匹配说明条件表达式分析完了,接下来分析循环体的代码。

如果不匹配,继续分析条件表达式。

循环体的分析结束说明整个while循环的分析完成,所以这里添加了一个end hook

编写while循环语句的三步骤(我写的while循环的语法分析)(8)

while语法分析的结束函数

当循环体的分析完成时,语法分析框架会通过hook触发这个函数。

它的内容也很简单,释放while上下文,并且把当前节点设置回while的父节点(它在while的分析开始时保存在while上下文里了,见_while_action_while()函数的说明)。

在while循环的代码分析完成时,如果它是嵌套在其他代码里的(例如if for while的主体部分),那么152行返回的SCF_DFA_OK将会导致多个end hook的级联触发,就跟递归调用的级联返回一样。

while循环的语法分析还是很简单的,这个模块只有200多行代码。

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页