я использую antlr4 c ++.
у меня есть ParseTree
и я пытаюсь воссоздать древовидную структуру.
Для этого я использую посетитель my_Visitor
и мой собственный объект (ы) узла.
Моя проблема в том что visitChildren(tree::RuleNode*)
вызывает функции посещений всех дочерних элементов, поэтому я теряю информацию, когда обходится одно дочернее дерево и посещается следующее дочернее дерево.
Предположим, дерево выглядит так:
A
/ \
B C
Когда я звоню visitChildren(A)
(используя перегруженный visitExpression(ExpressionContext*)
функции для B и C), я могу извлечь информацию о том, что последовательность посещений A, B, C.
Эта последовательность также может быть результатом:
A
|
B
|
C
Чтобы воссоздать дерево, я думаю, что мне нужно что-то вроде
antlrcpp::Any my_Visitor::my_visitChildren(tree::RuleNode* A){
for(int i=0;i<A->children.size();i++){
//create a new node in my own tree representation as child of A
visit(A->children[i]);
}
}
и позвонить my_visitChildren
по моему перегружен visitExpression
функции.
Проблема здесь в том, что A->children[i]
это Tree
а также visit(.)
нужен ParseTree
,
Могу ли я как-то создать ParseTree
от children[i]
или есть лучший подход для этого?
Я также думаю об использовании карты из tree->parent
к моим объектам и просто присоедините мой новый узел там, но это не оптимально, если я хочу опустить некоторые узлы (например, для AST).
Различие между ParseTree
и Tree
является чисто искусственным и фактически бесполезным. Дочерние узлы дерева на самом деле все ParseTree
экземпляров. Есть несколько древовидных классов, которые никогда не используются во время выполнения, за исключением создания базовых классов ParseTree
, Следовательно, позже я удалил Tree
, SyntaxTree
а также RuleNode
и положить все это вместе в класс ParseTree.
Чтобы ответить на ваш вопрос: вы можете безопасно привести дочерние узлы к ParseTree
для твоей прогулки по дереву.
Других решений пока нет …