用于语言分析的二叉树实现-子节点:不起作用

时间:2018-08-15 15:53:54

标签: c++ parsing tree abstract-syntax-tree

我一直在尝试在C ++中实现AST,以存储从ML语言派生的数据,这是我的AST设法记录的一条指令:

var foo = 8;

词法分析器隔离标记,解析器推断它是一个变量声明,因此将其整体隔离:

foo = 8

由此可以轻松地构建临时AST:

    =  
  /   \
foo    8

但是我仍然无法处理子节点:

foo = 2 + 4

foo : integer = 2 + 4

那谁应该给这个呢?

         =      
       /   \    
      /     \   
     :       +  
    / \     / \ 
   /   \   2   4
 foo integer     

这是我的实现尝试:

*。hpp

enum NodeTypes { /* ... */ };

struct Node {
    token_t NodeValue;
    NodeTypes NodeType;
    Node *LeftChild = NULL;
    Node *RightChild = NULL;
    Node(token_t value, NodeTypes type);
    void InsertLeft(token_t NodeValue, NodeTypes NodeType = NOTHING);
    void InsertRight(token_t NodeValue, NodeTypes NodeType = NOTHING);
    void BrowseUp();
};

*。cpp

Node(token_t value, NodeTypes type) {
    NodeValue = value;
    NodeType = type;
}
void InsertLeft(token_t value, NodeTypes type) {
    if (LeftChild == NULL)
        LeftChild = new Node(value, type);
    else {
        Node NewNode = Node(value, type);
        NewNode.LeftChild = LeftChild;
        LeftChild = &NewNode;
    }
}
void InsertRight(token_t value, NodeTypes type) {
    if (RightChild == NULL)
        RightChild = new Node(value, type);
    else {
        Node NewNode = Node(value, type);
        NewNode.RightChild = RightChild;
        RightChild = &NewNode;
    }
}
void BrowseUp() {
    std::cout << NodeValue.value << " ";
    if (LeftChild) LeftChild->BrowseUp();
    if (RightChild) RightChild->BrowseUp();
}

使用它:

Node main = Node(NodePosition, NodeType);
SetMainAst(main, expr);
main.BrowseUp();

SetMainAst:

void SetMainAst(Node &node, Expr expr, NodeTypes type = NodeTypes::NOTHING) {
    std::array<Expr, 3> exp = CutExpr(expr, GetNodePosition(expr));
    Expr left = exp[0], right = exp[2];
    token_t value = exp[1][0];

    if (type == NOTHING) node.NodeValue = value;

    if (!ContainNodes(left)) node.InsertLeft(left[0]);
    else SetMainAst(node, left, DetermineFirstNode(expr));
    if (!ContainNodes(right)) node.InsertRight(right[0]);
    else SetMainAst(node, right, DetermineFirstNode(expr));
}

CutExpr()允许在3中剪切表达式。

  • 左值;
  • 节点;
  • 右值。

我用this帮助自己(它在python中,但是我用C ++转录了)。

使用单节点表达式,它可以产生奇迹。但是,当有多个节点时,它将不再起作用:BrowseUp()在显示主节点后停止程序(在这种情况下,即等号)。

我真的不明白,但是我很好地遵循了本教程,并认为我在C ++中的转录效果很好……也许是指针/引用问题?

如果您能帮助我解决这个问题(困扰我3天),我将不胜感激。

1 个答案:

答案 0 :(得分:3)

let columnMenuItems = document.querySelectorAll('.ag-menu-option');
document.addEventListener('keydown', e => {
  if (e.key === 'ArrowDown') {
    for (let i = 0; i < columnMenuItems.length; i++) {
      if (columnMenuItems[i].classList.contains('ag-menu-option-active') === true) {
        console.log("MENU OPTION SELECTED: ", columnMenuItems[i + 1])
        columnMenuItems[i].click();
        break;
      }
    }
  }
});

是错误的,因为您要存储一个将要销毁的对象的指针(退出 Node NewNode = Node(value, type); NewNode.LeftChild = LeftChild; LeftChild = &NewNode; 语句时)。

您可能想要这样的东西

if ... else

您正在从具有垃圾回收的Python转录到没有垃圾回收的C ++。因此,您必须自己添加内存管理。