@Vany
2015-06-23T01:52:14.000000Z
字数 2303
阅读 1088
data segment
声明数据用
全局变量存在这里(在PROGRAM的VAR中的)
常数(const)也可以存在这里
需要了解如何定义数据
code segment
代码,一条条指令
需要了解那些指令
stack segment
栈,用于动态分配内存,即所有的函数内声明的变量应该都是在这里动态的使用
需要了解如何在Code Seg中操纵栈(push,pop bp)
需要了解如何定义栈(大小等)
除此之外
我们的基本思路就是遍历整个语法树,然后递归生成每个segment的字符串。
以下几种表用于在code generation过程中储存信息,
常量表,类型表,变量表,label表,函数表(用于存储函数名和入口地址,用么?还是直接用一个统一的标签,到时候直接call好了)
每个表有单独的结构体储存以及处理相应信息,例如添加新符号,拿到该符号对应的地址
由于routine的嵌套,这个表是根据作用域不同是在变的。那么每个作用域定义一个存储这些表的结构体(就是类似于你那个symtab_function_blocks),除此之外,还要包括指向它父作用域的指针(在处理的过程中把这些指针连起来)。
每个表提供接口,例如变量表,提供询问该id的地址为多少,应该能够计算出来,返回给它。为了能够计算地址,这个结构体应该储存作用域对应的栈空间开始的指针地址(真的要么?),然后根据这个进行偏移计算。
再如label表,直接返回label对应的地址。
这里面关键要解决的一个问题是,表是从当前作用域开始寻找,如果找到就立即返回,如果没找到向父作用于一层层的找。这样可以实现子作用域新声明的同名变量覆盖(使隐藏)父作用域的变量(或符号等……)。
类型无外乎以下几种:
我们应该实现多个表达这几种基本类型的结构体,然后其他的用到类型的地方存的都是这些,例如在类型表中储存的就是(id,指向这些类型的结构体的指针)这个pair;别的地方用到该类型时,直接指向该表示该类型结构体的指针。
对于系统类型,没有什么要说的,标识好就行
对于数组,标识好类型、大小
对于结构体,用一个vector存里面的信息,名字,大小
对于枚举类型,我想可以用一个map,将枚举类型转化为0~n-1
另外,除了可以type a = (mon, tue, sun)这样定义外,
还有一个是type a = tue..sun(枚举子界类型),
在处理这个时我想可以设置一个数字的上下界,例如定义时上下界是0~n-1,在这里就是1~n-1
其实应该还有挺多东西,例如枚举类型的赋值、运算、求前后继,类型检查,数组的偏移量计算,结构体的偏移量计算等等,不知应不应该这里留一些接口?
常量储存在data segment中(这个需要讨论下,如果是简单的数字就直接写在codeseg里好了),我们需要维护一张常量表。
如果存在data segment其结构包括<名字,{地址,类型}>;这个地方还需要讨论一下,或者常量表里面直接储存类型和值就好了,用到时直接拿出来。
对于label其实在实际处理时很简单,因为就是goto用得到,而汇编里直接Jmp就可以了吧
但这里有个问题是,子作用域中的label和父作用域中的label如果重名,应该以子的优先,因此我们需要一个label表,用来查询当前该label对应的别名。
比如在pascal的程序中有label 8888,调用goto 8888应该就可以实现功能。但是我们在实现中可以将8888前加上该作用域的名字,构成别名,然后放到汇编里,这样的话我们还是可以遇到goto就生成jmp,只是名字不同了;当遇到label时,自动将其转换成别名。
因此,这里面我们还是实现label的那个part吧,对于我们实现来说更方便一些,明天我改改。
变量表中储存:(变量名, 类型,返回地址?)
变量其实难点在于如何计算地址(相对地址),这个要根据函数的调用的处理进行计算。
函数调用涉及栈的操作,利用Push pop什么的维护栈
堆栈结构可以详见我室友的那个ppt里面,然后根据结构我们编写相应的代码
e.g. 调用时:
push bp什么的指针,,,
push 变量
声明标签,call xxx
push 实参
太困了,不细化了……
函数代码生成就直接在当前的code segment后生成就好,但是如果遇到了函数里面还定义了一个函数的情况,我们想可以将子函数的代码放在父函数最后一条语句后面。
表达式计算就直接按照语法树计算生成代码即可(每次运算前要做类型检查),如果遇到较长复杂表达式,我们不能用那么多寄存器,
这个需要仔细考虑下,可以在data segment里面开辟一段专门用作计算的数据区,把数据暂时存在那里
其他循环、条件分支等语句就正常按照语义来就好了
不同变量类型的内存的分配要规定清楚,以便于计算偏移量
我感觉这部分最好也让类型的那个struct来做
这个有空再讨论吧,据说可以把c语言的库的代码拿过来
不过最好先实现read\write功能
感觉很多地方没有说细,不懂得在讨论吧,面谈比较方便,打字不知哪里是重点