commit initial

This commit is contained in:
baishi
2026-05-30 07:59:28 +08:00
commit cbefad339f
39 changed files with 7736 additions and 0 deletions

View File

@@ -0,0 +1,392 @@
# Tiny C Compiler in C# - Technical Design
Feature Name: tiny-c-compiler-csharp
Updated: 2026-05-20
## Description
本项目实现一个使用 C# 编写的 C 语言编译器,参考 TCC 的设计理念。编译器将 C 源代码直接编译为 x86/x64 本地机器码,不经过 MSIL 中间层。项目目标是实现一个轻量级、编译速度快的 C 编译器,支持 C99 标准的核心子集。
## Architecture
```mermaid
graph TD
A["C Source Code\n.c files"] --> B["Preprocessor\n预处理"]
B --> C["Lexer\n词法分析"]
C --> D["Parser\n语法分析"]
D --> E["Semantic Analyzer\n语义分析"]
E --> F["IR Generator\n中间表示生成"]
F --> G["Code Generator\n代码生成 x86/x64"]
G --> H["Object File\nPE/ELF"]
H --> I["Executable\n可执行文件"]
J["Error Handler"] -.-> B
J -.-> C
J -.-> D
J -.-> E
J -.-> F
J -.-> G
K["Symbol Table"] -.-> E
K -.-> F
K -.-> G
L["Type System"] -.-> E
L -.-> F
```
### Architecture Overview
编译器采用传统的单遍或多遍编译架构,分为以下主要阶段:
1. **预处理阶段**:处理宏展开、条件编译、头文件包含
2. **前端阶段**:词法分析、语法分析、语义分析
3. **中间阶段**IR 生成与优化
4. **后端阶段**x86/x64 代码生成与可执行文件输出
## Components and Interfaces
### 1. Preprocessor (预处理器)
**职责**
- 处理 `#include` 指令,展开头文件
- 处理 `#define` 宏定义和宏展开
- 处理条件编译 `#ifdef``#ifndef``#endif``#if`
- 处理 `#pragma` 指令
**接口**
```csharp
public interface IPreprocessor
{
string Preprocess(string sourceCode, string sourceFile);
void AddIncludePath(string path);
void DefineMacro(string name, string? value);
}
```
### 2. Lexer (词法分析器)
**职责**
- 将预处理后的源代码分解为 token 流
- 识别关键字、标识符、字面量、运算符、分隔符
- 跳过注释和空白
- 报告词法错误
**接口**
```csharp
public interface ILexer
{
IEnumerable<Token> Tokenize(string source);
}
public enum TokenType
{
Keyword, Identifier, IntLiteral, FloatLiteral,
CharLiteral, StringLiteral, Operator, Separator,
EOF, Error
}
public record Token(
TokenType Type,
string Lexeme,
object? Value,
SourceLocation Location
);
```
### 3. Parser (语法分析器)
**职责**
- 实现递归下降解析器
- 构建抽象语法树AST
- 处理 C 语言的运算符优先级
- 报告语法错误
**接口**
```csharp
public interface IParser
{
AstNode Parse();
}
public abstract record AstNode(SourceLocation Location);
public record ProgramNode(List<DeclarationNode> Declarations, SourceLocation Location) : AstNode(Location);
public record FunctionDeclarationNode(
TypeNode ReturnType,
string Name,
List<ParameterNode> Parameters,
BlockStatementNode Body,
SourceLocation Location
) : AstNode(Location);
```
### 4. Semantic Analyzer (语义分析器)
**职责**
- 类型检查与类型推断
- 符号表管理
- 作用域管理
- 语义错误报告
**接口**
```csharp
public interface ISemanticAnalyzer
{
void Analyze(AstNode root);
}
public interface ISymbolTable
{
void EnterScope();
void ExitScope();
void AddSymbol(string name, Symbol symbol);
Symbol? Lookup(string name);
}
```
### 5. IR Generator (中间表示生成器)
**职责**
- 将 AST 转换为三地址码形式的 IR
- 构建控制流图CFG
- 支持基本优化(常量折叠、死代码消除)
**接口**
```csharp
public interface IIrGenerator
{
IrProgram Generate(AstNode ast);
}
public record IrProgram(List<IrFunction> Functions);
public record IrFunction(string Name, List<IrBasicBlock> BasicBlocks);
public record IrBasicBlock(string Label, List<IrInstruction> Instructions);
public abstract record IrInstruction;
```
### 6. Code Generator (代码生成器)
**职责**
- 将 IR 转换为 x86/x64 机器码
- 寄存器分配
- 栈帧管理
- 遵循平台调用约定
**接口**
```csharp
public interface ICodeGenerator
{
byte[] Generate(IrProgram program, TargetArchitecture architecture);
}
public enum TargetArchitecture { X86, X64 }
```
### 7. Object File Writer (目标文件写入器)
**职责**
- 生成 PE 格式文件Windows
- 生成 ELF 格式文件Linux
- 处理重定位信息
- 设置入口点
**接口**
```csharp
public interface IObjectFileWriter
{
byte[] WriteExecutable(byte[] machineCode, TargetPlatform platform);
}
public enum TargetPlatform { WindowsX86, WindowsX64, LinuxX86, LinuxX64 }
```
### 8. Compiler Driver (编译器驱动)
**职责**
- 协调各个编译阶段
- 处理命令行参数
- 错误汇总与报告
- 管理编译流程
**接口**
```csharp
public class CompilerDriver
{
public int Run(string[] args);
public CompilationResult Compile(CompilationOptions options);
}
```
## Data Models
### Token 模型
```csharp
public readonly struct SourceLocation
{
public string FileName { get; }
public int Line { get; }
public int Column { get; }
}
public enum TokenType
{
// 关键字
Int, Char, Float, Double, Long, Short, Void,
If, Else, While, For, Do, Switch, Case, Default,
Break, Continue, Return, Struct, Union, Typedef,
// 字面量
IntLiteral, FloatLiteral, CharLiteral, StringLiteral,
// 标识符
Identifier,
// 运算符
Plus, Minus, Star, Slash, Percent,
Equal, NotEqual, Less, Greater, LessEqual, GreaterEqual,
Assign, PlusAssign, MinusAssign, StarAssign, SlashAssign,
And, Or, Not, BitAnd, BitOr, BitXor,
LeftShift, RightShift,
// 分隔符
LeftParen, RightParen, LeftBrace, RightBrace,
LeftBracket, RightBracket,
Semicolon, Comma, Dot, Arrow, Colon,
// 预处理器
HashInclude, HashDefine, HashIf, HashIfdef, HashIfndef, HashElse, HashEndif,
// 特殊
EOF, Error
}
```
### Type System 模型
```csharp
public abstract record CType(string Name);
public record PrimitiveType(TypeKind Kind) : CType(Kind.ToString())
{
public enum TypeKind { Void, Char, Short, Int, Long, Float, Double }
}
public record PointerType(CType BaseType) : CType($"{BaseType}*");
public record ArrayType(CType ElementType, int Size) : CType($"{ElementType}[{Size}]");
public record StructType(string Name, List<FieldDeclaration> Fields) : CType(Name);
public record FunctionType(CType ReturnType, List<CType> ParameterTypes) : CType("function");
```
### IR 指令模型
```csharp
public abstract record IrInstruction;
public record IrBinaryOp(IrTemp Dest, IrBinaryOpType Op, IrValue Left, IrValue Right) : IrInstruction;
public record IrUnaryOp(IrTemp Dest, IrUnaryOpType Op, IrValue Source) : IrInstruction;
public record IrLoad(IrTemp Dest, IrValue Address) : IrInstruction;
public record IrStore(IrValue Address, IrValue Value) : IrInstruction;
public record IrCall(IrTemp? Dest, string FunctionName, List<IrValue> Arguments) : IrInstruction;
public record IrJump(string TargetLabel) : IrInstruction;
public record IrBranch(IrValue Condition, string TrueLabel, string FalseLabel) : IrInstruction;
public record IrReturn(IrValue? Value) : IrInstruction;
public record IrLabel(string LabelName) : IrInstruction;
public enum IrBinaryOpType { Add, Sub, Mul, Div, Mod, And, Or, Xor, Shl, Shr, Eq, Ne, Lt, Gt, Le, Ge }
public enum IrUnaryOpType { Neg, Not, BitNot, Deref }
public abstract record IrValue;
public record IrTemp(string Name, CType Type) : IrValue;
public record IrConstant(long Value, CType Type) : IrValue;
public record IrGlobal(string Name, CType Type) : IrValue;
```
## Correctness Properties
### 不变量
1. **类型安全**: 所有 IR 指令的操作数类型必须匹配
2. **作用域正确性**: 符号查找必须遵循词法作用域规则
3. **控制流完整性**: 所有基本块必须有明确的前驱和后继
4. **寄存器一致性**: 代码生成前后寄存器状态必须一致
### 约束条件
1. 生成的机器码必须符合 x86/x64 指令集规范
2. 函数调用必须遵循目标平台的 ABIApplication Binary Interface
3. 栈帧布局必须保证栈指针对齐x64 要求 16 字节对齐)
4. 可执行文件格式必须符合 PE 或 ELF 规范
## Error Handling
### 错误分类
| 错误类型 | 阶段 | 处理方式 |
|---------|------|---------|
| 词法错误 | Lexer | 报告错误位置,跳过错误 token |
| 语法错误 | Parser | 报告期望的 token尝试错误恢复 |
| 类型错误 | Semantic | 报告类型不匹配详情 |
| 未声明符号 | Semantic | 报告符号名称和位置 |
| 代码生成错误 | CodeGen | 报告不支持的 IR 指令 |
### 错误报告接口
```csharp
public record ErrorInfo(
ErrorLevel Level, // Warning, Error, Fatal
string Message,
SourceLocation Location,
string? Suggestion = null
);
public interface IErrorReporter
{
void Report(ErrorInfo error);
bool HasErrors { get; }
IEnumerable<ErrorInfo> GetErrors();
}
```
## Test Strategy
### 单元测试
1. **Lexer 测试**:验证各种 token 的正确识别
2. **Parser 测试**:验证各种 C 语法的 AST 构建
3. **Semantic 测试**:验证类型检查和符号表
4. **IR 测试**:验证 AST 到 IR 的转换
5. **CodeGen 测试**:验证 IR 到机器码的转换
### 集成测试
1. **端到端测试**:编译简单 C 程序并验证输出
2. **回归测试**:使用 TCC 测试套件进行对比测试
3. **性能测试**:测量编译速度和生成代码质量
### 测试用例示例
```c
// test_hello.c
#include <stdio.h>
int main() {
printf("Hello, World!\n");
return 0;
}
// test_arithmetic.c
int add(int a, int b) {
return a + b;
}
int main() {
int result = add(3, 4);
return result - 7; // should return 0
}
// test_control_flow.c
int factorial(int n) {
if (n <= 1) return 1;
return n * factorial(n - 1);
}
```
## References
[^1]: (TCC Source) - Tiny C Compiler 源码 https://repo.or.cz/tinycc.git
[^2]: (PE Format) - Microsoft PE 和 COFF 规范 https://docs.microsoft.com/en-us/windows/win32/debug/pe-format
[^3]: (ELF Format) - ELF 规范 https://refspecs.linuxfoundation.org/elf/elf.pdf
[^4]: (x64 ABI) - System V AMD64 ABI https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf
[^5]: (x86 Calling Conventions) - x86 调用约定 https://en.wikipedia.org/wiki/X86_calling_conventions