# Requirements Document ## Introduction 本改进计划涵盖 TinyCC 编译器的 9 个核心改进方向,包括端到端测试、错误报告增强、代码清理、语义分析完善、预处理器集成、代码生成优化、调试信息支持、PE 格式支持及性能基准测试。 ## Glossary - **TinyCC**: 本项目实现的轻量级 C 编译器 - **E2E 测试**: 端到端测试,验证完整编译流程 - **ELF**: Executable and Linkable Format,Linux 可执行文件格式 - **PE**: Portable Executable,Windows 可执行文件格式 - **DWARF**: 调试信息格式,支持源码级调试 - **ABI**: Application Binary Interface,应用二进制接口 ## Requirements ### Requirement 1: 端到端编译测试 **User Story:** AS 一个编译器开发者,I WANT 验证完整编译流程生成的可执行文件能够正确运行,SO THAT 确保编译器各组件协同工作正常 #### Acceptance Criteria 1. WHEN 提供包含 `main` 函数的 C 源代码,编译器 SHALL 生成可在 Linux 上执行的 ELF 文件 2. WHEN 运行生成的 ELF 文件,程序 SHALL 返回正确的退出码 3. WHEN 编译包含算术运算的 C 程序,执行程序 SHALL 输出正确的计算结果 4. WHEN 编译包含函数调用的 C 程序,执行程序 SHALL 正确调用函数并返回结果 5. WHEN 编译包含控制流语句(if/while/for)的 C 程序,执行程序 SHALL 正确执行控制流 ### Requirement 2: 增强错误报告 **User Story:** AS 一个 C 程序员,I WANT 编译器提供包含代码上下文和位置提示的错误信息,SO THAT 能够快速定位和修复代码问题 #### Acceptance Criteria 1. WHEN 报告编译错误,错误信息 SHALL 包含文件名、行号和列号 2. WHEN 报告语法错误,错误信息 SHALL 显示出错代码行及错误位置标记 3. WHEN 报告类型错误,错误信息 SHALL 说明期望的类型和实际提供的类型 4. WHEN 报告多个错误,编译器 SHALL 汇总所有错误并一次性输出 5. IF 错误信息包含建议,建议 SHALL 提供可能的修复方向 ### Requirement 3: 清理误提交文件 **User Story:** AS 一个仓库维护者,I WANT 从版本控制中移除构建产物和临时文件,SO THAT 保持仓库整洁并减小仓库体积 #### Acceptance Criteria 1. WHEN 提交代码,构建目录 `bin/` 和 `obj/` SHALL 被 `.gitignore` 排除 2. WHEN 提交代码,临时测试文件 `test_output` SHALL 从版本控制中移除 3. WHEN 提交代码,本地测试文件 `test.c` SHALL 从版本控制中移除 ### Requirement 4: 语义分析器完整实现 **User Story:** AS 一个 C 编译器开发者,I WANT 语义分析器能够验证程序的语义正确性,SO THAT 拒绝语义错误的 C 程序 #### Acceptance Criteria 1. WHEN 遇到未声明的变量,语义分析器 SHALL 报告"未声明的标识符"错误 2. WHEN 遇到类型不匹配的赋值操作,语义分析器 SHALL 报告类型不匹配错误 3. WHEN 遇到函数调用参数数量不匹配,语义分析器 SHALL 报告参数数量错误 4. WHEN 遇到函数调用参数类型不匹配,语义分析器 SHALL 报告参数类型错误 5. WHILE 处理嵌套作用域,语义分析器 SHALL 正确解析变量的词法作用域 6. WHEN 遇到重复的函数声明,语义分析器 SHALL 报告重复定义错误 ### Requirement 5: 预处理器集成到编译流程 **User Story:** AS 一个 C 编译器用户,I WANT 编译器正确处理预处理指令,SO THAT 可以编译包含宏和头文件的 C 程序 #### Acceptance Criteria 1. WHEN 遇到 `#include` 指令,预处理器 SHALL 展开并包含指定头文件的内容 2. WHEN 遇到 `#define` 宏定义,预处理器 SHALL 在后续代码中展开宏 3. WHEN 遇到 `#ifdef`/`#ifndef` 条件编译,预处理器 SHALL 根据宏定义情况选择编译分支 4. WHEN 预处理完成后,编译器驱动 SHALL 将预处理后的源代码传递给词法分析器 5. IF 头文件不存在,预处理器 SHALL 报告错误并提供搜索路径信息 ### Requirement 6: 代码生成优化验证 **User Story:** AS 一个编译器开发者,I WANT 验证优化后的代码生成器能够正确分配寄存器并生成高效代码,SO THAT 提升生成程序的执行性能 #### Acceptance Criteria 1. WHEN 使用优化代码生成器编译函数,寄存器分配算法 SHALL 为活跃变量分配物理寄存器 2. WHEN 寄存器数量不足,寄存器分配算法 SHALL 正确地将变量溢出到栈 3. WHEN 生成优化后的机器码,程序执行结果 SHALL 与未优化版本一致 4. WHILE 分配寄存器,寄存器分配算法 SHALL 遵循调用约定保留被调用者保存的寄存器 5. IF 代码生成器生成溢出代码,溢出区域 SHALL 正确管理栈帧布局 ### Requirement 7: DWARF 调试信息生成 **User Story:** AS 一个 C 程序员,I WANT 编译器生成 DWARF 调试信息,SO THAT 可以使用 gdb 对生成的可执行文件进行源码级调试 #### Acceptance Criteria 1. WHEN 启用调试信息选项,编译器 SHALL 在 ELF 文件中生成 `.debug_info` 节 2. WHEN 生成调试信息,调试信息 SHALL 包含源文件路径和行号映射 3. WHEN 生成调试信息,调试信息 SHALL 包含变量名称、类型和作用域信息 4. WHEN 使用 gdb 加载生成的可执行文件,gdb SHALL 能够显示源代码并设置断点 5. IF 未启用调试信息选项,编译器 SHALL 不生成调试信息以减小文件体积 ### Requirement 8: PE 格式可执行文件支持 **User Story:** AS 一个 Windows 用户,I WANT 编译器生成 Windows PE 格式的可执行文件,SO THAT 可以在 Windows 系统上运行编译后的程序 #### Acceptance Criteria 1. WHEN 指定目标平台为 Windows x64,编译器 SHALL 生成 PE32+ 格式的可执行文件 2. WHEN 生成 PE 文件,PE 文件 SHALL 包含正确的 DOS 头和 PE 签名 3. WHEN 生成 PE 文件,PE 文件 SHALL 包含有效的节表(`.text`、`.data`) 4. WHEN 运行生成的 PE 文件,Windows 操作系统 SHALL 能够加载并执行程序 5. WHEN 生成 PE 文件,PE 文件 SHALL 设置正确的入口点(Entry Point) ### Requirement 9: 编译性能基准测试 **User Story:** AS 一个编译器开发者,I WANT 建立编译性能基准,SO THAT 可以量化编译器性能变化并识别性能瓶颈 #### Acceptance Criteria 1. WHEN 运行性能基准测试,测试 SHALL 测量编译器处理标准 C 文件的编译时间 2. WHEN 运行性能基准测试,测试 SHALL 测量生成代码的执行时间 3. WHEN 运行性能基准测试,测试 SHALL 输出编译时间和执行时间的统计报告 4. WHILE 进行性能优化,开发者 SHALL 能够对比优化前后的基准测试结果 5. IF 性能基准测试发现回归,测试结果 SHALL 标记性能下降的模块