Проблемы с Лексом - PullRequest
0 голосов
/ 30 мая 2011

Я пишу программное обеспечение на 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;
}

Есть идеи?

1 Ответ

0 голосов
/ 30 мая 2011

Вам необходимо скопировать имена символов в записи таблицы символов. Если по какой-то особой причине ваша система не имеет 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.

...