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 }