太累了,感觉不会再爱了。执行了跟编译原理上的一模一样的例子,输出了正确结果
1 #include <stdio.h> 2 #include <malloc.h> 3 #include <string.h> 4 //这个头文件是为了将语法声明的产生式按照调用顺序来构建调用图,并顺便构建反向调用图。 5 //从而来构建拓扑排序,并用到将来的分析之中。 6 typedef struct _decl_hash_table 7 { 8 int is_used;//代表是否已经被使用 9 char* decl_hash_name;//代表名字 10 int node_index;//代表所代表的节点编号 11 }decl_hash_table,*pdecl_hash_table; 12 decl_hash_table decl_hash[100];//暂且定位100,其实我们在使用的过程中只会使用其中的97个,因为这个是一个质数 13 typedef struct _decl_edge 14 { 15 int node_of_dest; 16 struct _decl_edge* next; 17 }decl_edge,*pdecl_edge; 18 typedef struct _phrase 19 { 20 pdecl_edge begin_of_phrase; 21 struct _phrase* next; 22 }phrase; 23 typedef struct _decl_node 24 { 25 phrase* phrase_link;//作为产生体链表的第一个节点的指针 26 char* name_of_decl;//这个节点的名称,主要是为了输出使用的 27 }decl_node,*pdecl_node; 28 decl_node decl_node_table[100];//假设为100个节点,可以改 29 int node_index=0;//全局的用来给节点赋予编号的变量,最后的值代表了有多少个文法符号,结束符不算在里面 30 31 int insert_decl_hash(char* name,int input_node_index) 32 //hash表插入函数,如果满了则返回-1 33 //注意这里为了节省空间,hash表与节点表的名字域公用了一个字符串指针 34 { 35 int name_total; 36 int counter; 37 int result; 38 int name_for_i; 39 char* new_name; 40 name_for_i=counter=name_total=result=0; 41 while(name[name_for_i]!='