c++如何用ANTLR生成解析器 c++语法分析入门【工具】

用 ANTLR 生成 C++ 解析器的核心是编写 .g4 语法规则,用 ANTLR 工具生成 C++ 目标代码,再在项目中调用解析器类;需手动配置 C++ 运行时、使用社区 C++ 语法文件(如 CPP14.g4),通过 java -jar 命令生成 lexer/parser/visitor,最后在 C++ 中构造输入流、词法/语法分析器并访问 AST。

用 ANTLR 生成 C++ 解析器,核心是:先写语法规则(.g4 文件),再用 ANTLR 工具生成 C++ 目标代码,最后在 C++ 项目中调用生成的解析器类。整个过程不依赖编译器前端,适合做语法检查、代码转换、DSL 解析等任务。

准备 ANTLR 运行环境

ANTLR 官方不直接提供 C++ 运行时,需手动配置:

  • 下载 ANTLR v4.x 的 jar 包(如 antlr-4.13.1-complete.jar),建议从 antlr.org/download 获取
  • 安装 C++ 运行时:克隆官方仓库 https://github.com/antlr/grammars-v4 中的 runtime/Cpp,或使用 vcpkg 安装:vcpkg install antlr4cpp
  • 确保系统有 CMake(≥3.15)和支持 C++17 的编译器(如 GCC 9+、Clang 10+ 或 MSVC 2019+)

编写或复用 C++ 语法规则文件

ANTLR 不自带标准 C++ 语法(因 C++ 太复杂),但社区维护了较完整的实现:

  • 推荐使用 grammars-v4/cpp/cpp14cpp17 目录下的 CPP14.g4(路径:grammars-v4/cpp/cpp14/CPP14.g4
  • 该文件已拆分为 CPP14Lexer.g4CPP14Parser.g4,支持大部分 C++14 语法(宏、模板、lambda 等基础结构)
  • 若只需简单子集(如函数声明、变量定义),可自行精简规则,避免过度复杂导致内存溢出或解析慢

生成 C++ 解析器代码

进入存放 .g4 文件的目录,执行命令:

java -jar antlr-4.13.1-complete.jar -Dlanguage=Cpp -no-listener -visitor CPP14Lexer.g4 CPP14Parser.g4

  • -Dlanguage=Cpp 指定目标为 C++
  • -no-listener 跳过生成监听器(初学者建议先用 Visitor 模式)
  • -visitor 生成 CPP14Visitor.h/.cpp,方便遍历 AST 并自定义逻辑
  • 运行后会生成 CPP14Lexer.h/.cppCPP14Parser.h/.cpp 等文件

在 C++ 项目中调用解析器

以解析一段简单代码为例(如 "int main() { return 0; }"):

  • 将生成的 .h/.cpp 和 ANTLR C++ 运行时头文件加入工程(CMake 中 link antlr4_static 库)
  • 构造输入流 → 创建词法分析器 → 构建 token 流 → 创建语法分析器 → 调用起始规则(如 translationUnit()
  • 获取 parse tree 后,继承 CPP14Visitor 实现自己的访问逻辑,重写对应 visit 方法(如 visitFunctionDefinition

关键代码片段:

auto input = std::make_shared(code);
auto lexer = std::make_shared(input);
auto tokens = std::make_shared(lexer);
auto parser = std::make_shared(tokens);
tree::ParseTree* tree = parser->translationUnit();
MyVisitor visitor;
visitor.visit(tree);