1 /*
  2  * 该程序用于计算某个非终结符的 FIRST 集合
  3  * RexfieldVon
  4  * 2013年6月29日19:53:45
  5  * 2013年7月3日22:01:57 修改 GetFIRST 例程以简化驱动例程以及自身结构
  6  */
  7 #include <stdio.h>
  8 #include <stdlib.h>
  9 #include <string.h>
 10 
 11 /* 三级指针
 12  * 第一级指向整个产生式组
 13  * 第二级指向单个产生式
 14  * 第三级指向产生式符号单元
 15  * 约定:所有的大写字母为非终结符
 16  * 假设:无左递归、FIRST集中不会出现重复符号
 17  */
 18 char*** GrammerRule;
 19 
 20 /*
 21  * 初始化文法序列
 22  */
 23 void InitizationGrammerRule()
 24 {
 25     // 分配表头空间
 26     GrammerRule = (char***)malloc(sizeof(int) * 128);
 27     memset(GrammerRule, '\0', sizeof(int) * 128);
 28     // 分配文法空间并写入产生式
 29     // G -> E
 30     GrammerRule['G'] = (char**)malloc(sizeof(int) * 2);
 31     GrammerRule['G'][0] = (char*)malloc(2);
 32     memcpy(GrammerRule['G'][0], "E\0", 2);        // E
 33     GrammerRule['G'][1] = NULL;
 34     // E -> T F
 35     GrammerRule['E'] = (char**)malloc(sizeof(int) * 2);
 36     GrammerRule['E'][0] = (char*)malloc(3);
 37     memcpy(GrammerRule['E'][0], "TF\0", 3);        // T F
 38     GrammerRule['E'][1] = NULL;
 39     // F -> '+' T F | '-' T F | e
 40     GrammerRule['F'] = (char**)malloc(sizeof(int) * 4);
 41     GrammerRule['F'][0] = (char*)malloc(4);
 42     memcpy(GrammerRule['F'][0], "+TF\0", 4);    // '+' T F
 43     GrammerRule['F'][1] = (char*)malloc(4);
 44     memcpy(GrammerRule['F'][1], "-TF\0", 4);    // '-' T F
 45     GrammerRule['F'][2] = (char*)malloc(1);
 46     memcpy(GrammerRule['F'][2], "\0", 1);        // e (该产生式存在但是为空)
 47     GrammerRule['F'][3] = NULL;
 48     // T -> A U
 49     GrammerRule['T'] = (char**)malloc(sizeof(int) * 2);
 50     GrammerRule['T'][0] = (char*)malloc(3);
 51     memcpy(GrammerRule['T'][0], "AU\0", 3);        // A U
 52     GrammerRule['T'][1] = NULL;
 53     // U -> '*' A U | '/' A U | e
 54     GrammerRule['U'] = (char**)malloc(sizeof(int) * 4);
 55     GrammerRule['U'][0] = (char*)malloc(4);
 56     memcpy(GrammerRule['U'][0], "*AU\0", 4);    // '*' A U
 57     GrammerRule['U'][1] = (char*)malloc(4);
 58     memcpy(GrammerRule['U'][1], "/AU\0", 4);    // '/' A U
 59     GrammerRule['U'][2] = (char*)malloc(1);
 60     memcpy(GrammerRule['U'][2], "\0", 1);        // e (该产生式存在但是为空)
 61     GrammerRule['U'][3] = NULL;
 62     // A -> '(' E ')' | d | n
 63     GrammerRule['A'] = (char**)malloc(sizeof(int) * 4);
 64     GrammerRule['A'][0] = (char*)malloc(4);
 65     memcpy(GrammerRule['A'][0], "(E)\0", 4);    // '(' E ')'
 66     GrammerRule['A'][1] = (char*)malloc(2);
 67     memcpy(GrammerRule['A'][1], "d\0", 2);        // d
 68     GrammerRule['A'][2] = (char*)malloc(2);
 69     memcpy(GrammerRule['A'][2], "n\0", 2);        // n
 70     GrammerRule['A'][3] = NULL;
 71 }
 72 
 73 int GetTerminalCount()
 74 {
 75     int i, TerminalCount = 0;
 76     for (i = 0; i < 128; i++)
 77     {
 78         if (GrammerRule[i] != NULL)
 79         {
 80             int k = 0;
 81             while (GrammerRule[i][k] != NULL)
 82             {
 83                 int n = 0;
 84                 while (GrammerRule[i][k][n] != '\0')
 85                 {
 86                     char c = GrammerRule[i][k][n];
 87                     if (c < 'A' || c > 'Z')
 88                     {
 89                         TerminalCount++;
 90                     }
 91                     n++;
 92                 }
 93                 k++;
 94             }
 95         }
 96     }
 97     return TerminalCount;
 98 }
 99 
100 /*
101  * 递归取得 FIRST 集
102  * Token : char 需要打印的符号
103  * FIRST : char* FIRST集
104  * Ptr : int* FIRST集的位置指针
105  */
106 void GetFIRST(char Token, char *FIRST, int *Ptr)
107 {
108     if (Token >= 'A' && Token <= 'Z' && GrammerRule[Token] != NULL)
109     {
110         int i = 0;
111         while (GrammerRule[Token][i] != NULL)
112         {
113             GetFIRST(GrammerRule[Token][i++][0], FIRST, Ptr);
114         }
115     }
116     else if (Token < 'A' || Token > 'Z')
117     {
118         FIRST[*Ptr] = Token;
119         *Ptr = *Ptr + 1;
120     }
121 }
122 
123 /*
124  * 打印指定非终结符的 FIRST 集
125  * Token : char 需要打印的符号
126  * TerminalCount : int 终结符数量
127  */
128 void PrintFIRST(char Token, int TerminalCount)
129 {
130     char *FIRST = (char*)malloc(TerminalCount + 1);
131     memset(FIRST, '\0', TerminalCount + 1);
132     int Ptr = 0, i;
133     GetFIRST(Token, FIRST, &Ptr);
134     printf("FIRST(%c): ", Token);
135     for (i = 0; i < Ptr; i++)
136     {
137         if (FIRST[i] == '\0')
138         {
139             printf("<e> ");
140         }
141         else
142         {
143             printf("%c ", FIRST[i]);
144         }
145     }
146     printf("\n");
147 }
148 
149 int main(int argc, char **argv)
150 {
151     InitizationGrammerRule();    // 初始化文法
152     int TerminalCount = GetTerminalCount();
153     printf("Terminal Symbol Count: %d\n", TerminalCount);
154     PrintFIRST('E', TerminalCount);
155     PrintFIRST('F', TerminalCount);
156     PrintFIRST('T', TerminalCount);
157     PrintFIRST('U', TerminalCount);
158     PrintFIRST('A', TerminalCount);
159     return 0;
160 }

 

posted on 2013-06-29 20:03  RexfieldVon  阅读(411)  评论(0编辑  收藏  举报