基于ANTLR Visitor模式:如何将antlrcpp::Any转为std::string?
把ANTLR Visitor返回的antlrcpp::Any转为std::string的实用方案
嘿,我之前做ANTLR翻译器的时候也碰到过这个问题,给你两个靠谱的解决思路:
1. 直接使用as<std::string>()方法
这是最直接的方式,只要你确保Visitor返回的antlrcpp::Any内部确实包裹着std::string,就可以直接调用as()方法提取出来。结合你的代码片段,修改后的完整逻辑大概是这样:
ANTLRInputStream input(in_stream); QwertyLexer lexer(&input); CommonTokenStream tokens(&lexer); QwertyParser parser(&tokens); QwertyParserBaseVisitorImpl visitor; // 调用Visitor的入口规则(这里要替换成你语法里的实际入口,比如parser.program()) auto visitorResult = visitor.visit(parser.program()); // 转换为std::string std::string translatedCpp = visitorResult.as<std::string>(); // 写入文件 std::ofstream outputFile("generated_code.cpp"); if (outputFile.is_open()) { outputFile << translatedCpp; outputFile.close(); }
需要注意的是:如果antlrcpp::Any里存储的不是std::string,调用as()会抛出异常,所以一定要保证你实现的所有visitXXX方法返回的都是包裹着字符串的antlrcpp::Any,比如:
antlrcpp::Any QwertyParserBaseVisitorImpl::visitVariableDef(QwertyParser::VariableDefContext *ctx) override { // 生成对应的C++变量定义代码 std::string cppCode = "int " + ctx->IDENTIFIER()->getText() + ";"; return antlrcpp::Any(cppCode); }
2. 先检查类型再转换(更安全)
如果担心某些场景下返回类型不匹配,可以先调用is<std::string>()做类型检查,避免异常:
auto visitorResult = visitor.visit(parser.program()); std::string translatedCpp; if (visitorResult.is<std::string>()) { translatedCpp = visitorResult.as<std::string>(); // 写入文件逻辑 } else { // 处理类型错误,比如打印日志或者抛出自定义异常 std::cerr << "Error: Visitor返回的结果不是std::string类型" << std::endl; return 1; // 或者其他错误处理逻辑 }
这样就能安全地把翻译后的C++代码字符串提取出来,然后写入文件啦。
内容的提问来源于stack exchange,提问作者Марк Логвинович
相关产品推荐
相关产品推荐

