【自研Fe编译器】三、(变量声明+栈分配)基于Flex + Yacc开发的高级语言编译器 您所在的位置:网站首页 变量c语言过程代码 【自研Fe编译器】三、(变量声明+栈分配)基于Flex + Yacc开发的高级语言编译器

【自研Fe编译器】三、(变量声明+栈分配)基于Flex + Yacc开发的高级语言编译器

2023-06-25 15:27| 来源: 网络整理| 查看: 265

项目链接:https://github.com/FeliGame/FeCompiler 本项目中的文法和AST数据结构设计参考了北京大学编译器实践项目pku-minic.github.io/online-doc/ 本博客会同步更新开发进度,欢迎各位交流、批评! 简介

Fe语言是一种语法类似C的高级语言,由于笔者将重点放在编译器的语义分析和代码优化上,因此目前阶段语法和C不会有什么不同。 该编译器会生成Koopa IR,并基于Koopa IR生成目标汇编代码(RISC-V)。

目前进度

可以实现变量的声明、定义、运算,并且通过栈统一维护用户定义变量(@开头)、参数、中间代码的临时变量(%开头)、返回值等。 运行PKU-Compiler自带的autotest脚本,Lv4的Koopa IR全部通过,RISC-V为13/14(complex-var用例出现了一个WRONG ANSWER),笔者正在排查故障中……

解决问题 为函数开辟栈空间时,需要事先知道指令中变量的个数。我采用了在分析IR前,预先扫描KoopaIR文本中的变量名种数,使用去重集合std::set维护,从而得到变量名个数,乘以4即为要开辟的栈空间。开辟栈的指令很简单:addi sp, sp, -(要开辟的栈空间字节数);相应地,在函数调用结束的ret指令前,要恢复栈顶地址(出栈):addi sp, sp, (要开辟的栈空间字节数)。 void scanStackSize(string ir) { stringstream ss(ir); string word; set identifiers; // 存储所有变量(不重复) // 按空格切分ir while (ss >> word) { if (word[0] == '@' || word[0] == '%') { // 去掉末尾的逗号 if (word.back() == ',') { word = word.substr(0, word.size() - 1); } identifiers.insert(word); } } cerr


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有