{"id":15048899,"url":"https://github.com/laa-1/c-compiler","last_synced_at":"2026-02-06T08:03:36.070Z","repository":{"id":239262447,"uuid":"799043194","full_name":"laa-1/c-compiler","owner":"laa-1","description":"一个 C 语言编译器和虚拟机，支持除结构体以外的语法，支持字节码导出和直接运行字节码，内建I/O函数，包含了词法分析、语法分析、构建 AST、类型推导和检查、错误检查、错误信息输出、字节码生成、虚拟机执行等多个模块。","archived":false,"fork":false,"pushed_at":"2024-09-18T16:40:41.000Z","size":169,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-17T20:21:22.000Z","etag":null,"topics":["abstract-syntax-tree","bytecode","c-language","complier","cpp","virtual-machine"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/laa-1.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-05-11T03:11:46.000Z","updated_at":"2024-09-18T16:40:44.000Z","dependencies_parsed_at":"2024-09-24T21:27:10.246Z","dependency_job_id":null,"html_url":"https://github.com/laa-1/c-compiler","commit_stats":null,"previous_names":["laa-1/c-compiler","laa-1/ccompiler"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/laa-1%2Fc-compiler","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/laa-1%2Fc-compiler/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/laa-1%2Fc-compiler/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/laa-1%2Fc-compiler/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/laa-1","download_url":"https://codeload.github.com/laa-1/c-compiler/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254442329,"owners_count":22071863,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["abstract-syntax-tree","bytecode","c-language","complier","cpp","virtual-machine"],"created_at":"2024-09-24T21:17:04.015Z","updated_at":"2026-02-06T08:03:36.021Z","avatar_url":"https://github.com/laa-1.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# c-compiler\n\n一个 C 语言编译器和虚拟机，支持除结构体以外的语法，支持字节码导出和直接运行字节码，内建I/O函数，\n\n包含了词法分析、语法分析、构建 AST、类型推导和检查、错误检查、错误信息输出、字节码生成、虚拟机执行等多个模块。\n\n完全使用 C++ 手写实现，不使用任何编译器构建工具，没有任何除了 C++ 标准库外的依赖。\n\n[点击这里](doc/doc.md) 可以查看介绍本项目的设计和原理的技术文档\n\n## 安装\n\n### 二进制可执行文件\n\n[点击这里](https://github.com/laa-1/c-compiler/releases) 可以跳转 Releases 找到构建好的 Windows 平台的二进制可执行文件。\n\n### 从源代码构建\n\n环境要求：\n\n* C++20\n\n由于没有除标准库以外的依赖，根据 CMakeLists.txt 的内容进行构建即可 \n\n## 使用\n\n使用 `cc -h` 可以获取帮助来查看用法。\n\n```text\nUsage:\n   cc -cl \u003cinput_file\u003e [options]                        Compile mode, compile source file and performing other operations depending on the options\n   cc -vm \u003cinput_file\u003e                                  Virtual machine mode, run binary bytecode file\n   cc -h                                                Get help, display this information\nOptions:\n                                                        Defaults to run when no option is selected\n   -r                                                   Run\n   -o \u003coutput_file\u003e                                     Output binary bytecode file\n   -oh \u003coutput_file\u003e                                    Output human-readable bytecode file\n   -ast                                                 Print abstract syntax tree\nExamples:\n   cc -c main.c                                         Compile source file and run\n   cc -c main.c -r                                      Compile source file and run\n   cc -c main.c -ast -o main.bin -oh main.txt -r        Compile source file, print abstract syntax tree, output binary bytecode file, output human-readable bytecode file and run\n   cc -vm main.bin                                      Run binary bytecode file\n```\n\n## 示例\n\n一个简单的快速排序和二分查找：\n\n```c\n/**\n * 二分查找\n */\n\nvoid swap(int *p1, int *p2) {\n    int tmp = *p1;\n    *p1 = *p2;\n    *p2 = tmp;\n}\n\nvoid quick_sort(int *nums, int start, int end) {\n    if (start \u003e= end) {\n        return;\n    }\n    int base = start;\n    int left = start;\n    int right = end;\n    while (left \u003c right) {\n        while (nums[right] \u003e= nums[base] \u0026\u0026 left \u003c right) {\n            right--;\n        }\n        while (nums[left] \u003c= nums[base] \u0026\u0026 left \u003c right) {\n            left++;\n        }\n        swap(nums + left, nums + right);\n    }\n    swap(nums + base, nums + left);\n    quick_sort(nums, start, left - 1);\n    quick_sort(nums, left + 1, end);\n}\n\nint binary_search(int *nums, int start, int end, int value) {\n    for (int left = start, right = end, middle = left + (right - left) / 2; left \u003c= right; middle = left + (right - left) / 2) {\n        if (nums[middle] \u003c value) {\n            left = middle + 1;\n        } else if (nums[middle] \u003e value) {\n            right = middle - 1;\n        } else {\n            return middle;\n        }\n    }\n    return -1;\n}\n\nint main() {\n    int nums[10] = {13, 17, 15, 19, 18, 10, 14, 12, 16, 11};\n    print_s(\"unsorted: \");\n    for (int i = 0; i \u003c 10; i++) {\n        print_i64(nums[i]);\n        print_s(\" \");\n    }\n    print_s(\"\\n\");\n    quick_sort(nums, 0, 9);\n    print_s(\"sorted: \");\n    for (int i = 0; i \u003c 10; i++) {\n        print_i64(nums[i]);\n        print_s(\" \");\n    }\n    print_s(\"\\n\");\n    int location = binary_search(nums, 0, 9, 13);\n    print_s(\"location: \");\n    print_i64(location);\n    print_s(\"\\n\");\n    return 0;\n}\n``` \n\n```text\nunsorted: 13 17 15 19 18 10 14 12 16 11 \nsorted: 10 11 12 13 14 15 16 17 18 19 \nlocation: 3\n```\n\n打印一个复杂声明的 AST：\n\n```c\n/**\n * 文档中的示例程序\n */\n\nint main() {\n    char (*(*p[3])())[5];\n    return 0;\n}\n```\n\n```text\nTranslationUnit 5:1\n    declaration: FunctionDefinition 5:1\n        functionType: FunctionType 5:5\n            returnType: ScalarType 5:1\n                baseType: int\n        identifier: main\n        body: CompoundStatement 5:12\n            statement: DeclarationStatement 6:5\n                declaration: VariableDeclaration 6:5\n                    variableType: ArrayType 6:14\n                        elemType: PointerType 6:13\n                            sourceType: FunctionType 6:12\n                                returnType: PointerType 6:11\n                                    sourceType: ArrayType 6:10\n                                        elemType: ScalarType 6:5\n                                            baseType: char\n                                        size: 5\n                        size: 3\n                    identifier: p\n            statement: ReturnStatement 7:5\n                value: IntLiteralExpression 7:12\n                    value: 0\n```\n\n更多的示例可以在 example 目录下找到。\n\n## 内建函数\n\n编译器中内建 8 个函数，用于输入和输出。\n\n无需引入头文件或添加额外声明，直接调用即可。\n\n内建函数也会参与类型检查，需要注意传参类型。\n\n下面是它们的声明原型：\n\n```c\nvoid scan_i64(long long int *address);\nvoid scan_u64(unsigned long long int *address);\nvoid scan_f64(double *address);\nvoid scan_s(char *address);\nvoid print_i64(long long int value);\nvoid print_u64(unsigned long long int value);\nvoid print_f64(double value);\nvoid print_s(char *address);\n```\n\n## 不支持的语法\n\n本项目的语法是根据 ISO-IEC 9899-1999 (E) 标准进行设计，实际的经过修改后语法规则可以查看 [grammar.txt](doc/grammar.txt)。\n\n* 不支持 struct、union、enum、typedef 相关的语法特性。\n* 不支持变长参数，如 `(int a, ...)`\n* 不支持动态数组，如 `a[n]`。\n* typedef、extern、static、auto、register、inline、restrict、volatile 修饰符无实际效果，但不影响正常编译。\n* sizeof 运算符不支持对类型求字节数，但可以对表达式求字节数。\n\n其他语法特性都是支持的，如任意形式嵌套的声明、函数指针、指针运算、多维数组、字符串初始化、隐式类型转换、后置递增、逗号表达式、for 语句空条件等等均支持。","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flaa-1%2Fc-compiler","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flaa-1%2Fc-compiler","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flaa-1%2Fc-compiler/lists"}