【问题标题】:Parser tree or expression tree解析器树或表达式树
【发布时间】:2012-06-13 23:16:54
【问题描述】:

我在做一个命令行计算器,所以我需要解析表达式。

calc 2*(3+4)*5

我已经完成了扫描步骤,返回了一个令牌的数组。 现在我处于解析器步骤。但是我不知道如何做一个解析器/表达式树。

这就是我目前所拥有的:

NODE* create_node(TOKEN* t) {
    NODE* n = (NODE*)malloc(sizeof(NODE));
    n->t = t;
    n->l = n->r = 0;
    return n;
}

void insert_node(NODE** top, NODE** n) {
    if (!*top) {
        *top = *n;
        return;
    }

    if (!(*top)->l) insert_node(&(*top)->l, n);
    else
    if (!(*top)->r) insert_node(&(*top)->r, n);
    else
        insert_node(&(*top)->l, n);
}

然后我像这样传递令牌数组:

while (*tokens != 0) {
    NODE* n = create_node(*tokens++);
    insert_node(&root, &n);
}

如您所见,我的树向左升起。我不知道如何让它按顶部的运算符排序,并将数字作为叶子,包括运算符的优先顺序。

我希望能得到启发,在编程(代码)方面也是如此。

【问题讨论】:

    标签: c parsing expression-trees


    【解决方案1】:

    您创建节点的代码对我来说看起来不错。问题是您需要代码来弄清楚如何正确构建二叉树。你不能在任何找到 NULL 指针的地方粘贴一个节点。

    您的示例表达式:2*(3+4)*5

    会变成这样的:

        *
       / \
      *   5
     / \
    2   +
       / \
      3   4
    

    你的老师应该给你一些想法如何做到这一点。

    在我上大学的时候,我编写了这种代码,并且我们编写了自己的“递归下降解析器”。另一种流行的方法是使用像 GNU Bison 这样的系统。

    你应该复习你的笔记,看看老师是怎么说的,如果你真的不知道,问问老师。

    http://en.wikipedia.org/wiki/Recursive_descent_parser

    http://en.wikipedia.org/wiki/GNU_bison

    【讨论】:

    • +1。另外,看看你关于编程和数据结构的教科书对这个问题的看法,它真的应该在那里。
    【解决方案2】:

    @Fabricio:提示。尝试将您的输入(中缀表达式)转换为后缀或前缀表达式。在转换它们时将令牌推入堆栈。弹出每个元组(一个运算符和两个操作数)评估并将结果压入堆栈。重复直到堆栈为空。您可以在输入表达式中添加冗余大括号,以便轻松强制执行运算符优先级(但要付出一些代价,否则您将不得不说服您的教授 :))。

    【讨论】:

      【解决方案3】:

      查看这些链接以了解 C++ 的实现

      1. An infix to postfix parser
      2. An infix to binary-expression-tree parser

      如前所述,两种实现都使用堆栈。对于二叉树的中缀,使用了两个栈,一个用于操作符,一个用于操作数。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-09-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-13
        • 2018-03-11
        相关资源
        最近更新 更多