.\icu

Blog of @megakite.


January 1, 0001

因为SysY里的const完全是编译期计算的(实际上是constexpr),所以可以在语义分析阶段就把常量全算完存进符号表,后面IR生成就不用管常量语句了;同理,语义分析阶段也不应该为变量赋实值。

setjmp()longjmp()整了一套异常系统,好玩。

语法分析阶段,我的设计是把三个list直接给flatten掉。理论上没什么问题,但是要注意一点:LR分析器的基本规则是后序遍历,所以不需要、也不能按照如下的前序遍历(LL)思路设置不动点:

ConstDefList
	: ConstDef {
		/* ... */
		this_ConstDefList = NULL;
	}
	| ConstDef COMMA ConstDefList {
		if (!this_ConstDefList)
			this_ConstDefList = /* ... */;
		/* ... */
	}
	;

其实完全没这么复杂,只需要在ConstDef处创建结点,然后在每次规约的时候往里面加child就可以了。 从这里也可以看出来,虽然对树的前序、后序遍历都需要下推自动机,但后序的表达能力是比先序要强一点,主要是后序的平均栈深度要大不少,context也更明确。

实际上,codegen的过程,就是把递归的数据结构扁平(迭代)化的过程,而这个过程我们刚才其实已经做过了,借助的是this_ConstDefList这一全局变量。

07_var_main.c里头竟然写了个这个东西……

int main() {
  int main = 10;
  return main;
}

留到Lv5再做算了,这很明显是跟符号定义和作用域有关的。

代码生成时仅仅为alloc指令分配了栈空间,而其余部分的表达式计算、常量计算等全部都是用寄存器完成。感觉这样如果不call的话还算合理,但是一旦要call,需要保存的寄存器数量应该不少。

prologue和epilogue写得有点混乱了,之后得看看怎么重构。