Во-первых, я предполагаю, что List
является typedef для struct conscell*
.Если это не так, то так и должно быть, иначе ваш код не будет компилироваться без множества предупреждений.
Ячейка схемы должна быть простым односвязным списком, а не двусвязным списком.Таким образом, ваши отдельные ячейки должны быть больше похожи на:
typedef conscell
{
unsigned char *data; //<== use unsigned char for a memory buffer
struct conscell* next; //<== only a "next" pointer needed
} conscell;
Я вижу, что вы просто пытаетесь напечатать символы в данный момент, так что использование char
вместо unsigned char
может работать для этой цели, но когдавы идете с более общими структурами данных, такими как лямбды и т. д., вам придется переключиться на unsigned char*
или void*
для ссылки на буфер памяти, содержащий эти типы более сложных структур данных.
Другая проблема, которая кажется немного запутанной, состоит в том, что вы делаете каждую ячейку ваших cons-ячеек другой cons-ячейкой, например, эти строки кода
if (token[0] == '(')
{
strcpy(token, getToken());
node->first = nextNode(node->first);
node->rest = nextNode(node->rest);
}
рекурсивно добавляют cons-ячейкикак ваши "first" и "rest" ... но не так, как должен выглядеть связанный список.Он должен иметь указатель на узел списка в качестве «заголовка» списка (а не на другую конс-ячейку, как кажется, что вы здесь делаете), а затем каждый узел в списке указывает на некоторые данные и следующий узел всписок.
Далее, у вас есть утечки памяти повсюду с вашей функцией createList()
, когда вы выделяете ей память, но затем никогда не удаляете эту память (т. е. у вас есть код, такой как node = NULL
, который эффективноэто утечка памяти, потому что вы потеряли ссылку на выделенную область памяти, на которую изначально указывал node
).Вы должны вызвать free()
для указателя узла, прежде чем назначить ему NULL
.
Наконец, printList()
ничего не делает, но печатает первый элемент списка, который вы передаете ему ...нет рекурсивных вызовов или циклов для перехода к следующему узлу в связанном списке.Таким образом, вы не собираетесь много печатать с этой функцией.Это должно выглядеть примерно так:
void printList(List node)
{
List current = node;
while (current != NULL) //<== guard for the end-of-list
{
if (node->data != NULL)
{
printf("%s", node->data);
}
current = current->next; //cycle to the next node in the linked list
}
}
Итак, чтобы подвести итог, 1) ваша структура данных cons должна представлять собой односвязный список, состоящий из типа данных структуры, имеющего элемент данных и указатель наследующий узелДоступ к списку заключенных осуществляется через указатель головы, указывающий на первый узел.2) Когда вы анализируете входные данные, вы должны добавить узлы в начало связанного списка, так как операция Схемы cons
, и на самом деле все операции в схеме являются рекурсивными и «сворачиваются вправо», то есть они работают избазовый случай (т. е. состоящий из двух элементов), а затем разверните этот базовый случай.Так что, если у вас было что-то вроде (cons 'd (cons 'c (cons 'b (cons 'a '()))))
, вы бы распечатали список (d c b a)
.Если вы хотите, это также может помочь поместить токены в стек, так как вы рекурсивно анализируете входные данные, а затем из стекового ввода в свой связанный список (вроде как будет работать калькулятор RPN).