# go-complier **Repository Path**: sheenashea/go-complier ## Basic Information - **Project Name**: go-complier - **Description**: go语言编译器java版本 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-12-17 - **Last Updated**: 2025-12-29 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Go语言编译器 这是一个使用Java和ANTLR4实现的Go语言编译器,作为编译原理课程的实践项目。 ## 项目概述 本编译器实现了Go语言核心子集的编译功能,包括: ### 基本功能 1. **词法分析和语法分析** - 使用ANTLR4生成词法分析器和语法分析器 2. **语法树生成** - 生成并可视化抽象语法树(AST) 3. **三地址代码生成** - 生成中间代码表示 4. **汇编代码生成** - 生成x86-64汇编代码 ### 附加功能 1. **错误分析和恢复** - 检测语法和语义错误,提供错误恢复建议 2. **可执行文件生成** - 通过汇编器和链接器生成可执行文件 3. **代码优化** - 多种优化技术提升代码质量 ## Go语言语法描述 ### 支持的语法结构 #### 1. 程序结构 ```go package main import "fmt" func main() { // 程序入口 } ``` #### 2. 变量声明 ```go var x int = 10 // 完整声明 var y = 20 // 类型推断 z := 30 // 短变量声明 var a, b, c int // 多变量声明 ``` #### 3. 常量声明 ```go const PI = 3.14159 const ( A = 1 B = 2 ) ``` #### 4. 基本类型 - 整数: `int`, `int8`, `int16`, `int32`, `int64` - 无符号整数: `uint`, `uint8`, `uint16`, `uint32`, `uint64` - 浮点数: `float32`, `float64` - 布尔: `bool` - 字符串: `string` - 字节/符文: `byte`, `rune` #### 5. 运算符 - 算术: `+`, `-`, `*`, `/`, `%` - 比较: `==`, `!=`, `<`, `<=`, `>`, `>=` - 逻辑: `&&`, `||`, `!` - 位运算: `&`, `|`, `^`, `<<`, `>>` - 赋值: `=`, `:=`, `+=`, `-=`, `*=`, `/=` #### 6. 控制流 ```go // if语句 if condition { // ... } else if condition2 { // ... } else { // ... } // for循环 for i := 0; i < 10; i++ { // ... } for condition { // while风格 } for { // 无限循环 } // switch语句 switch value { case 1: // ... case 2: // ... default: // ... } ``` #### 7. 函数 ```go func add(a int, b int) int { return a + b } func swap(a, b int) (int, int) { return b, a } ``` ## 中间代码设计 ### 三地址指令格式 采用四元式表示法:`(op, arg1, arg2, result)` ### 指令类型 | 类型 | 格式 | 说明 | |------|------|------| | 赋值 | `x = y` | 简单赋值 | | 二元运算 | `x = y op z` | 算术/逻辑运算 | | 一元运算 | `x = op y` | 取负/取反 | | 条件跳转 | `if x goto L` | 条件为真跳转 | | 无条件跳转 | `goto L` | 无条件跳转 | | 函数调用 | `x = call f, n` | 调用函数f,n个参数 | | 参数传递 | `param x` | 传递参数 | | 返回 | `return x` | 函数返回 | | 标签 | `L:` | 跳转目标 | ### 示例 源代码: ```go x = a + b * c ``` 三地址代码: ``` t1 = b * c t2 = a + t1 x = t2 ``` ## 代码优化 ### 实现的优化技术 1. **常量折叠 (Constant Folding)** - 在编译时计算常量表达式 - 例:`x = 2 + 3` → `x = 5` 2. **常量传播 (Constant Propagation)** - 将变量替换为已知的常量值 - 例:`x = 5; y = x + 1` → `y = 5 + 1` → `y = 6` 3. **复制传播 (Copy Propagation)** - 将变量复制替换为原变量 - 例:`x = y; z = x + 1` → `z = y + 1` 4. **代数简化 (Algebraic Simplification)** - `x + 0 = x` - `x * 1 = x` - `x * 0 = 0` - `x - x = 0` 5. **强度削弱 (Strength Reduction)** - 用移位代替乘除2的幂 - 例:`x * 8` → `x << 3` 6. **公共子表达式消除 (CSE)** - 避免重复计算相同表达式 7. **死代码消除 (Dead Code Elimination)** - 删除结果未被使用的指令 ## 项目结构 ``` go-compiler/ ├── pom.xml # Maven配置文件 ├── README.md # 项目文档 ├── src/ │ └── main/ │ ├── antlr4/ │ │ └── com/compiler/parser/ │ │ ├── GoLexer.g4 # 词法规则 │ │ └── GoParser.g4 # 语法规则 │ └── java/ │ └── com/compiler/ │ ├── GoCompiler.java # 编译器主类 │ ├── CompilerOptions.java # 编译选项 │ ├── CompilationResult.java# 编译结果 │ ├── ast/ │ │ └── ASTVisualizer.java# AST可视化 │ ├── semantic/ │ │ ├── Symbol.java # 符号定义 │ │ ├── GoType.java # 类型系统 │ │ ├── SymbolTable.java # 符号表 │ │ └── SemanticAnalyzer.java # 语义分析 │ ├── codegen/ │ │ ├── ThreeAddressCode.java # 三地址指令 │ │ ├── ThreeAddressCodeGenerator.java # TAC生成器 │ │ ├── AssemblyGenerator.java # 汇编生成器 │ │ └── Optimizer.java # 代码优化器 │ └── error/ │ └── ErrorHandler.java # 错误处理 └── examples/ ├── hello.go # Hello World示例 ├── arithmetic.go # 算术运算示例 ├── control_flow.go # 控制流示例 ├── functions.go # 函数示例 ├── error_example.go # 错误示例 └── optimization.go # 优化示例 ``` ## 使用方法 ### 编译项目 ```bash # 进入项目目录 cd go-compiler # 使用Maven编译 mvn clean compile # 打包成JAR mvn package ``` ### 运行编译器 ```bash # 运行示例(无参数) java -jar target/go-compiler-1.0-SNAPSHOT-jar-with-dependencies.jar # 编译Go源文件 java -jar target/go-compiler-1.0-SNAPSHOT-jar-with-dependencies.jar [选项] <源文件> ``` ### 命令行选项 | 选项 | 说明 | |------|------| | `-ast` | 生成语法树 | | `-ast-out FILE` | 将语法树保存到文件(DOT格式) | | `-tac` | 生成三地址代码 | | `-tac-out FILE` | 将三地址代码保存到文件 | | `-asm` | 生成汇编代码 | | `-asm-out FILE` | 将汇编代码保存到文件 | | `-o FILE` | 输出可执行文件 | | `-O` | 启用优化 | | `-tokens` | 显示词法单元 | | `-v` | 详细输出 | | `-continue` | 遇到错误继续编译 | ### 示例 windows系统点击test_all.bat ```bash # 显示语法树和三地址代码 java -jar go-compiler.jar -ast -tac examples/hello.go # 生成优化后的汇编代码 java -jar go-compiler.jar -asm -O -asm-out output.s examples/arithmetic.go # 生成可执行文件 java -jar go-compiler.jar -o program examples/functions.go ``` ## 输出示例 ### 语法树输出(文本格式) ``` sourceFile ├── packageClause │ ├── PACKAGE: 'package' │ └── IDENTIFIER: 'main' ├── topLevelDecl │ └── functionDecl │ ├── FUNC: 'func' │ ├── IDENTIFIER: 'main' │ ├── signature │ │ └── parameters │ │ ├── LPAREN: '(' │ │ └── RPAREN: ')' │ └── block │ └── ... ``` ### 三地址代码输出 ``` 0: func main: 1: // 函数 main 开始 2: x = 10 3: y = 20 4: t0 = y * 2 5: t1 = x + t0 6: z = t1 7: t2 = z > 30 8: ifFalse t2 goto L0 9: println z 10: goto L1 11: L0: 12: println x 13: L1: 14: return 15: endfunc main ``` ### 汇编代码输出 ```nasm section .data fmt_int_nl db "%lld", 10, 0 section .text global main extern printf main: push rbp mov rbp, rsp sub rsp, 256 ; x = 10 mov rax, 10 mov [rbp-8], rax ; y = 20 mov rax, 20 mov [rbp-16], rax ; ... 更多指令 ... mov rsp, rbp pop rbp ret ``` ## 错误处理 编译器能够检测并报告以下类型的错误: 1. **词法错误** - 无法识别的字符或标记 2. **语法错误** - 不符合语法规则的结构 3. **语义错误** - 类型不匹配、未定义变量等 4. **类型错误** - 操作数类型不兼容 错误报告格式: ``` 错误 [行号:列号]: 错误描述 (在 '相关符号' 附近) 建议: 可能的修复建议 ``` ## 技术栈 - **Java 17** - 主要编程语言 - **ANTLR 4.13** - 词法/语法分析器生成器 - **Maven** - 项目构建工具 - **NASM** - 汇编器(用于生成可执行文件) - **GCC** - 链接器(用于生成可执行文件) ## 参考资料 1. Go语言规范: https://go.dev/ref/spec 2. ANTLR4文档: https://www.antlr.org/ 3. 编译原理(龙书) 4. x86-64汇编语言参考 ## 作者 编译原理课程实践项目 ## 许可证 MIT License