#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 в качестве хэш-таблицы.