1 /*
  2  * 该程序用于计算某个产生式的闭包
  3  * RexfieldVon
  4  * 2013年8月9日16:01:38
  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  * LeftUnterminal : char 左非终结符
173  * Expression : char* 产生式
174  * PreviewSymbol : char 前瞻符号
175  */
176 void AddItem(struct Collection *S, char LeftUnterminal, char *Expression, char PreviewSymbol)
177 {
178     static struct Collection *Tail = NULL;
179     if (Tail == NULL) {Tail = S;}
180     while (Tail->next != NULL) {Tail = Tail->next;}
181     // 检查是否重复
182     struct Collection *SPtr = S;
183     for (; SPtr != NULL; SPtr = SPtr->next)
184     {
185         if (SPtr->LeftUnterminal == LeftUnterminal &&
186             SPtr->PreviewSymbol == PreviewSymbol &&
187             strcmp(SPtr->Expression, Expression) == 0)
188         {
189             return;
190         }
191     }
192     struct Collection *NewItem = (struct Collection*)malloc(sizeof(struct Collection));
193     NewItem->LeftUnterminal = LeftUnterminal;
194     NewItem->Expression = strdup(Expression);
195     NewItem->PreviewSymbol = PreviewSymbol;
196     NewItem->next = NULL;
197     NewItem->Processed = false;
198     Tail->next = NewItem;
199     Tail = Tail->next;
200 }
201 
202 /*
203  * 闭包运算
204  * S : struct Collection* 项集
205  * TerminalCount : int 终结符个数
206  */
207 void Closure(struct Collection *S, int TerminalCount)
208 {
209     bool CollectChanged;
210     struct Collection *Ptr = S;
211     do        // while (S is still changing)
212     {
213         CollectChanged = false;
214         while (Ptr != NULL)        // for each item [A->β·Cζ,α]∈S
215         {
216             PrintItem(Ptr);
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, 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 int main(int argc, char **argv)
253 {
254     InitizationGrammerRule();    // 初始化文法
255     int TerminalCount = GetTerminalCount();
256     struct Collection *S = (struct Collection*)malloc(sizeof(struct Collection));
257     S->LeftUnterminal = 'G';
258     S->Expression = "\376L";
259     S->PreviewSymbol = '\377';
260     S->next = NULL;
261     S->Processed = false;
262     Closure(S, TerminalCount);
263     return 0;
264 }

 

posted on 2013-08-10 23:33  RexfieldVon  阅读(1167)  评论(0编辑  收藏  举报