深入解析DoctorWkt/acwj项目:字符与字符串字面量的实现
acwj A Compiler Writing Journey 项目地址: https://gitcode.com/gh_mirrors/ac/acwj
前言
在编译器开发过程中,处理字符和字符串字面量是一个重要的里程碑。本文将深入探讨如何在DoctorWkt/acwj项目中实现字符和字符串字面量的支持,这对于理解编译器如何处理文本数据具有重要意义。
字符字面量的实现
基本概念
字符字面量在C语言中由单引号包围的单个字符组成,如 'A'
。在我们的编译器中,字符字面量被当作整数类型处理,这符合C语言将字符视为小整数的特性。
扫描过程实现
扫描字符字面量的核心在于scanch()
函数,它负责处理转义字符:
static int scanch(void) {
int c = next();
if (c == '\\') {
switch (c = next()) {
case 'a': return '\a'; // 响铃
case 'b': return '\b'; // 退格
case 'f': return '\f'; // 换页
case 'n': return '\n'; // 换行
case 'r': return '\r'; // 回车
case 't': return '\t'; // 水平制表
case 'v': return '\v'; // 垂直制表
case '\\': return '\\'; // 反斜杠
case '"': return '"'; // 双引号
case '\'': return '\''; // 单引号
default: fatalc("未知的转义序列", c);
}
}
return c;
}
这个实现涵盖了常见的转义序列,但为了简化,没有处理八进制或Unicode转义。
字符串字面量的实现
基本概念
字符串字面量由双引号包围的字符序列组成,如 "Hello"
。在内存中,字符串以null字符('\0')结尾。
扫描过程
scanstr()
函数负责扫描字符串字面量:
static int scanstr(char *buf) {
int i, c;
for (i=0; i<TEXTLEN-1; i++) {
if ((c = scanch()) == '"') {
buf[i] = 0;
return i;
}
buf[i] = c;
}
fatal("字符串字面量过长");
return 0;
}
该函数使用scanch()
处理每个字符,确保字符串以null结尾,并防止缓冲区溢出。
语法分析与AST构建
在语法分析阶段,字符串字面量被处理为AST中的叶节点:
case T_STRLIT:
id = genglobstr(Text);
n = mkastleaf(A_STRLIT, P_CHARPTR, id);
break;
这里的关键点:
- 为字符串分配全局标签
- 创建类型为P_CHARPTR的AST节点
- 使用A_STRLIT表示字符串字面量节点
代码生成
字符串存储生成
cgglobstr()
函数生成字符串的汇编表示:
void cgglobstr(int l, char *strvalue) {
char *cptr;
cglabel(l);
for (cptr = strvalue; *cptr; cptr++) {
fprintf(Outfile, "\t.byte\t%d\n", *cptr);
}
fprintf(Outfile, "\t.byte\t0\n");
}
字符串地址加载
cgloadglobstr()
生成加载字符串地址的指令:
int cgloadglobstr(int id) {
int r = alloc_register();
fprintf(Outfile, "\tleaq\tL%d(\%%rip), %s\n", id, reglist[r]);
return r;
}
类型系统调整
在处理指针类型时,发现了一个重要修正:
if (inttype(ltype) && ptrtype(rtype)) {
rsize = genprimsize(value_at(rtype));
if (rsize > 1)
return mkastunary(A_SCALE, rtype, tree, rsize);
else
return tree; // 对于char*不需要缩放
}
这个修正确保了对char*
类型的正确处理,避免了不必要的缩放操作。
测试与验证
实现完成后,编译器现在可以处理如下的代码:
char *s = "Hello world";
printint(10);
输出结果为:
10
Hello world
总结与展望
本文详细介绍了在DoctorWkt/acwj项目中实现字符和字符串字面量的过程,包括:
- 词法分析器对字符和字符串的扫描处理
- 语法分析器构建相应的AST节点
- 代码生成器输出正确的汇编指令
- 类型系统的相关调整
这个实现虽然简化了某些复杂情况(如宽字符、Unicode等),但完整覆盖了基本的字符和字符串处理需求。下一步可以考虑添加更多的运算符支持,进一步增强编译器的表达能力。
理解字符和字符串字面量的处理机制,对于深入学习编译器设计和C语言实现原理具有重要意义。这种实现方式也展示了如何将高级语言特性映射到底层机器表示的基本方法。
acwj A Compiler Writing Journey 项目地址: https://gitcode.com/gh_mirrors/ac/acwj
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考