1 /*
  2  * 该程序用于计算某个非终结符的 FOLLOW 集合
  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 /*
203  * 打印指定非终结符的 FOLLOW 集
204  * Unterminal : char 需要打印的非终结符
205  * TerminalCount : int 终结符数量
206  */
207 void PrintUnterminalFOLLOW(char Unterminal, int TerminalCount)
208 {
209     char *FOLLOW = (char*)malloc(TerminalCount + 1);
210     memset(FOLLOW, '\0', TerminalCount + 1);
211     int Ptr = 0, i;
212     FOLLOW[Ptr++] = '\377';        // 初始化第一个符号为 EOF
213     GetFOLLOW(Unterminal, FOLLOW, &Ptr, TerminalCount);
214     printf("FOLLOW(%c): ", Unterminal);
215     for (i = 0; i < Ptr; i++)
216     {
217         if (FOLLOW[i] == '\377')
218         {
219             printf("<eof> ");
220         }
221         else
222         {
223             printf("%c ", FOLLOW[i]);
224         }
225     }
226     printf("\n");
227 }
228 
229 int main(int argc, char **argv)
230 {
231     InitizationGrammerRule();    // 初始化文法
232     int TerminalCount = GetTerminalCount();
233     PrintUnterminalFOLLOW('E', TerminalCount);
234     PrintUnterminalFOLLOW('F', TerminalCount);
235     PrintUnterminalFOLLOW('T', TerminalCount);
236     PrintUnterminalFOLLOW('U', TerminalCount);
237     PrintUnterminalFOLLOW('A', TerminalCount);
238     return 0;
239 }

 

posted on 2013-06-30 22:03  RexfieldVon  阅读(498)  评论(0编辑  收藏  举报