一开始,我为了偷懒将所有的任务全都压在了一个浮动指针上:
1 for (; CCPtr->S != NULL; CCPtr->S = CCPtr->S->next) // for each x following a · in an item in CCi 2 { 3 char *Placeholder = strchr(CCPtr->S->Expression, '\376'); 4 if (Placeholder != NULL && *(Placeholder + 1) != '\0') 5 { 6 unsigned char PrevSym = *(Placeholder + 1); 7 printf("Goto(CC%d, %c(%d)):\n", CCPtr->id, PrevSym, PrevSym); 8 struct Collection *temp = Goto(CCPtr->S, PrevSym, TerminalCount); // temp <- goto(CCi, x) 9 PrintCollections(temp); 10 int temp_id = AddCoreCollection(CC, &CCTail, temp, CCid); 11 if (temp_id > CCid) 12 { 13 CCid++; // 意味着新的 CCID 被分配 14 HadChanged = true; 15 } 16 // record transition form CCi to temp on X 17 Record(RecordTable, CCPtr->id, PrevSym, temp_id); 18 } 19 }
直到在计算两次Goto(CC0, L)的时候得到了不一样的结果,PrevSym:unsigned char 和 TerminalCount:int 显然没有任何问题,那么问题就出在 CCPtr->S 上,它在两次循环时不应该改变。然而 for 的第三条子句很明确的修改了这个指针指向的值 CCPtr->S = CCPtr->S->next。
也就是说我不应该修改CCPtr指向的内存空间,我创造了一个新的指针指向CCPtr->S:
1 struct Collection *ExprPtr = NULL; 2 for (ExprPtr = CCPtr->S; ExprPtr != NULL; ExprPtr = ExprPtr->next) // for each x following a · in an item in CCi 3 { 4 char *Placeholder = strchr(ExprPtr->Expression, '\376'); 5 if (Placeholder != NULL && *(Placeholder + 1) != '\0') 6 { 7 unsigned char PrevSym = *(Placeholder + 1); 8 printf("Goto(CC%d, %c(%d)):\n", CCPtr->id, PrevSym, PrevSym); 9 struct Collection *temp = Goto(CCPtr->S, PrevSym, TerminalCount); // temp <- goto(CCi, x) 10 PrintCollections(temp); 11 int temp_id = AddCoreCollection(CC, &CCTail, temp, CCid); 12 if (temp_id > CCid) 13 { 14 CCid++; // 意味着新的 CCID 被分配 15 HadChanged = true; 16 } 17 // record transition form CCi to temp on X 18 Record(RecordTable, CCPtr->id, PrevSym, temp_id); 19 } 20 }
很好,一切正常。
对于这个 for 语句块而言,CCPtr 指向的内存空间应该是一个 Constant 区域,这里由于偷懒省去一个临时变量导致一大片空间丢失了指向自己的指针。
我觉得我现在应该去检查所有的 for 语句了。