深入解析DoctorWkt/acwj项目:编译器开发中的空函数参数与词法分析改进

深入解析DoctorWkt/acwj项目:编译器开发中的空函数参数与词法分析改进

acwj A Compiler Writing Journey acwj 项目地址: https://gitcode.com/gh_mirrors/ac/acwj

前言

在编译器开发过程中,处理函数参数和词法分析是构建可靠编译器的关键环节。本文将详细探讨如何实现void函数参数的支持,以及如何改进词法分析器以处理十六进制和八进制常量。

空函数参数的处理

问题背景

在C语言中,函数参数列表有两种方式表示无参数:

int func(void);  // 明确使用void表示无参数
int func();       // 空括号也表示无参数

虽然第二种语法已经能够表示无参数,但第一种形式在C语言中更为常见和明确,因此编译器需要支持这种语法。

技术挑战

当编译器遇到左括号时,通常会进入declaration_list()函数处理参数声明。但这个函数设计时假设每个类型后面都会跟着一个标识符,难以处理只有类型(void)而没有标识符的情况。

解决方案

我们采用"前瞻"(peek)技术来解决这个问题:

  1. 遇到左括号后,检查下一个token是否为void
  2. 如果是void,再前瞻检查再下一个token
  3. 如果是右括号,则表示无参数
  4. 否则,正常处理参数列表

这种技术避免了直接消费token导致的状态混乱,保持了词法分析的灵活性。

词法分析器的改进

前瞻机制实现

为了实现token前瞻功能,我们在词法分析器中增加了以下结构:

struct token Token;      // 当前token
struct token Peektoken;   // 前瞻token

扫描函数scan()被修改为首先检查Peektoken,如果存在则返回Peektoken,否则才从输入中读取新token。

参数列表处理逻辑

参数列表处理函数param_declaration_list()的核心逻辑变为:

while (未遇到右括号) {
    if (当前token是void) {
        扫描Peektoken;
        if (Peektoken是右括号) {
            设置参数计数为0;
            跳过void token;
            退出循环;
        }
    }
    // 否则正常处理参数声明
}

这种处理方式优雅地解决了void参数列表的歧义问题。

数值常量解析增强

十六进制和八进制支持

原始编译器只支持十进制整数常量,我们扩展了scanint()函数以支持:

  1. 以0x开头的十六进制数
  2. 以0开头的八进制数

实现原理是:

  • 检测前导0
  • 如果是0x则设置基数为16
  • 如果是单独0则设置基数为8
  • 使用相应基数进行数值转换

字符常量增强

我们还改进了字符常量的解析,支持:

  • 八进制转义序列(如'\0')
  • 十六进制转义序列(如'\x41')

关键函数scanch()和新增的hexchar()协同工作,精确解析各种形式的字符常量。

技术实现细节

基数转换算法

数值转换的核心算法保持简洁高效:

val = val * radix + digit_value;

这个通用公式适用于任何基数(10、8或16)的转换。

错误处理

增强的错误检查包括:

  • 数字有效性验证(确保数字符合当前基数)
  • 十六进制数字缺失检测
  • 数值范围检查(特别是字符常量)

总结与展望

本次改进主要集中在词法分析器方面,虽然改动不大,但为编译器的自举(self-compiling)能力奠定了基础。这些看似微小的功能实际上是构建完整编译器不可或缺的部分。

未来工作可能包括:

  1. 实现sizeof运算符
  2. 支持static函数和变量
  3. 进一步的代码重构和优化

通过逐步解决这些技术挑战,我们的编译器正朝着功能完整性和健壮性稳步前进。

acwj A Compiler Writing Journey acwj 项目地址: https://gitcode.com/gh_mirrors/ac/acwj

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

谭凌岭Fourth

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值