#include "stdio.h" #include "stdbool.h" // A C program to demonstrate linked list based implementation of queue // A linked list (LL) node to store a queue entry struct trie_QNode { char * rule_name; int rule_name_index; char * key; int index; char * rule_next; int rule_next_index; struct QNode *next; }; // The queue, front stores the front node of LL and rear stores ths // last node of LL struct trie_Queue { struct trie_QNode *front, *rear; }; // A utility function to create a new linked list node. struct trie_QNode* trie_newNode(char * a, int b, char * c, int d, char * e, int f) { struct trie_QNode *temp = (struct trie_QNode*)malloc(sizeof(struct trie_QNode)); temp->rule_name = a; temp->rule_name_index = b; temp->key = c; temp->index = d; temp->rule_next = e; temp->rule_next_index = f; temp->next = NULL; return temp; } // A utility function to create an empty queue struct trie_Queue *trie_createQueue() { struct trie_Queue *q = (struct trie_Queue*)malloc(sizeof(struct trie_Queue)); q->front = q->rear = NULL; return q; } void trie_store_asm(struct trie_Queue *q, char * rule_name, int rule_name_index, char * key, int index, char * rule_next, int rule_next_index) { // Create a new LL node struct trie_QNode *temp = trie_newNode(rule_name,rule_name_index,key,index,rule_next,rule_next_index); // If queue is empty, then new node is front and rear both if (q->rear == NULL) { q->front = q->rear = temp; q->rear->rule_next = NULL; q->rear->rule_next_index = -1; return; } // Add the new node at the end of queue and change rear if (q->rear) { q->rear->rule_next = rule_name; q->rear->rule_next_index = rule_name_index; } q->rear->next = temp; q->rear = temp; if (q->rear) { q->rear->rule_next = NULL; q->rear->rule_next_index = -1; } } void trie_store_asm2(struct trie_Queue *q, char * rule_name, int rule_name_index, char * key, int index, char * rule_next, int rule_next_index) { // Create a new LL node struct trie_QNode *temp = trie_newNode(rule_name,rule_name_index,key,index,rule_next,rule_next_index); // If queue is empty, then new node is front and rear both if (q->rear == NULL) { q->front = q->rear = temp; return; } // Add the new node at the end of queue and change rear if (q->rear) { q->rear->rule_next = rule_name; q->rear->rule_next_index = rule_name_index; } q->rear->next = temp; q->rear = temp; } void trie_store_asm3(struct trie_Queue *q, char * rule_name, int rule_name_index, char * key, int index, char * rule_next, int rule_next_index) { // Create a new LL node struct trie_QNode *temp = trie_newNode(rule_name,rule_name_index,key,index,rule_next,rule_next_index); // If queue is empty, then new node is front and rear both if (q->rear == NULL) { q->front = q->rear = temp; return; } // Add the new node at the end of queue and change rear q->rear->next = temp; q->rear = temp; } struct trie_QNode * trie_load_asm(struct trie_Queue **q) { // If queue is empty, return NULL. if ((q) == NULL) return NULL; if ((*q) == NULL) return NULL; if ((*q)->front == NULL) return NULL; // Store previous front and move front one node ahead struct trie_QNode *temp = (*q)->front; (*q)->front = (*q)->front->next; // If front becomes NULL, then change rear also as NULL if ((*q)->front == NULL) (*q)->rear = NULL; return temp; } int trie_queue_add(struct trie_Queue **q, char * rule_name, int rule_name_index, char * key, int index, char * rule_next, int rule_next_index) { if (!(*q)) (*q) = trie_createQueue(); trie_store_asm((*q), rule_name,rule_name_index,key,index,rule_next,rule_next_index); return 0; } int trie_queue_add2(struct trie_Queue **q, char * rule_name, int rule_name_index, char * key, int index, char * rule_next, int rule_next_index) { if (!(*q)) (*q) = trie_createQueue(); trie_store_asm2((*q), rule_name,rule_name_index,key,index,rule_next,rule_next_index); return 0; } int trie_queue_add3(struct trie_Queue **q, char * rule_name, int rule_name_index, char * key, int index, char * rule_next, int rule_next_index) { if (!(*q)) (*q) = trie_createQueue(); trie_store_asm3((*q), rule_name,rule_name_index,key,index,rule_next,rule_next_index); return 0; } char * trie_root = "root"; char * trie_sub_root = "sub_root"; char * trie_rule_prefix = "rule_"; struct trie_Queue * trie_trie = NULL; int main(int argc, char **argv) { trie_queue_add(&trie_trie, trie_sub_root, -1, NULL, 0, trie_rule_prefix, 0); // root>0 trie_queue_add(&trie_trie, trie_rule_prefix, 0, NULL, 1, trie_rule_prefix, 1); // 0>1 trie_queue_add(&trie_trie, trie_rule_prefix, 1, NULL, 1, trie_rule_prefix, 2); // 1>2 trie_queue_add2(&trie_trie, trie_rule_prefix, 2, NULL, 1, trie_rule_prefix, 3); // 2>3 trie_queue_add3(&trie_trie, trie_rule_prefix, 0, NULL, 1, trie_rule_prefix, 1); // 0>1 trie_queue_add(&trie_trie, trie_rule_prefix, 1, NULL, 1, trie_rule_prefix, 2); // 1>2 trie_queue_add2(&trie_trie, trie_rule_prefix, 2, NULL, 1, trie_rule_prefix, 3); // 2>3 trie_queue_add3(&trie_trie, trie_rule_prefix, 3, NULL, 1, NULL, -1); // 3>END struct trie_QNode * node = trie_newNode(NULL,0,NULL,0,NULL,0); // this gets freed anyway int nodes = 0; int start_indent = 0; int i = 0; for (i = 0; i < start_indent; i++) printf(" "); printf("struct TrieNode * %s = getNode(); \n", trie_root); for (i = 0; i < start_indent; i++) printf(" "); printf("struct TrieNode * %s = getNode(); \n", trie_sub_root); while (node != NULL) { // drain the list until empty if (node->key) free(node->key); free(node); node = trie_load_asm(&trie_trie); if (node == NULL) break; // pp(node) // pp(node->rule_name) // ps(node->rule_name) // pi(node->rule_name_index) // pp(node->key) // ps(node->key) // pi(node->index) // pp(node->rule_next) // ps(node->rule_next) // pi(node->rule_next_index) if (node->rule_next && node->rule_next_index != -1) { bool rule_does_not_exist = false; bool next_rule_does_not_exist = false; if (node->rule_name_index == -1) { // is sub_root if (rule_does_not_exist) { for (i = 0; i < start_indent+1; i++) printf(" "); printf("struct TrieNode * %s%d = getNode(); \n", node->rule_name, node->rule_name_index); } if (next_rule_does_not_exist) { for (i = 0; i < start_indent+1; i++) printf(" "); printf("struct TrieNode * %s%d = getNode(); \n", node->rule_next, node->rule_next_index); } for (i = 0; i < start_indent+1; i++) printf(" "); printf("insert(%s, \"%s\", %d, %s%d);\n", node->rule_name, node->key, node->index, node->rule_next, node->rule_next_index); } else { // is rule if (rule_does_not_exist) { for (i = 0; i < start_indent+2; i++) printf(" "); printf("struct TrieNode * %s%d = getNode(); \n", node->rule_name, node->rule_name_index); } if (next_rule_does_not_exist) { for (i = 0; i < start_indent+2; i++) printf(" "); printf("struct TrieNode * %s%d = getNode(); \n", node->rule_next, node->rule_next_index); } for (i = 0; i < start_indent+2; i++) printf(" "); printf("insert(%s%d, \"%s\", %d, %s%d);\n", node->rule_name, node->rule_name_index, node->key, node->index, node->rule_next, node->rule_next_index); } } else { if (node->rule_name_index == -1) { // is sub_root for (i = 0; i < start_indent+1; i++) printf(" "); printf("insert(%s, \"%s\", %d, NULL);\n", node->rule_name, node->key, node->index); } else { // is rule for (i = 0; i < start_indent+2; i++) printf(" "); printf("insert(%s%d, \"%s\", %d, NULL);\n", node->rule_name, node->rule_name_index, node->key, node->index); } } nodes++; } return 0; }