You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何构建最新版ANTLR4 C++语法解析器?

构建最新版ANTLR4 C++ C++解析器遇到编译错误

背景

已从官方ANTLR语法仓库下载C++语法文件(包含CPP14Parser、CPP14Lexer及CPPParser相关文件),旧版本(指定GitHub提交)可通过自行编写的CMakeLists.txt正常构建,但最新版编译时出现大量错误,查阅的文档已过时。

旧版本可工作的操作流程

1. CMakeLists.txt配置

cmake_minimum_required(VERSION 3.14)
project(CPPparser)
set(CMAKE_CXX_STANDARD 17)
include_directories(
        ${PROJECT_SOURCE_DIR}/generated/
        ${PROJECT_SOURCE_DIR}/cppruntime/src/
        ${PROJECT_SOURCE_DIR}/src/
)
set(src_dir
        ${PROJECT_SOURCE_DIR}/generated/CPP14Lexer.cpp
        ${PROJECT_SOURCE_DIR}/generated/CPP14Parser.cpp
        ${PROJECT_SOURCE_DIR}/generated/CPP14Visitor.cpp
        ${PROJECT_SOURCE_DIR}/generated/CPP14BaseVisitor.cpp
 )
file(GLOB antlr4-cpp-src
    ${PROJECT_SOURCE_DIR}/cppruntime/src/*.cpp
    ${PROJECT_SOURCE_DIR}/cppruntime/src/atn/*.cpp
    ${PROJECT_SOURCE_DIR}/cppruntime/src/dfa/*.cpp
    ${PROJECT_SOURCE_DIR}/cppruntime/src/internal/*.cpp
    ${PROJECT_SOURCE_DIR}/cppruntime/src/misc/*.cpp
    ${PROJECT_SOURCE_DIR}/cppruntime/src/support/*.cpp
    ${PROJECT_SOURCE_DIR}/cppruntime/src/tree/*.cpp
    ${PROJECT_SOURCE_DIR}/cppruntime/src/tree/pattern/*.cpp
    ${PROJECT_SOURCE_DIR}/cppruntime/src/tree/xpath/*.cpp
)
add_library (antlr4-cpp-runtime ${antlr4-cpp-src})
add_executable(CPPparser ${src_dir} src/main.cpp)
target_link_libraries(CPPparser antlr4-cpp-runtime)

2. 目录结构

  • /src:存放main.cpp
  • /generated:存放通过antlr4 -Dlanguage=Cpp -visitor生成的文件
  • /cppruntime:存放官方ANTLR运行时

3. 编译命令

mkdir build && cd build
cmake ..
make

新版本编译错误信息

: error: expected class-name before ‘{’ token
   12 | class  CPP14Parser : public CPP14ParserBase {
      |                                             ^
/home/user/CPnew/generated/CPP14Parser.h:118:3: error: ‘CPP14Parser::~CPP14Parser()’ marked ‘override’, but does not override
  118 |   ~CPP14Parser() override;
      |   ^
/home/user/CPnew/generated/CPP14Parser.h:120:15: error: ‘std::string CPP14Parser::getGrammarFileName() const’ marked ‘override’, but does not override
  120 |   std::string getGrammarFileName() const override;
      |               ^~~~~~~~~~~~~~~~~~
/home/user/CPnew/generated/CPP14Parser.h:122:27: error: ‘const antlr4::atn::ATN& CPP14Parser::getATN() const’ marked ‘override’, but does not override
  122 |   const antlr4::atn::ATN& getATN() const override;
      |                           ^~~~~~
/home/user/CPnew/generated/CPP14Parser.h:124:35: error: ‘const std::vector<std::__cxx11::basic_string<char> >& CPP14Parser::getRuleNames() const’ marked ‘override’, but does not override
  124 |   const std::vector<std::string>& getRuleNames() const override;
      |                                   ^~~~~~~~~~~~
/home/user/CPnew/generated/CPP14Parser.h:126:34: error: ‘const antlr4::dfa::Vocabulary& CPP14Parser::getVocabulary() const’ marked ‘override’, but does not override
  126 |   const antlr4::dfa::Vocabulary& getVocabulary() const override;
      |                                  ^~~~~~~~~~~~~
/home/user/CPnew/generated/CPP14Parser.h:128:34: error: ‘antlr4::atn::SerializedATNView CPP14Parser::getSerializedATN() const’ marked ‘override’, but does not override
  128 |   antlr4::atn::SerializedATNView getSerializedATN() const override;
      |                                  ^~~~~~~~~~~~~~~~
/home/user/CPnew/generated/CPP14Parser.h:3895:8: error: ‘bool CPP14Parser::sempred(antlr4::RuleContext*, size_t, size_t)’ marked ‘override’, but does not override
 3895 |   bool sempred(antlr4::RuleContext *_localctx, size_t ruleIndex, size_t predicateIndex) override;
      |        ^~~~~~~
/home/user/CPnew/cppruntime/src/CPP14ParserBase.cpp:5:6: error: ‘CPP14ParserBase’ has not been declared
    5 | bool CPP14ParserBase::IsPureSpecifierAllowed()
      |      ^~~~~~~~~~~~~~~
/home/user/CPnew/cppruntime/src/CPP14ParserBase.cpp: In function ‘bool IsPureSpecifierAllowed()’:
/home/user/CPnew/cppruntime/src/CPP14ParserBase.cpp:9:18: error: invalid use of ‘this’ in non-member function
    9 |         auto x = this->getRuleContext(); // memberDeclarator
      |                  ^~~~

main.cpp代码

#include <iostream>
#include "CPP14Lexer.h"
#include "CPP14Parser.h"
using namespace antlr4;

int main(int argc, const char* argv[]) {
    const char* filepath = argv[1];
    std::ifstream ifs;
    ifs.open(filepath);
    ANTLRInputStream input(ifs);

    CPP14Lexer lexer(&input);
    CommonTokenStream tokens(&lexer);

    CPP14Parser parser(&tokens);
    tree::ParseTree* tree = parser.translationunit();

    if (parser.getNumberOfSyntaxErrors() > 0) {
        std::cout<<"File syntax error"<<std::endl;
        return 0;
    }

    tokens.fill();
    for (auto t : tokens.getTokens()) {
        std::cout<<t->toString()<<std::endl;
    }
    std::cout << tree->toStringTree(&parser) << std::endl << std::endl;


    ifs.close();
    return 0;
}

解决建议

  1. 匹配ANTLR版本:确保使用的语法文件(CPP14.g4等)与ANTLR运行时版本完全一致。最新版语法文件可能依赖了运行时的新特性或接口变更,旧版运行时不兼容。
  2. 正确生成代码:使用最新版ANTLR工具生成C++代码,命令应为antlr4 -Dlanguage=Cpp -visitor -no-listener CPP14.g4(根据需要调整参数),确保生成的代码与当前运行时匹配。
  3. 调整CMakeLists.txt:
    • 确保ANTLR运行时的头文件路径正确,最新版运行时的头文件可能位于cppruntime/include/antlr4-runtime/而非cppruntime/src/,需更新include_directories:
      include_directories(
          ${PROJECT_SOURCE_DIR}/generated/
          ${PROJECT_SOURCE_DIR}/cppruntime/include/
          ${PROJECT_SOURCE_DIR}/src/
      )
      
    • 链接运行时库时,优先使用官方提供的CMake配置,而非手动收集源文件。可以通过find_package(ANTLR REQUIRED)来导入官方运行时的CMake目标。
  4. 处理CPP14ParserBase依赖:错误提示CPP14ParserBase未声明,说明生成的代码中该基类的头文件未被正确包含,或生成时未生成该基类文件。检查语法文件中是否有parserBaseClass定义,确保生成代码时包含了基类的头文件,且该文件在generated目录中,CMake能正确找到。
  5. 检查C++标准:最新版ANTLR4 C运行时可能需要更高的C标准(如C++20),尝试将CMAKE_CXX_STANDARD设置为20。

内容的提问来源于stack exchange,提问作者EggDi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 12:54:57