首页 > 其他分享 >编译实践学习 Part8

编译实践学习 Part8

时间:2024-07-06 17:09:31浏览次数:22  
标签:decl return val int i32 实践 编译 func Part8

License: CC BY-NC-SA 4.0

lv 8.1

你可以把全局范围内所有的函数 (包括之后章节中会出现的全局变量) 都放在同一个作用域内, 即全局作用域.

于是我加入了 Koopa_val_global_func.

class Koopa_val_global_func : public Koopa_val_base {
private:
	FuncDefAST const * func;

public:
	bool is_void() const { return func->func_typ->is_void; }
	Koopa_val_global_func(FuncDefAST const * func) { this->func = func; }
	std::string get_str() const override { return "@" + func->ident; }
	Koopa_value_type val_type() const override { return KOOPA_VALUE_TYPE_GLOBAL_FUNCTION; }
};

某人把

FuncDefParam:
	BType IDENT {
		auto ast = new FuncDefParamsAST();
		ast->params.push_back({cast_ast<BTypeAST>($1), *$2});
		$$ = ast;
	}
	;

写成了

FuncDefParam:
	BType IDENT {
		auto ast = new FuncDefParamsAST();
		ast->params.push_back({cast_ast<BTypeAST>($1), *$2});
		$$ = $1;
	}
	;

然后 debug 了大半天,是谁我不说。

某人又把函数参数忘放进符号表了。


然后是生成汇编。

重写了原来的 Asm_val 类(原来只有堆栈值/立即值的分类,现在加了寄存器值,来获取参数)。

判断函数调用其他函数是否有其他参数时先 dfs 一次,错误方式:

int get_function_max_call_param(const koopa_raw_value_t &val) {
	if(val->ty->tag != KOOPA_RTT_FUNCTION) {
		return -1;
	}
	return val->ty->data.function.params.len;
}

正确方式:

int get_function_max_call_param(const koopa_raw_value_t &val) {
	if(val->kind.tag != KOOPA_RVT_CALL) {
		return -1;
	}
	return val->kind.data.call.args.len;
}

写完 lv 8.1 后突发奇想想写个递归。

int main(){ return main(); }

报错了,怎么会逝呢?

然后修好了。

lv 8.2

在生成 Koopa IR 时无脑加几行:

decl @getint(): i32
decl @getch(): i32
decl @getarray(*i32): i32
decl @putint(i32)
decl @putch(i32)
decl @putarray(i32, *i32)
decl @starttime()
decl @stoptime()

但这样还不够,

根据 SysY 的规定, SysY 库函数可以不加声明就直接使用, 所以你可能需要预先在全局符号表中添加和库函数相关的符号定义, 以防无法正确处理相关内容.

把之前 Koopa_val_global_func 改了改。顺利通过。

lv 8.3

遇到了 reduce/reduce conflict.

折腾过程

发现有人遇到过同样的问题,链接在这

问了 AI 但没得到什么有用的信息,参考了 github 上 BerkinChen/pku-compiler 但仍然报错。

翻阅 Bison 文档。发现可以让 Bison 生成示例。

然后 google 了一通并找到了 StackOverflow 的帖子

报错原理

考虑以下输出 int foo,编译器在读入 foo 时就要判断前面的 int 属于哪种规则。

它不知道完整的内容是 int foo; 还是 int foo(){},因此有多种规约 int 的方式,就出错了。

原来的语法规则是 FuncType IDENT '(' ')' // ...BType IDENT ';',Bison 读到 IDENT 时不知道之前的 INT 该给 FuncType 还是 BType

解决方案

FuncTypeBType 统一为一种类型就行了。

注意,你不能定义一个 void 类型的变量(这也是 FuncTypeBType 间最大的差异),因此在 cpp 部分要加特判。


生成完汇编开测,发现 WA 4/12.

进入函数时:

  • 上层符号表加入函数名

  • 新建一层符号表

  • 本层符号表加入函数参数

发现生成汇编时会在调用完 void 函数后试图获取返回值。本来想着再建个符号表,但实际上只要看 kind.data.call.callee->ty->data.function.ret->tag != KOOPA_RTT_UNIT

标签:decl,return,val,int,i32,实践,编译,func,Part8
From: https://www.cnblogs.com/x383494/p/18287474

相关文章

  • 从零开始实践大模型 - 配置环境
    本文地址:blog.lucien.ink/archives/549本文将介绍在面向深度学习时,推荐的环境配置以及一些使用Linux的习惯。本文的部分内容与Debian下CUDA生产环境配置笔记有所重叠,但也有些许的不一样,在正文中不额外注明。前言本文将主要分4部分:配置SSH登陆安装显卡驱动......
  • 从零开始实践大模型 - 安装系统
    本文地址:blog.lucien.ink/archives/548本章节将介绍在面向深度学习时,推荐安装的系统以及对应的安装选项。系统选择目前主流操作系统有Linux、macOS、Winodws,如果不考虑日常当作个人电脑来使用的话,强烈建议使用无图形化界面的Linux,因为图形化界面会占用一定的显存(虽然也有......
  • MinGW GCC 5.3.0 编译OpenCV4.5.5 运行到imshow时崩溃
    Windows 下通过mingw32-make编译opencv4.5.5,经过一系列问题解决后发现其他正常,imshow崩溃.GCC版本太低原因,换更高版本的GCC解决.毕竟GCC5.3.0是2015年发行的,opencv4.5.5是2020年发行的尝试换GCC i686-8.1.0-release-posix-sjlj-rt_v6-rev0编译,调用imshow时正常运行,并且......
  • MinGW GCC 编译Glog0.6.0
     GCC版本: gccversion5.3.0(i686-posix-dwarf-rev0,BuiltbyMinGW-W64project)glog0.6.0地址: https://github.com/google/glog/tree/v0.6.0 编译很顺利,直接 然后进入C:/tmp/glog-0.6.0/Build2目录,执行命令: 编译完成后,在目录下存在libglog.dll和libglog.dll.a......
  • MinGW GCC Windows下编译libmodbus
    最近项目从MSVC切换到GCC,libmodbus官网没提供MinGW下GCC如何编译,官网推荐在类UNIX环境下MSYS下编译,个人更偏向直接拿源文件编译。编译libmodbus版本:libmodbus-3.1.10GCC编译器版本: 5.3.0(i686-posix-dwarf-rev0,BuiltbyMinGW-W64project)CMake版本: 3.29.0在随笔最......
  • mac os 迁移后,编译链接foundation的qt 项目失败
    error:unknowntypename'CFAttributedStringRef';didyoumean'NSAttributedStringKey'?CFAttributedStringRefattrString)CT_AVAILABLE(macos(10.5),ios(3.2),watchos(2.0),tvos(9.0));^/Library/Developer/CommandLineTools/SDKs/MacOSX1......
  • LLM4Decompile——专门用于反编译的大规模语言模型
    概述论文地址:https://arxiv.org/abs/2403.05286反编译是一种将已编译的机器语言或字节码转换回原始高级编程语言的技术。该技术用于分析软件的内部工作原理,尤其是在没有源代码的情况下;Ghidra和IDAPro等专用工具已经开发出来,但这些工具很难生成人类可读格式的代码。反......
  • 深度学习驱动的中文情感分析:PlugLink 在实践中的桥梁作用
    深度学习驱动的中文情感分析:PlugLink在实践中的桥梁作用情感分析技术则如同滤网,帮助我们从这股洪流中筛选出有价值的情感信号。特别是对于中文这样的多音字、同音词丰富且语境复杂度高的语言,深度学习模型展现了无与伦比的优势。本文将以一个具体的应用案例出发,探讨如何利......
  • 动手学深度学习(Pytorch版)代码实践 -循环神经网络-54~55循环神经网络的从零开始实现和
    54循环神经网络的从零开始实现importmathimporttorchfromtorchimportnnfromtorch.nnimportfunctionalasFfromd2limporttorchasd2limportmatplotlib.pyplotaspltimportliliPytorchaslp#读取H.G.Wells的时光机器数据集batch_size,num_steps......
  • 编译器(1)AI for compiler
    简介使用人工智能技术来改进编译器的性能和功能是一个激动人心的领域。以下是一些利用人工智能技术来改进编译器的方法和应用:自动优化:利用机器学习和深度学习技术,可以训练模型来自动优化编译器生成的代码。例如,可以使用神经网络来学习代码优化的模式和规律,从而提高编译器生......