Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C语言中的符号表_C_Linux_Symbol Table - Fatal编程技术网

C语言中的符号表

C语言中的符号表,c,linux,symbol-table,C,Linux,Symbol Table,我目前正在开发一种静态分析工具,用于执行模式匹配。我正在使用生成词法分析器,并编写代码来管理符号表。我对C不是很有经验,所以我决定将符号表实现为一个线性链表 #include <stdlib.h> #include <stdio.h> #include <string.h> struct symtab { int id; char *name; int type; struct symtab *next; }; enum types

我目前正在开发一种静态分析工具,用于执行模式匹配。我正在使用生成词法分析器,并编写代码来管理符号表。我对C不是很有经验,所以我决定将符号表实现为一个线性链表

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

struct symtab {
   int id;
   char *name;
   int type;
   struct symtab *next;
};

enum types {
   KEYWORD = 1,
   CONSTANT,
   IDENTIFIER,
   OPERATOR,
   DELIMITER,
   WHITESPACE
};

struct symtab *last_entry(struct symtab *start)
{
   struct symtab *p;
   p = start;
   while(p -> next != NULL) {
      p = p -> next;
   }
   return p;
}

void add_entry(char* name, int type, struct symtab *start)
{
   struct symtab *new;
   new = last_entry(start);
   int id;
   if(new == start) {
      new = start;
      id = 0;
   }
   else {
      new = malloc(sizeof(struct symtab));
      id = last_entry(start) -> id;
      last_entry(start) -> next = new;
   }
   new -> id = id + 1;
   new -> name = name;
       new -> type = type;
   new -> next = NULL;
}

struct symtab *find_entry(char* name, struct symtab *start)
{
   struct symtab *p;
   p = start;
   while(p -> next != NULL) {
      if(strcmp(p -> name, name) == 0) {
         return p;
      }
   }
}
#包括
#包括
#包括
结构符号表{
int-id;
字符*名称;
int型;
结构符号表*下一步;
};
枚举类型{
关键字=1,
常数
标识符,
操作人员
分隔符,
空白
};
结构symtab*最后一项(结构symtab*开始)
{
结构符号表*p;
p=启动;
while(p->next!=NULL){
p=p->next;
}
返回p;
}
void add_条目(char*名称、int类型、struct symtab*开始)
{
结构符号表*新建;
新建=最后一项(开始);
int-id;
如果(新==开始){
新=开始;
id=0;
}
否则{
新建=malloc(sizeof(struct symtab));
id=最后一项(开始)->id;
最后一项(开始)->下一项=新建;
}
新建->id=id+1;
新建->名称=名称;
新建->类型=类型;
新建->下一步=空;
}
结构符号表*查找项(字符*名称,结构符号表*开始)
{
结构符号表*p;
p=启动;
while(p->next!=NULL){
if(strcmp(p->name,name)==0){
返回p;
}
}
}

但是,当我使用
add_entry()
添加符号,然后尝试使用
find_entry()
查找符号时,
find_entry()
返回null。有人可以帮忙吗?

看起来您正试图将列表表示为标题对象(开始),后跟列表的实际元素。这是一个好主意,因为它简化了空列表的情况,但是您没有正确地实现

添加时,需要删除上次启动时的特殊情况代码。开始节点将永远不包含符号数据

查找时,必须确保跳过头部(开始),因为它不包含符号数据。查找代码中的第二个错误是当p->next为NULL时停止搜索(这意味着您永远无法返回列表中的最后一个元素)。当p为NULL时,应该停止搜索


当然,您根本不应该使用链表:哈希表是更好的选择,因为它具有更好的性能和内存效率。

如果我对C不是很有经验,我不会将符号表实现为链表,而是将其实现为一个固定大小的大数组。如果我有C语言的经验(我是),我也会这么做。您可以随时在以后转换为链表(或者更好,转换为动态数组),但要先让它工作。在大多数情况下,链接列表是你应该考虑的最后一个数据结构,而不是自己实现数据结构,而应该使用像Glib这样的已经实现的解决方案。C程序有许多不同的数据结构:顺便说一句:符号表不是列表,而是散列。请不要在
->
运算符周围加空格。它和 > ./Cuth>运算符绑定得非常紧密,对于在C或C++中体验到空间的人来说,这看起来很奇怪。@ CaveIn:符号表通常不是用简单链表创建的,而是可以用这种方式创建的。因此,您的陈述“符号表不是列表而是散列”是误导性的。假设符号表只需要包含3个符号,那么一个数组(甚至是一个链表)实现可能会更快,占用更少的内存。许多编译器使用许多小符号表。优点-所有这些。奇怪的是,像这样把新符号放在列表的末尾也可能对性能有害;把它们放在最前面意味着可以更快地找到新定义的符号,这通常是有益的。非常感谢。我知道哈希表会更有效,将来我可能会将symbopl表重新实现为哈希表。