0

再次快速提问。我正在创建一个递归函数,如果“源”规则类型与目标字符相同,它将在“源”规则数组中查找元素并将这些规则应用于规则“目标数组”。此外,该函数检查目标字符是否在符号数组中,如果不在则添加它(并且还在新应用的规则上抛出一些标志)。这一切都是由递归调用驱动的,该调用使用计数器来确定已经通过了多少次迭代,并用于确定目标数组中应该应用新规则的位置,因此我们不会覆盖。

我也加入了一些调试代码来显示结果。

这是函数本身:

//Recursively tack on any non terminal pointed elements 
int recursiveTack(rule * inrule[], char target, rule * targetrule[],
        int counter, char symbols[])
{

    printf("Got into recursiveTack\n");
    printf("target is %c\n", target);
    printf("counter is %d", counter);

    for (int k = 0; k < sizeof(inrule); k++)
    {

        if (inrule[k]->type == target)
        {

            //doublecheck to see if we're trying to overwrite
            if (targetrule[counter]->used = true)
            {
                counter++;
            }

            targetrule[counter]->head = inrule[k]->head;
            targetrule[counter]->type = inrule[k]->type;
            targetrule[counter]->used = true;

            //Check to see if the elements are new to the symbols table and need to be added
            if (!contains(returnGotoChar(targetrule[counter]), symbols))
            {

                //If not then add the new symbol
                addChar(returnGotoChar(targetrule[counter]), symbols);
                //Also set the goto status of the rule
                targetrule[counter]->needsGoto = true;
                //Also set the rule's currentGotoChar
                targetrule[counter]->currentGotoChar = returnGotoChar(
                        targetrule[counter]);
            }

            counter++;

            //recursivly add elements from non terminal nodes
            if (isNonTerm(targetrule[counter]))
            {
                char newTarget = returnGotoChar(targetrule[counter]);
                counter = recursiveTack(inrule, newTarget, targetrule, counter,
                        symbols);
            }
        }
    }

    //return how many elements we've added
    return counter;
}

这是电话:

if(isNonTerm(I[i+first][second]))
{
    printf("Confirmed non termainal\n");
    printf("Second being passed: %d\n", second);
    //Adds each nonterminal rule to the rules for the  I[i+first] array
    second = recursiveTack(I[i], targetSymbol, I[i+first], second, symbols[first]);
}

在此之前,所有传入的数组都已初始化。但是,我得到的输出表明递归在它开始之前在某处被杀死。

输出:

Second being passed: 0
Confirmed non termainal
Got into recursiveTack
target is E
Segmentation fault

任何帮助都会很棒,如果需要的话,我也可以使用该程序的其余部分,不过它大约有 700 行,包括注释。我很确定这只是缺少一些简单内容的另一种情况,但请告诉我您的想法。

4

3 回答 3

1
for(int k = 0; k < sizeof(inrule); k++)

sizeof(inrule)将返回指针类型(4 或 8)的大小。可能不是你想要的。如果要使用这些类型的结构,还需要将数组的大小作为参数传递。

不过,最好使用标准库容器std::vector,例如 .

于 2013-10-20T23:24:28.857 回答
0
if(targetrule[counter]->used = true){
 counter++;
  }

// 什么是 targetrule[counter] 实际上有效的保证?你能在它之前和之后做一个 printf 调试吗?

于 2013-10-20T23:15:34.123 回答
0

我在这里看到的最大的事情是:

for(int k = 0; k < sizeof(inrule); k++)

这不会像你想的那样。inrule 是一个指针数组,因此 sizeof(inrule) 将是元素数 * sizeof(rule*)。这可能很快导致您的阵列末端耗尽。

尝试将其更改为:

for (int k = 0; k < sizeof(inrule) / sizeof(rule*); ++k)

您可能会考虑的其他东西是 fflush(stdout); 在您的打印声明之后。您正在崩溃,而某些输出仍在缓冲中,因此它可能隐藏了您的崩溃发生的位置。

编辑:

那是行不通的。如果您有一个执行以下操作的函数:

int x[10];
for (int i = 0; i < sizeof(x) / sizeof(int); ++i) ...

它会起作用,但在函数调用的另一端,类型降级为 int*,并且 sizeof(int*) 与 sizeof(int[10]) 不同。您要么需要传递大小,要么......更好的是,使用向量而不是数组。

于 2013-10-20T23:35:30.180 回答