【发布时间】:2015-07-12 13:18:51
【问题描述】:
对于我的 C 编程课的最后一个项目,我们正在实现一个反向波兰符号计算器,它可以评估表达式的正确性、返回相应的中缀表达式或打印出模拟汇编代码。为此,我们将同时实现堆栈和抽象语法树。
struct snode /*stack data structure */
{
int datum;
struct snode* bottom;
};
struct tnode /*tree data structure */
{
int datum;
struct tnode* left;
struct tnode* right;
};
目前,我已将程序设计为从标准输入读取并将元素放入堆栈,然后使用该堆栈创建一个抽象语法树,稍后可用于评估表达式。目前,我还没有进行任何检查,我只是想先构建一个 AST。
下面是我的主要功能。目前,没有检查来确保给定的方程是正确的。
int i = 1;
struct snode *stack;
stack = push(stack, -999); /* Here I set what will be the "empty" value of my stack. There's better ways to do it, but this is how I did it for a previous lab and it tended to cause less issues for me when I check if my stack is empty at the end */
struct tnode *AST;
AST = (struct tnode*)malloc(sizeof(struct tnode));
AST->datum = -7062; /*same thing as with stack, this is just a place holder that will be over written. */
AST->right = NULL;
AST -> left = NULL;
struct tnode* tmp;
tmp = (struct tnode*)malloc(sizeof(struct tnode));
tmp -> datum = -7062;
tmp -> right = NULL;
tmp -> left = NULL;
/*Operators are given as letters instead of +,-, etc. */
char *addition = "A"
char *subtraction = "S";
char *multiplication = "X";
char *division = "D"
char *mod = "M";
while(argv[i] !=NULL){
if(isdigit(unsignedchar)argv[i][0])){
stack = push(stack, atol(argv[i]));
}else{ /* In the final code, a strcmp will check to see if argv[i] is one of the above A,S,X,D, or M arguments. For right now, it just fires if it's not a digit for my testing. */
if(AST->datum == -7062){ /*if this is the first time we're running it*/
AST->datum = atol(argv[i]);
AST->right = create_node(stack->datum);
stack = pop(stack);
AST -> left = create_node(stack->datum);
stack = pop(stack); /* I pop the top off the stack twice to get the 2 integers it stores. I know it will for the current testing, checks will be in place later */
}else{ /* if AST already has elements in it. */
tmp = AST;
tmp -> left = tmp-> right = NULL;
AST->datum = atol(argv[i]);
AST->right = create_node(stack->datum);
stack = pop(stack);
AST->left = tmp; /*This puts the new operator as the root of the tree, the old tree as the left child of that root, and the right child as the integer stored on stack.*/
}
}
i++;
}
print_table(AST); /*Should print the AST */
}
create_node 分配空间并存储分配给它的空间。
struct tnode*
create_node(int x){
struct tnode* tmp;
tmp = (struct tnode*)malloc(sizeof(struct tnode))
tmp->datum = x;
tmp->right = NULL;
tmp->left = NULL;
return tmp;
}
print_table 递归地打印抽象语法树。
void
print_table(struct tnode *AST){
if(AST !=NULL){
print_table(AST->left);
printf("%d ", AST->datum);
print_table(AST->right);
}
}
现在,如果给出以下内容:/rpcalc 5 4 A 然后程序将返回 5 0 4。我理解为什么 A 返回为 0,所以这部分按预期工作。 但是,当我尝试给程序 /rpcalc 5 4 A 3 X,即 (5+4)*3 时,它会冻结片刻,然后返回分段错误。
使用几个 printf 语句,我将问题隔离到 print_table 函数中的递归。由于某种原因,AST->left 似乎没有到达 NULL 指针来终止程序,导致它无限运行直到程序崩溃。我不确定是什么原因造成的,不幸的是,在我修复它之前,我无法继续我的项目......
【问题讨论】:
-
printf()-debugging 在 C 中不起作用。编译器可能会重新排序指令。 -
也许您忘记在某处设置指向
NULL的指针?在调试器中运行程序,并逐行逐行执行代码,看看它到底做了什么。
标签: c recursion stack abstract-syntax-tree