构建自己的编译器(四)递归下降

按理说,今天开始讲词法分析,但是奈何我已经学完了,今天学学递归下降。
传统上,编写语法分析器有两种方法,一种是自顶向下,一种是自底自上。自顶向下是从起始非终结符开始,不断地对非终结符进行分解,直到匹配输入的终结符;自底向上是不断地将终结符进行合并,直到合并成起始的非终结符。它们的目的都是判断这条语句是否合法,不合法的不能递归完毕的。自顶向下方法就是我们所说的递归下降。我们能直接根据BNF写出解析代码。

四则运算的解释器是递归向下实现的,并且真的是能算出其结果的,并没有用到虚拟机。递归直接算出得数了。

而实现变量定义呢,那么必须用到虚拟机了。如果仅仅是一个全局定义时,就这么做就行,但是,我们怎么区分各个EBNF呢?这个以后再说。

match应该是将id与对应的意义联系起来。

对于C语言来说,区分各种定义就是直接接受直接判断,例如如果有enmu就直接走枚举,如果是int就向前看一个有没有括号,区分变量定义或者函数定义。就这样继续向下区分。

然后就会到了专门处理的实体函数。而实体函数,就是切割储存信息而已。这个信息就是类似语法树之类的吧?

match 函数是一个辅助函数:

void match(int tk) {

    if (token == tk) {

        next();

    } else {

        printf("%d: expected token: %d\n", line, tk);

        exit(-1);

    }

}

它将 next 函数包装起来,如果不是预期的标记则报错并退出。

栈是干什么用的?函数参数,局部变量,都是放在栈里的,全局变量放在数据段里面。match一般就是消耗终结符用的,变量定义,一旦我们解析出来,我们就把这个变量压入栈,为其分配内存,就是这样。存在栈中的唯一目的就是为了掩盖全局变量。我不用赋值代码根据语义直接就能解释的。

也就是说,我现在就可以进行,emm,做了。














 

发布了147 篇原创文章 · 获赞 11 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/HeroIsUseless/article/details/104277987