这个涉及yacc,bison等问题的开销很大,它基本上构建了一个用于计算字符串的关键元素的解析树。但是,所有这一切都正常,我相当自信,问题在于一个唠叨的链表。
正如我所提到的,我正在使用各种“计算器”,但这个计算器应该接受已存储在链表中的变量。像(加1)这样的短语工作得很好,但是如果你尝试像((let(firstvar 2))(添加firstvar 4)那么棘手的部分现在,它应该通过一个符号列表(列表1)在这种情况下)并找到firstvar的值(在add语句之前创建,实例化并使用let语句分配)并将其放入链中。
所有这一切,问题是当我尝试将“symbolList”传递给各种操作数时,它会以奇怪和混乱的方式覆盖结构。
首先,来自.h的主要工会:
typedef struct
{
double value;
} NUMBER_AST_NODE;
typedef struct
{
char *name;
} SYMBOL_AST_NODE;
typedef struct
{
char *name;
struct ast_node *op1;
struct ast_node *op2;
} FUNCTION_AST_NODE;
typedef struct ast_symbol
{
char *name; //symbol name
struct ast_node *data;
struct ast_symbol *next;
struct ast_symbol *parent;
} AST_SYMBOL;
typedef struct ast_node
{
AST_NODE_TYPE type;
union
{
NUMBER_AST_NODE number;
FUNCTION_AST_NODE function;
SYMBOL_AST_NODE symbol;
} data;
AST_SYMBOL *symbolList;
} AST_NODE;
好的,现在,假设树已部分创建,问题是“symbolList”仅附加到树的最高成员...所以我需要将它传递给子项(即,操作数1和操作数2)以便它们可以访问symbolList,从而能够正确地转换传递给它们的函数的任何变量。
所以,我正在做这样的递归调用:
void translate(AST_NODE *p)
{
//recursive infix traversal.
if(p->type == NUM_TYPE){
printf("%6f",(double) p->data.number.value);
}
else if (p->type == SYM_TYPE){
resolveSymbol(p->symbolList, p->data.symbol.name); //this goes and finds the variable, and it does it correctly IF it has the symbolList!
}
else if(p->type == FUNC_TYPE){
printf("( ");
p->data.function.op1->symbolList = p->symbolList; //passing the symbolList onward
translate(p->data.function.op1);
printf( " %c ",resolveOp(resolvdfunc)); //ignore this, it's just displaying the char like '+' for add
p->data.function.op2->symbolList = p->symbolList; //passing the symbolList onward
translate(p->data.function.op2);
printf(" )");
}
}
if (!p)
return;
}
好的,所以,举例。假设我注释掉第二个操作数的symbolList传递。然后,像((let(a 2))(添加4))这样的语句就可以了。但是,显然,如果我尝试((let(a 2))(添加4 a))它将无法工作,因为第二个操作数无法访问'a'变量。
麻烦的是,目前,在没有注释掉第二个symbolList传递的情况下,它覆盖了我的第一个操作数,它再也无法访问symbolList了!
我希望这是有道理的......这让我疯了。
感谢。
编辑:9:22 - 这是resolveSymbol代码(根据要求)......
void resolveSymbol(AST_SYMBOL *p, char *name)
{
if (p == NULL)
yyerror("No such symbol exists");
else if (strcmp(p->name, name) == 0) {
translate(p->data);
}
else
resolveSymbol(p->next, name);
}
答案 0 :(得分:1)
可能没有连接到你的问题(但可能会让它更容易解决),将参数传递给递归函数作为参数通常更有意义,而不是将它们从未传输的数据结构中挂起:
void translate(AST_NODE *p, AST_SYMBOL *symbols) {
if(p->type == NUM_TYPE) {
printf("%6f",(double) p->data.number.value);
} else if (p->type == SYM_TYPE) {
resolveSymbol(symbols, p->data.symbol.name);
} else if(p->type == FUNC_TYPE) {
printf("( ");
translate(p->data.function.op1, symbols);
printf( " %c ", resolveOp(resolvdfunc)); //ignore this, it's just displaying the char like '+' for add
translate(p->data.function.op2, symbols);
printf(" )");
}
}
通过这个你可以完全摆脱symbolList字段,你可以遍历AST数据结构而无需修改它。