1 /*
  2  * 该程序用于计算某个非终结符的 FIRST+ 集合
  3  * RexfieldVon
  4  * 2013年6月30日16:02:47
  5  */
  6 #include <stdio.h>
  7 #include <stdlib.h>
  8 #include <string.h>
  9 
 10 /* 三级指针
 11  * 第一级指向整个产生式组
 12  * 第二级指向单个产生式
 13  * 第三级指向产生式符号单元
 14  * 约定:所有的大写字母为非终结符
 15  * 假设:无左递归、FIRST集中不会出现重复符号
 16  */
 17 char*** GrammerRule;
 18 
 19 /*
 20  * 初始化文法序列
 21  */
 22 void InitizationGrammerRule()
 23 {
 24     // 分配表头空间
 25     GrammerRule = (char***)malloc(sizeof(int) * 128);
 26     memset(GrammerRule, '\0', sizeof(int) * 128);
 27     // 分配文法空间并写入产生式
 28     // G -> E
 29     GrammerRule['G'] = (char**)malloc(sizeof(int) * 2);
 30     GrammerRule['G'][0] = (char*)malloc(2);
 31     memcpy(GrammerRule['G'][0], "E\0", 2);        // E
 32     GrammerRule['G'][1] = NULL;
 33     // E -> T F
 34     GrammerRule['E'] = (char**)malloc(sizeof(int) * 2);
 35     GrammerRule['E'][0] = (char*)malloc(3);
 36     memcpy(GrammerRule['E'][0], "TF\0", 3);        // T F
 37     GrammerRule['E'][1] = NULL;
 38     // F -> '+' T F | '-' T F | e
 39     GrammerRule['F'] = (char**)malloc(sizeof(int) * 4);
 40     GrammerRule['F'][0] = (char*)malloc(4);
 41     memcpy(GrammerRule['F'][0], "+TF\0", 4);    // '+' T F
 42     GrammerRule['F'][1] = (char*)malloc(4);
 43     memcpy(GrammerRule['F'][1], "-TF\0", 4);    // '-' T F
 44     GrammerRule['F'][2] = (char*)malloc(1);
 45     memcpy(GrammerRule['F'][2], "\0", 1);        // e (该产生式存在但是为空)
 46     GrammerRule['F'][3] = NULL;
 47     // T -> A U
 48     GrammerRule['T'] = (char**)malloc(sizeof(int) * 2);
 49     GrammerRule['T'][0] = (char*)malloc(3);
 50     memcpy(GrammerRule['T'][0], "AU\0", 3);        // A U
 51     GrammerRule['T'][1] = NULL;
 52     // U -> '*' A U | '/' A U | e
 53     GrammerRule['U'] = (char**)malloc(sizeof(int) * 4);
 54     GrammerRule['U'][0] = (char*)malloc(4);
 55     memcpy(GrammerRule['U'][0], "*AU\0", 4);    // '*' A U
 56     GrammerRule['U'][1] = (char*)malloc(4);
 57     memcpy(GrammerRule['U'][1], "/AU\0", 4);    // '/' A U
 58     GrammerRule['U'][2] = (char*)malloc(1);
 59     memcpy(GrammerRule['U'][2], "\0", 1);        // e (该产生式存在但是为空)
 60     GrammerRule['U'][3] = NULL;
 61     // A -> '(' E ')' | d | n
 62     GrammerRule['A'] = (char**)malloc(sizeof(int) * 4);
 63     GrammerRule['A'][0] = (char*)malloc(4);
 64     memcpy(GrammerRule['A'][0], "(E)\0", 4);    // '(' E ')'
 65     GrammerRule['A'][1] = (char*)malloc(2);
 66     memcpy(GrammerRule['A'][1], "d\0", 2);        // d
 67     GrammerRule['A'][2] = (char*)malloc(2);
 68     memcpy(GrammerRule['A'][2], "n\0", 2);        // n
 69     GrammerRule['A'][3] = NULL;
 70 }
 71 
 72 /*
 73  * 取得终结符数量
 74  */
 75 int GetTerminalCount()
 76 {
 77     int i, TerminalCount = 0;
 78     for (i = 0; i < 128; i++)
 79     {
 80         if (GrammerRule[i] != NULL)
 81         {
 82             int k = 0;
 83             while (GrammerRule[i][k] != NULL)
 84             {
 85                 int n = 0;
 86                 while (GrammerRule[i][k][n] != '\0')
 87                 {
 88                     char c = GrammerRule[i][k][n];
 89                     if (c < 'A' || c > 'Z')
 90                     {
 91                         TerminalCount++;
 92                     }
 93                     n++;
 94                 }
 95                 k++;
 96             }
 97         }
 98     }
 99     return TerminalCount;
100 }
101 
102 /*
103  * 递归取得 FIRST 集
104  * Token : char 需要打印的符号
105  * FIRST : char* FIRST集
106  * Ptr : int* FIRST集的位置指针
107  */
108 void GetFIRST(char Token, char *FIRST, int *Ptr)
109 {
110     if (Token >= 'A' && Token <= 'Z' && GrammerRule[Token] != NULL)
111     {
112         int i = 0;
113         while (GrammerRule[Token][i] != NULL)
114         {
115             GetFIRST(GrammerRule[Token][i++][0], FIRST, Ptr);
116         }
117     }
118     else if (Token < 'A' || Token > 'Z')
119     {
120         FIRST[*Ptr] = Token;
121         *Ptr = *Ptr + 1;
122     }
123 }
124 
125 /*
126  * 添加符号到 FOLLOW 集
127  * FOLLOW : char* FOLLOW集
128  * Ptr : int* FOLLOW集的位置指针
129  * NewItem : char 将加入的符号
130  */
131 void AddFOLLOWItem(char *FOLLOW, int *Ptr, char NewItem)
132 {
133     int i = 0;
134     for (; i < *Ptr; i++)
135     {
136         if (FOLLOW[i] == NewItem)
137         {
138             return ;
139         }
140     }
141     FOLLOW[*Ptr] = NewItem;
142     *Ptr = *Ptr + 1;
143 }
144 
145 /*
146  * 取得 FOLLOW 集
147  * Unterminal : char 需要打印的非终结符
148  * FOLLOW : char* FOLLOW集
149  * Ptr : int* FOLLOW集的位置指针
150  * TerminalCount : int 终结符数量
151  */
152 void GetFOLLOW(char Unterminal, char *FOLLOW, int *Ptr, int TerminalCount)
153 {
154     int RuleIndex, ExprIndex, TokenIndex;
155     // 开始遍历整个文法
156     for (RuleIndex = 0; RuleIndex < 128; RuleIndex++)
157     {
158         if (GrammerRule[RuleIndex] == NULL)
159         {
160             continue;
161         }
162         // 搜索整个文法找到指定的非终结符
163         for (ExprIndex = 0; GrammerRule[RuleIndex][ExprIndex] != 0; ExprIndex++)
164         {
165             for (TokenIndex = 0; GrammerRule[RuleIndex][ExprIndex][TokenIndex] != '\0'; TokenIndex++)
166             {
167                 if (GrammerRule[RuleIndex][ExprIndex][TokenIndex] == Unterminal)
168                 {
169                     char nc = GrammerRule[RuleIndex][ExprIndex][TokenIndex + 1];
170                     if (nc == '\0' && RuleIndex != Unterminal)        // 情形三:反复计算:将FOLLOW(P)加入FOLLOW(U)
171                     {
172                         GetFOLLOW((char)RuleIndex, FOLLOW, Ptr, TerminalCount);
173                     }
174                     else if (nc >= 'A' && nc <= 'Z')    // 情形二:间接计算:将FIRST(P)加入FOLLOW(U)
175                     {
176                         char *FIRST = (char*)malloc(TerminalCount + 1);
177                         memset(FIRST, '\0', TerminalCount + 1);
178                         int FIRSTPtr = 0, InsertPtr;
179                         GetFIRST(nc, FIRST, &FIRSTPtr);
180                         for (InsertPtr = 0; InsertPtr < FIRSTPtr; InsertPtr++)
181                         {
182                             if (FIRST[InsertPtr] != '\0')
183                             {
184                                 AddFOLLOWItem(FOLLOW, Ptr, FIRST[InsertPtr]);
185                             }
186                             else    // 对于 P->... U B,FOLLOW ← FIRST(B) - <e> + FOLLOW(P)
187                             {
188                                 GetFOLLOW((char)RuleIndex, FOLLOW, Ptr, TerminalCount);
189                             }
190                         }
191                     }
192                     else if (nc != '\0')    // 情形一:直接计算:将终结符加入FOLLOW(U)
193                     {
194                         AddFOLLOWItem(FOLLOW, Ptr, nc);
195                     }
196                 }
197             }
198         }
199     }
200 }
201 
202 void GetFIRSTPlus(char Unterminal, int Index, char *FIRSTPlus, int *Ptr, int TerminalCount)
203 {
204     if (GrammerRule[Unterminal][Index] != NULL)
205     {
206         GetFIRST(GrammerRule[Unterminal][Index][0], FIRSTPlus, Ptr);
207         int i = 0;
208         while (i < *Ptr)
209         {
210             if (FIRSTPlus[i++] == '\0')
211             {
212                 FIRSTPlus[*Ptr] = '\377';
213                 *Ptr = *Ptr + 1;
214                 GetFOLLOW(Unterminal, FIRSTPlus, Ptr, TerminalCount);
215                 break;
216             }
217         }
218     }
219 }
220 
221 /*
222  * 打印指定非终结符的 FIRST+ 集
223  * Unterminal : char 需要打印的非终结符
224  * TerminalCount : int 终结符数量
225  */
226 void PrintUnterminalFIRSTPlus(char Unterminal, int TerminalCount)
227 {
228     char *FIRSTPlus = (char*)malloc(TerminalCount + 1);
229     memset(FIRSTPlus, '\0', TerminalCount + 1);
230     int Ptr, Index = 0, i;
231     for (; GrammerRule[Unterminal][Index] != NULL; Index++)
232     {
233         Ptr = 0;
234         GetFIRSTPlus(Unterminal, Index, FIRSTPlus, &Ptr, TerminalCount);
235         printf("FIRST+(%c, %c): ", Unterminal, GrammerRule[Unterminal][Index][0]);
236         for (i = 0; i < Ptr; i++)
237         {
238             if (FIRSTPlus[i] == '\377')
239             {
240                 printf("<eof> ");
241             }
242             else if (FIRSTPlus[i] == '\0')
243             {
244                 printf("<e> ");
245             }
246             else
247             {
248                 printf("%c ", FIRSTPlus[i]);
249             }
250         }
251         printf("\n");
252     }
253 }
254 
255 int main(int argc, char **argv)
256 {
257     InitizationGrammerRule();    // 初始化文法
258     int TerminalCount = GetTerminalCount();
259     PrintUnterminalFIRSTPlus('E', TerminalCount);
260     PrintUnterminalFIRSTPlus('F', TerminalCount);
261     PrintUnterminalFIRSTPlus('T', TerminalCount);
262     PrintUnterminalFIRSTPlus('U', TerminalCount);
263     PrintUnterminalFIRSTPlus('A', TerminalCount);
264     return 0;
265 }

 

posted on 2013-07-03 23:26  RexfieldVon  阅读(337)  评论(0编辑  收藏  举报