3

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

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);
}

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

我会很感激在编程(代码)方面的启发。

4

3 回答 3

8

您创建节点的代码对我来说看起来不错。问题是您需要代码来弄清楚如何正确构建二叉树。您不能只将节点粘贴到找到 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

于 2012-06-13T23:25:17.780 回答
2

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

于 2012-06-14T07:12:24.750 回答
0

有关 C++ 实现的信息,请参见这些链接

  1. 后缀解析器的中缀
  2. 二叉表达式树解析器的中缀

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

于 2012-12-18T14:38:49.680 回答