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 }