私はANTLR4で式を解析しようとしています。そのため私はビジターパターンを使用しており、抽象構文ツリーを作成しています。このstd :: bad_castをantlrcpp :: Anyからどのように解決すればよいですか?
結果は式など(この例のコードから削除したもの)にすることができます。訪問者は戻りタイプがantlrcpp::Any
であるため、抽象構文ツリーの要素はantlrcpp::Any
に変換されます。
antlrcpp::Any
からstd::shared_ptr<Expression>
に結果を変換しようとしている場合、私はstd::bad_cast
を取得しています。
#include <iostream>
#include <string>
#include <memory>
#include "antlr4-runtime.h"
#include "Parser/SimpleLangLexer.h"
#include "Parser/SimpleLangParser.h"
#include "Parser/SimpleLangBaseVisitor.h"
struct Expression;
struct Node {
virtual ~Node() { }
};
struct Expression: public Node {
int constValue;
Expression(int constValue) : constValue(constValue) { }
virtual ~Expression() override { }
};
struct AstVisitor: public SimpleLangBaseVisitor {
virtual antlrcpp::Any visitTopLevelElement(SimpleLangParser::TopLevelElementContext *ctx) override {
std::shared_ptr<Expression> expression = ctx->expression()->accept(this);
return std::dynamic_pointer_cast<Node>(expression);
}
virtual antlrcpp::Any visitIntExpr(SimpleLangParser::IntExprContext *ctx) override {
std::string strInteger = ctx->INTEGER()->getSymbol()->getText();
int constValue = std::stoi(strInteger);
auto intExpr = std::make_shared<Expression>(constValue);
return intExpr;
}
};
int main() {
std::string line = "123;";
antlr4::ANTLRInputStream input(line);
SimpleLangLexer lexer(&input);
antlr4::CommonTokenStream tokens(&lexer);
SimpleLangParser parser(&tokens);
antlr4::tree::ParseTree *tree = parser.start();
// Prints:
// > (start (topLevelElement (expression 123) ;) <EOF>)
std::cout << std::endl << tree->toStringTree(&parser) << std::endl;
AstVisitor astVisitor;
antlrcpp::Any result = tree->accept(&astVisitor);
// Prints:
// > Dn
// std::cout << result.get_typeinfo().name() << std::endl;
// Error:
// > terminate called after throwing an instance of 'std::bad_cast'
// what(): std::bad_cast
std::shared_ptr<Node> node = result;
std::shared_ptr<Expression> iexpr = std::dynamic_pointer_cast<Expression>(node);
// Expected:
// > 123
std::cout << iexpr->constValue << std::endl;
return 0;
}
Implementation of antlrcpp::Any
私の文法:
grammar SimpleLang;
start
: topLevelElement* EOF
;
topLevelElement
: expression ';'
;
expression
: IDENTIFIER #identifierExpr
| INTEGER #intExpr
;
IDENTIFIER
: [_a-zA-Z][_a-zA-Z0-9]*
;
INTEGER
: [0-9]+
;
WS: [ \r\n\t] -> skip;
注:私は非常にこの質問のための私のコードを削減し、私はそれはまだ感じるになりたいと考えています。ここ
すばやくお返事ありがとうございます!私は私の質問を編集しました。 'std :: bad_cast'は' std :: shared_ptr node = result; 'という行にスローされます。私はローカルコピーをAnyに再構築します。しかし、私はタイプ名 'Dn'が意味するものを見つけることができません。 –
dotjpg3141
@ JP3141 http://coliru.stacked-crooked.com/a/2e6451847ce85e93(nullptr)。 – Yakk
ありがとう! 'result.isNull()'は 'true'を返します。 – dotjpg3141