Таблица символов в C

#c #linux #symbol-table

#c #linux #таблица символов

Вопрос:

В настоящее время я разрабатываю инструмент статического анализа, который выполняет сопоставление с шаблоном. Я использую Flex для создания лексического анализатора, и я написал код для управления таблицей символов. У меня не очень большой опыт работы с 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;
      }
   }
}
  

Однако, когда я использую add_entry() для добавления символов, а затем пытаюсь найти их с помощью find_entry() , find_entry() возвращает null. Может кто-нибудь, пожалуйста, помочь?

Комментарии:

1. Если бы я не был очень опытен в C, я бы не реализовывал таблицу символов в виде связанного списка, я бы реализовал ее как большой массив фиксированного размера. Если бы у меня был опыт работы с C (а я им являюсь), я бы сделал то же самое. Вы всегда можете преобразовать в связанный список (или, что еще лучше, в динамический массив) позже, но сначала заставьте его работать. И совет профессионала — связанный список — это самая последняя структура данных, которую вам следует учитывать в большинстве ситуаций.

2. Вместо того, чтобы реализовывать структуру данных самостоятельно, вам следует использовать уже реализованное решение, такое как Glib. Для программ на C доступно множество различных структур данных: developer.gnome.org/glib/2.28/glib-data-types.html КСТАТИ: таблица символов — это не список, а хэш.

3. Пожалуйста, не ставьте пробелы вокруг -> оператора. И она, и . оператор чрезвычайно тесно связаны, и любому, кто имеет опыт работы с C или C , просто кажется странным видеть там пробелы.

4. @ceving: таблица символов обычно не создается с использованием простого связанного списка, но она может быть создана таким образом. Следовательно, ваше утверждение «таблица символов — это не список, а хэш» вводит в заблуждение.

5. @ceving Мусор. Предположим, что таблица символов должна содержать, скажем, только 3 символа — реализация массива (или даже связанного списка) вполне может быть быстрее и потреблять меньше памяти. Многие компиляторы используют множество небольших таблиц символов.

Ответ №1:

Похоже, вы пытаетесь представить список как объект заголовка (start), за которым следуют фактические элементы списка. Это хорошая идея, поскольку она упрощает случай с пустым списком, но у вас неправильная реализация.

При добавлении вам нужно удалить код специального регистра, который у вас есть для last_entry, который является start . Начальный узел никогда не будет содержать символьных данных.

При поиске вы должны убедиться, что пропустили заголовок (start), поскольку он не содержит символьных данных. Вторая ошибка в вашем коде поиска заключается в том, что вы прекращаете поиск, когда p-> next имеет значение NULL (что означает, что вы никогда не сможете вернуть последний элемент в вашем списке.) Вы должны остановиться, когда p равно нулю.

Конечно, вам вообще не следует использовать связанный список: хэш-таблица была бы лучшим выбором, поскольку она обладает лучшей производительностью и эффективностью памяти.

Комментарии:

1. Хорошие моменты — все они. Любопытно, что размещение новых символов в конце списка, как это делается, также, вероятно, плохо сказывается на производительности; размещение их в начале означает, что вновь определенные символы находятся быстрее, что часто полезно.

2. Большое вам спасибо. Я понимаю, что хэш-таблица была бы более эффективной, и в будущем я, вероятно, повторно внедрю таблицу symbopl в качестве хэш-таблицы.