【问题标题】:Problems With LexLex 的问题
【发布时间】:2011-05-30 03:13:05
【问题描述】:

我正在用 C 语言编写软件。为此我使用 lex。我用 C 写了一段代码来创建一个symbol table 并管理它。因此,每当 lex 找到一个新符号时,它都会将其放入符号表中。问题是,当我尝试打印符号表中的所有结果时,我得到了我没想到的输出。 例如,如果输入文件是:

int main(){}

输出应该是:

int
main
(
)
{
}

但输出是:

int main(){}
main(){}
(){}
...

等等。 用于打印的函数是这样的

void print_entries(struct symtab *start) {
   struct symtab *s = start;
   while(s != NULL) {
      printf("%s\n", s->name);
      s = s->next;
   }
}

这是添加新符号的代码:

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

有什么想法吗?

【问题讨论】:

  • (这可能是一个愚蠢的问题,但你只调用一次 print_entries 吗?)
  • 是的,我只调用一次 :)
  • 对不起,我想我应该问:P
  • 那么add_entry() 是怎么称呼的?你还没有为这里的名字分配任何东西。
  • 杰夫是正确的。您将指针存储到 ->name 字段中的输入缓冲区中;您需要为正确数量的字符分配空间(在add_entry 中似乎您目前不知道 - 这需要传入)、复制和 nul-terminate。

标签: c linux lex


【解决方案1】:

您需要将符号名称复制到符号表条目中。如果由于某些特殊原因您的系统还没有strdup(),请使用:

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

char *strdup(const char *str)
{
   size_t len = strlen(str) + 1;
   char *dup = malloc(len);
   if (dup != 0)
       memmove(dup, str, len);
   return dup;
}

(在这种情况下,我可以安全地使用memcpy();我使用memmove(),因为它始终有效,而memcpy() 无效。我使用memmove(),因为我确切知道字符串有多长,所以复制不需要测试每个字符是否为空。)

手头上有strdup()

void add_entry(char* name, int type, struct symtab *start)
{
   struct symtab *sym;
   sym = malloc(sizeof(struct symtab));
   last_entry(start)->next = sym;
   sym->name = strdup(name);
   sym->type = type;
   sym->next = NULL;
}

请注意,这仍然忽略了两次内存分配的错误检查,这不是一个好习惯。我已将其修改为使用 sym 而不是 new,因为后者是 C++ 关键字,我避免使用它们作为标识符,即使在 C 代码中也是如此。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-14
    • 1970-01-01
    相关资源
    最近更新 更多