1 /* 2 * LR 转换表 3 * + Goto 记录表 4 * + 状态转换表 5 */ 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <string.h> 9 10 #include "Common.h" 11 #include "Closure.h" 12 #include "LRCal.h" 13 #include "LRMigrate.h" 14 15 extern char *Grammer[]; 16 extern char ***GrammerRule; 17 18 /* 19 * 创建Goto记录表 20 */ 21 struct Record *CreateRecordTable() 22 { 23 struct Record *RecordTable = (struct Record *)malloc(sizeof(struct Record)); 24 memset(RecordTable, '\0', sizeof(struct Record)); 25 RecordTable->RecordRow = -1; 26 RecordTable->RecordRowMax = 32; 27 RecordTable->Record = (int **)malloc(sizeof(int) * 32); 28 memset(RecordTable->Record, '\0', sizeof(int) * 32); 29 30 return RecordTable; 31 } 32 33 /* 34 * 记录 Goto[CCi, symbol]->CCj 35 * RecordTable : struct Record* 记录表 36 * CCi : int 当前项集 ID 37 * Symbol : unsigned char 转移符号 38 * CCj : int 转移目的项集 ID 39 */ 40 void Record(struct Record *RecordTable, int CCi, unsigned char Symbol, int CCj) 41 { 42 // [CCi, Symbol] -> CCj 43 if (RecordTable->RecordRow < CCi) // 新请求的位置大于最大项位,需要更新项位 44 { 45 // 一次分配 32 条记录空间 46 if (RecordTable->RecordRowMax <= CCi) // 新请求的位置超过最大可使用项数,追加新的项表空间 47 { 48 int NewSize = ((int)(CCi / 32) + 1) * 32; 49 int** NewRecordTable = (int**)malloc(NewSize * sizeof(int)); 50 memset(NewRecordTable, '\0', NewSize * sizeof(int)); 51 memcpy(NewRecordTable, RecordTable->Record, RecordTable->RecordRowMax * sizeof(int)); 52 RecordTable->RecordRowMax = NewSize; 53 RecordTable->Record = NewRecordTable; 54 } 55 RecordTable->RecordRow = CCi; 56 57 int *tmp_spc = (int*)malloc(sizeof(int) * 256); 58 memset(tmp_spc, '\0', sizeof(int) * 256); 59 RecordTable->Record[CCi] = tmp_spc; 60 } 61 if (RecordTable->Record[CCi][Symbol] == CCj) 62 { 63 // printf("Find Repeat.\n"); 64 } 65 else if (RecordTable->Record[CCi][Symbol] != 0) 66 { 67 printf("Find Conflict.\n"); 68 } 69 else 70 { 71 RecordTable->Record[CCi][Symbol] = CCj; 72 printf("[CC%d, %c] -> CC%d\n", CCi, Symbol, CCj); 73 } 74 } 75 76 /* 77 * 查找产生式序号 78 * s : unsigned char* 要查找的产生式 79 */ 80 int FindGrammer(unsigned char *s) 81 { 82 int i; 83 for (i = 0; Grammer[i][0] != '\0'; i++) 84 { 85 if (strcmp((char*)Grammer[i], (char*)s) == 0) 86 { 87 return i; 88 } 89 } 90 return -1; 91 } 92 93 /* 94 * 检查产生式是否为最终接受 95 * s : unsigned char* 要检查的产生式 96 */ 97 bool CheckIsAccept(unsigned char *s) 98 { 99 // 默认第一行语法产生式左非终结符为起始符号 100 int l = strlen((char*)s); 101 return (Grammer[0][0] == s[0] && s[l - 2] == SYM_PLACEHOLDER && s[l - 1] == SYM_EOF); 102 } 103 104 /* 105 * 添加转换项 106 * LRTable : struct LRElement** LR转换表 107 * StateID : int 状态ID 108 * Symbol : unsigned int 转换符号 109 * Action : enum ActionEnum 转换动作 110 * ActionValue : int 动作值 111 */ 112 void AddState(struct LRElement **LRTable, int StateID, unsigned int Symbol, enum ActionEnum Action, int ActionValue) 113 { 114 if (LRTable[StateID] != NULL) 115 { 116 // 不存在 None 和 Accept 参与的冲突 117 if (LRTable[StateID][Symbol].Action == None) 118 { 119 LRTable[StateID][Symbol].Action = Action; 120 LRTable[StateID][Symbol].ActionValue = ActionValue; 121 } 122 else if (!(LRTable[StateID][Symbol].Action == Action && LRTable[StateID][Symbol].ActionValue == ActionValue)) 123 { 124 int ConflictType = (int)(LRTable[StateID][Symbol].Action) + (int)Action; 125 switch (ConflictType) 126 { 127 case 3: // 移进-归约 128 printf("Found Shift-Reduce Conflicting.\n"); 129 if (Action == Shift) 130 { 131 LRTable[StateID][Symbol].Action = Action; 132 LRTable[StateID][Symbol].ActionValue = ActionValue; 133 } 134 break; 135 case 4: // 归约-归约 136 printf("Found Reduce-Reduce Conflicting.\n"); 137 break; 138 default: 139 printf("Found Undefined Conflicting.\n"); 140 break; 141 } 142 } 143 } 144 } 145 146 /* 147 * 通过生成的核心项集 CC 填充状态转移表 148 * CC : struct CoreCollection* 核心项集 149 * CoreCollectionCount : int 核心项集个数 150 * RecordTable : struct Record* Goto记录表 151 */ 152 struct LRElement **LRFillTable(struct CoreCollection *CC, int CoreCollectionCount, struct Record *RecordTable) 153 { 154 // 虽然 Action 表和 Goto 表的表项存在一定的差异,但是还是可以使用同一个结构体作为元素结构 155 // 因为每个核心项集生成一项 LR 转移项,所以 LR 转移表的项数和核心项集的个数是一样的 156 // Goto 表不会使用 Action 字段,因为 ActionValue 字段的值必须为正整数 157 struct LRElement **LRTable = (struct LRElement**)malloc(sizeof(int) * CoreCollectionCount); 158 int LRIndex = 0; 159 while (LRIndex < CoreCollectionCount) 160 { 161 LRTable[LRIndex] = (struct LRElement*)malloc(sizeof(struct LRElement) * 256); 162 memset(LRTable[LRIndex], '\0', sizeof(struct LRElement) * 256); 163 LRIndex++; 164 } 165 166 struct CoreCollection *CCPtr; 167 for (CCPtr = CC; CCPtr != NULL; CCPtr = CCPtr->next) // for each CCi∈CC 168 { 169 struct Collection *SPtr; 170 for (SPtr = CCPtr->S; SPtr != NULL; SPtr = SPtr->next) // for each item I∈CCi 171 { 172 unsigned char *Placeholder = (unsigned char*)strchr((char*)SPtr->Expression, SYM_PLACEHOLDER); 173 unsigned char PrevSymbol = *(Placeholder + 1); 174 175 if (*(Placeholder + 1) != '\0' && *(Placeholder + 2) != '\0' && 176 (PrevSymbol < 'A' || PrevSymbol > 'Z') && 177 RecordTable->RecordRow >= CCPtr->id && RecordTable->Record[CCPtr->id][PrevSymbol] != 0) // if I is [A -> β·cγ, α] and goto(CCi, c) = CCj then 178 { 179 // Action[i, c] <- "shift j" 180 AddState(LRTable, CCPtr->id, PrevSymbol, Shift, RecordTable->Record[CCPtr->id][PrevSymbol]); 181 } 182 else if (CheckIsAccept(SPtr->Expression) == true) // else if I is [S' -> S·, eof] then 183 { 184 // Action[i, eof] <- "accept" 185 AddState(LRTable, CCPtr->id, SYM_EOF, Accept, 0); 186 } 187 else if (*(Placeholder + 1) != '\0' && *(Placeholder + 2) == '\0') // else if I is [A -> β·, α] then 188 { 189 // Action[i, α] <- "reduce A -> β" 190 int i = 0; 191 unsigned char *SExpr = SPtr->Expression; 192 unsigned char *Expr = (unsigned char*)malloc(strlen((char*)SExpr)); 193 while (*SExpr != '\0') 194 { 195 if (*SExpr != SYM_PLACEHOLDER) 196 { 197 Expr[i++] = *SExpr; 198 } 199 SExpr++; 200 } 201 Expr[--i] = '\0'; 202 203 AddState(LRTable, CCPtr->id, PrevSymbol, Reduce, FindGrammer(Expr) + 1); 204 } 205 } 206 int NTPtr; 207 for (NTPtr = 0; NTPtr < 128; NTPtr++) 208 { 209 if (GrammerRule[NTPtr] != NULL) // for each n∈NT 210 { 211 if (RecordTable->Record[CCPtr->id] != NULL) // if goto(CCi, n) = CCj then 212 { 213 LRTable[CCPtr->id][NTPtr].ActionValue = RecordTable->Record[CCPtr->id][NTPtr]; // Goto[i, n] <- j 214 } 215 } 216 } 217 } 218 return LRTable; 219 } 220 221 /* 222 * 打印状态转移表 223 * LRMigrateTable : struct LRElement** LR状态转移表 224 * CoreCollectionCount : int 核心项集个数 225 */ 226 void PrintLRMigrate(struct LRElement **LRMigrateTable, int CoreCollectionCount) 227 { 228 // 为了方便压缩打印,将行链表转换为列链表 229 struct LRElement **LRCompression[256]; 230 int index, ItemPtr; 231 for (index = 0; index < 256; index++) 232 { 233 LRCompression[index] = NULL; 234 } 235 236 for (index = 0; index < CoreCollectionCount; index++) // 行 237 { 238 for (ItemPtr = 0; ItemPtr < 256; ItemPtr++) // 列 239 { 240 if (LRMigrateTable[index][ItemPtr].Action != None || LRMigrateTable[index][ItemPtr].ActionValue != 0) 241 { 242 if (LRCompression[ItemPtr] == NULL) // 如果该列自始自终没有任何表项,那么不创建该列的指针表 243 { 244 LRCompression[ItemPtr] = (struct LRElement**)malloc(sizeof(int) * CoreCollectionCount); 245 memset(LRCompression[ItemPtr], '\0', sizeof(int) * CoreCollectionCount); 246 } 247 LRCompression[ItemPtr][index] = &LRMigrateTable[index][ItemPtr]; 248 } 249 } 250 } 251 252 // 此时列表头若为 NULL 则该列无数据 253 printf("State"); 254 for (index = 0; index < 256; index++) 255 { 256 if (LRCompression[index] != NULL) 257 { 258 if (index != 255) 259 { 260 printf("\t%c", index); 261 } 262 else 263 { 264 printf("\t<eof>"); 265 } 266 } 267 } 268 printf("\n"); 269 for (index = 0; index < CoreCollectionCount; index++) 270 { 271 printf("%d", index); 272 for (ItemPtr = 0; ItemPtr < 256; ItemPtr++) 273 { 274 if (LRCompression[ItemPtr] != NULL) 275 { 276 if (LRCompression[ItemPtr][index] != NULL) 277 { 278 printf("\t"); 279 switch (LRCompression[ItemPtr][index]->Action) 280 { 281 case None: 282 // printf(""); 283 break; 284 case Shift: 285 printf("s"); 286 break; 287 case Reduce: 288 printf("r"); 289 break; 290 case Accept: 291 printf("acc"); 292 break; 293 } 294 if (LRCompression[ItemPtr][index]->Action != Accept) 295 { 296 printf("%d", LRCompression[ItemPtr][index]->ActionValue); 297 } 298 } 299 else 300 { 301 printf("\t"); 302 } 303 } 304 } 305 printf("\n"); 306 } 307 }
全部代码:https://files.cnblogs.com/rexfield/LR.7z