LR(1)表生成算法演示程序

  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 }

全部代码:http://files.cnblogs.com/rexfield/LR.7z

你可能感兴趣的:(LR(1)表生成算法演示程序)