链接列表不通过递归调用传播

时间:2012-10-30 15:16:41

标签: c bison yacc

这个涉及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);
}

1 个答案:

答案 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数据结构而无需修改它。