Lex 的问题

发布于 2024-11-10 09:42:25 字数 886 浏览 4 评论 0原文

我正在用 C 语言编写一个软件。为此我使用 lex。我用 C 编写了一段代码来创建 符号表 并管理它。因此,每当 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;
}

有什么想法吗?

I am writing a software in C. For that purpose I use lex. I wrote a piece of code in C to create a symbol table and manage it. So, whenever lex finds a new symbol, it puts it in a symbol table. Problem is, when I try to print all results from symbol table, I get output I didn't expect.
If, for example, the input file was:

int main(){}

the output should be:

int
main
(
)
{
}

but the output is:

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

and so on.
The function used for printing is something like this

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

Here is the code for adding new symbols:

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;
}

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

待天淡蓝洁白时 2024-11-17 09:42:25

您需要将符号名称复制到符号表条目中。如果由于某种特殊原因您的系统还没有 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 代码中也是如此。

You need to copy the symbol names into the symbol table entries. If for some peculiar reason your system does not have strdup() already, then use:

#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;
}

(In this context, I could use memcpy() safely; I use memmove() because it always works and memcpy() does not. And I use memmove() because I know exactly how long the string is so the copy doesn't need to test each character for nullness as it goes.)

With strdup() on hand:

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;
}

Note that this still omits the error checking from the two memory allocations, which is not a good habit to get into. I've revised it to use sym rather than new because the latter is a C++ keyword and I avoid using those as identifiers, even in C code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文