1 /*
  2  * 该程序用于计算某个项集的Goto集
  3  * RexfieldVon
  4  * 2013年8月11日2:34:50
  5  */
  6 #include <stdio.h>
  7 #include <stdlib.h>
  8 #include <string.h>
  9 
 10 #ifndef bool
 11 #    define bool char
 12 #endif
 13 
 14 #ifndef true
 15 #    define true 1
 16 #endif
 17 
 18 #ifndef false
 19 #    define false 0
 20 #endif
 21 
 22 struct Collection
 23 {
 24     char LeftUnterminal;        // 左非终结符
 25     char *Expression;            // 产生式
 26     char PreviewSymbol;            // 前瞻符号
 27     bool Processed;                // 是否被处理
 28     struct Collection *next;
 29 };
 30 /* 三级指针
 31  * 第一级指向整个产生式组
 32  * 第二级指向单个产生式
 33  * 第三级指向产生式符号单元
 34  * 约定:①所有的大写字母为非终结符②所有小写字母为终结符③'\377'为eof④'\0'为ε⑤'\376'为占位符·
 35  */
 36 char*** GrammerRule;
 37 /*
 38  * 文法书写约定:
 39  * 每个字符串表示一个单独的产生式
 40  * 第一个字符为产生式左边的非终结符,由初始化引擎进行产生式归并
 41  * 整个文法以 null 结束
 42  */
 43 char *Grammer[] =
 44 {
 45     "GL",
 46     "LLP", "LP",
 47     "P(P)", "P()",
 48     "\0"
 49 };
 50 /*
 51  * 初始化文法序列
 52  */
 53 void InitizationGrammerRule()
 54 {
 55     // 分配表头空间
 56     GrammerRule = (char***)malloc(sizeof(int) * 128);
 57     memset(GrammerRule, '\0', sizeof(int) * 128);
 58     // 扫描整个文法记录每个非终结符产生式的个数
 59     int UnterminalOp[127], index;
 60     char Unterminal;
 61     memset(UnterminalOp, '\0', 4 * 127);
 62     for (index = 0; (Unterminal = Grammer[index][0]) != '\0'; index++)
 63     {
 64         UnterminalOp[Unterminal]++;
 65     }
 66     // 写入产生式
 67     for (index = 0; (Unterminal = Grammer[index][0]) != '\0'; index++)
 68     {
 69         if(GrammerRule[Unterminal] == NULL)
 70         {
 71             GrammerRule[Unterminal] = (char**)malloc(sizeof(int) * (UnterminalOp[Unterminal] + 1));
 72             memset(GrammerRule[Unterminal], '\0', sizeof(int) * (UnterminalOp[Unterminal] + 1));
 73         }
 74         // 找到空位
 75         int blank = 0;
 76         while (GrammerRule[Unterminal][blank] != '\0') {blank++;}
 77         GrammerRule[Unterminal][blank] = &Grammer[index][1];
 78     }
 79 }
 80 
 81 /*
 82  * 取得终结符数量
 83  * return 终结符的数量
 84  */
 85 int GetTerminalCount()
 86 {
 87     int i, TerminalCount = 0;
 88     for (i = 0; i < 128; i++)
 89     {
 90         if (GrammerRule[i] != NULL)
 91         {
 92             int k = 0;
 93             while (GrammerRule[i][k] != NULL)
 94             {
 95                 int n = 0;
 96                 while (GrammerRule[i][k][n] != '\0')
 97                 {
 98                     char c = GrammerRule[i][k][n];
 99                     if (c < 'A' || c > 'Z')
100                     {
101                         TerminalCount++;
102                     }
103                     n++;
104                 }
105                 k++;
106             }
107         }
108     }
109     return TerminalCount;
110 }
111 
112 /*
113  * 递归取得 FIRST 集
114  * Token : char 需要打印的符号
115  * FIRST : char* FIRST集
116  * Ptr : int* FIRST集的位置指针
117  */
118 void GetFIRST(char Token, char *FIRST, int *Ptr)
119 {
120     if (Token >= 'A' && Token <= 'Z' && GrammerRule[Token] != NULL)
121     {
122         int i = 0;
123         while (GrammerRule[Token][i] != NULL)
124         {
125             GetFIRST(GrammerRule[Token][i++][0], FIRST, Ptr);
126         }
127     }
128     else if (Token < 'A' || Token > 'Z')
129     {
130         FIRST[*Ptr] = Token;
131         *Ptr = *Ptr + 1;
132     }
133 }
134 
135 /*
136  * 打印 LR(1) 项
137  * Item : struct Collection* 需要打印的项
138  */
139 void PrintItem(struct Collection *Item)
140 {
141     printf("[%c ->", Item->LeftUnterminal);
142     int i = 0;
143     for(; Item->Expression[i] != '\0'; i++)
144     {
145         printf(" ");
146         switch (Item->Expression[i])
147         {
148             case '\377':
149                 printf("<eof>");
150                 break;
151             case '\376':
152                 printf("<@>");
153                 break;
154             default:
155                 printf("%c", Item->Expression[i]);
156                 break;
157         }
158     }
159     if (Item->PreviewSymbol == '\377')
160     {
161         printf(", <eof>]\n");
162     }
163     else
164     {
165         printf(", %c]\n", Item->PreviewSymbol);
166     }
167 }
168 
169 /*
170  * 添加项到集合
171  * S : struct Collection* 项集
172  * Tail : struct Collection* 尾部指针
173  * LeftUnterminal : char 左非终结符
174  * Expression : char* 产生式
175  * PreviewSymbol : char 前瞻符号
176  */
177 void AddItem(struct Collection *S, struct Collection **Tail, char LeftUnterminal, char *Expression, char PreviewSymbol)
178 {
179     if (Tail == NULL) {Tail = (struct Collection **)malloc(sizeof(struct Collection **)); (*Tail) = NULL;}
180     if ((*Tail) == NULL) {(*Tail) = S;}
181     while ((*Tail)->next != NULL) {(*Tail) = (*Tail)->next;}
182     // 检查是否重复
183     struct Collection *SPtr = S;
184     for (; SPtr != NULL; SPtr = SPtr->next)
185     {
186         if (SPtr->LeftUnterminal == LeftUnterminal &&
187             SPtr->PreviewSymbol == PreviewSymbol &&
188             strcmp(SPtr->Expression, Expression) == 0)
189         {
190             return;
191         }
192     }
193     struct Collection *NewItem = (struct Collection*)malloc(sizeof(struct Collection));
194     NewItem->LeftUnterminal = LeftUnterminal;
195     NewItem->Expression = strdup(Expression);
196     NewItem->PreviewSymbol = PreviewSymbol;
197     NewItem->next = NULL;
198     NewItem->Processed = false;
199     (*Tail)->next = NewItem;
200     (*Tail) = (*Tail)->next;
201 }
202 
203 /*
204  * 闭包运算
205  * S : struct Collection* 项集
206  * TerminalCount : int 终结符个数
207  */
208 void Closure(struct Collection *S, int TerminalCount)
209 {
210     bool CollectChanged;
211     struct Collection *Ptr = S, *Tail = S;
212     do        // while (S is still changing)
213     {
214         CollectChanged = false;
215         while (Ptr != NULL)        // for each item [A->β·Cζ,α]∈S
216         {
217             char *Placeholder = strchr(Ptr->Expression, '\376');
218             if (Placeholder != NULL && *(Placeholder + 1) != '\0')        // 占位符不能在产生式尾
219             {
220                 char Unterminal = *(Placeholder + 1);
221                 if (Unterminal >= 'A' && Unterminal <= 'Z')
222                 {
223                     int ProductionIndex;
224                     for (ProductionIndex = 0; GrammerRule[Unterminal][ProductionIndex] != NULL; ProductionIndex++)    // for each production C->γ∈P
225                     {
226                         char *FIRST = (char*)malloc(TerminalCount + 1), FirstSymbol = *(Placeholder + 2);
227                         FirstSymbol = (FirstSymbol != '\0')? FirstSymbol : Ptr->PreviewSymbol;
228                         memset(FIRST, '\0', TerminalCount + 1);
229                         int FIRSTCount = 0, i;
230                         GetFIRST(FirstSymbol, FIRST, &FIRSTCount);
231                         for (i = 0; i < FIRSTCount; i++)        // for each b∈FIRST(ζα)
232                         {
233                             if (FIRST[i] != '\0')               // S <- S∪{[C->·γ,b]}
234                             {
235                                 char *Expr = (char*)malloc(2);
236                                 Expr[0] = '\376';
237                                 Expr[1] = '\0';
238                                 Expr = strcat(Expr, GrammerRule[Unterminal][ProductionIndex]);
239                                 AddItem(S, &Tail, Unterminal, Expr, FIRST[i]);
240                                 CollectChanged = true;
241                             }
242                         }
243                     }
244                 }
245             }
246             Ptr = Ptr->next;
247         }
248     }
249     while (CollectChanged == true);
250 }
251 
252 /*
253  * Goto 运算
254  * S : struct Collection* 项集
255  * Symbol : char 前瞻符号
256  * TerminalCount : int 终结符个数
257  */
258 struct Collection *Goto(struct Collection *S, char Symbol, int TerminalCount)
259 {
260     // moved <- 空集
261     struct Collection *Moved = (struct Collection*)malloc(sizeof(struct Collection));
262     memset(Moved, '\0', sizeof(struct Collection));
263     struct Collection *Tail = Moved;
264     while (S != NULL)    // for each item i∈S
265     {
266         char *Placeholder = strchr(S->Expression, '\376');
267         if (Placeholder != NULL && *(Placeholder + 1) == Symbol)    // if the form of i is [α->β·xζ,a] then
268         {
269             char *Expr = strdup(S->Expression);
270             Placeholder = strchr(Expr, '\376');
271             *Placeholder = Symbol;
272             *(Placeholder + 1) = '\376';
273             AddItem(Moved, &Tail, S->LeftUnterminal, Expr, S->PreviewSymbol);    // moved <- moved∪{[α->βx·ζ,a]}
274         }
275         S = S->next;
276     }
277     struct Collection *FreeNode = Moved;
278     Moved = Moved->next;
279     free(FreeNode);
280     Closure(Moved, TerminalCount);    // return closure(moved)
281     return Moved;
282 }
283 
284 int main(int argc, char **argv)
285 {
286     InitizationGrammerRule();    // 初始化文法
287     int TerminalCount = GetTerminalCount();
288     struct Collection *S = (struct Collection*)malloc(sizeof(struct Collection));
289     S->LeftUnterminal = 'G';
290     S->Expression = "\376L";
291     S->PreviewSymbol = '\377';
292     S->next = NULL;
293     S->Processed = false;
294     Closure(S, TerminalCount);
295     struct Collection *Moved = Goto(S, '(', TerminalCount);
296     while (Moved)
297     {
298         PrintItem(Moved);
299         Moved = Moved->next;
300     }
301     return 0;
302 }

 

posted on 2013-08-11 02:37  RexfieldVon  阅读(283)  评论(0编辑  收藏  举报