gpt4 book ai didi

c - 链表不通过递归调用传播

转载 作者:行者123 更新时间:2023-12-05 01:17:02 26 4
gpt4 key购买 nike

这个涉及 yacc、bison 等的问题有很多开销,本质上是构建一个用于计算字符串的关键元素的解析树。但是,所有这些都正常工作,我相当有信心,问题出在一个烦人的链表上。

正如我提到的,我正在使用某种“计算器”,但这个计算器应该接受存储在链表中的变量。像 (add 1 4) 这样的短语工作得很好,但棘手的部分是如果你尝试像 ((let (firstvar 2)) (add firstvar 4)) 现在,它应该通过一个符号列表(一个列表 1在这种情况下)并找到 firstvar 的值(在 add 语句之前使用 let 语句创建、实例化和赋值)并将其放入链中。

总而言之,问题是当我尝试将“symbolList”向下传递给各种操作数时,它会以奇怪且令人困惑的方式覆盖结构。

首先,来自 .h 的主要 union :

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)) (add a 4)) 这样的语句就可以正常工作了。但是,显然,如果我尝试 ((let (a 2)) (add 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);
}

最佳答案

可能与您的问题无关(但可能更容易解决),通常将参数作为参数传递给递归函数比将它们卡在不相关的数据结构中更有意义:

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 数据结构。

关于c - 链表不通过递归调用传播,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13142077/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com