-
- #include <stdbool.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.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 trie_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 rule_index = -1;
- int actual_index = 0;
- bool passed_first = false;
- bool passed_next = false;
- int update_on_next_pass = false;
-
- int final_rule = 0;
- int rule_index_tmp = 0;
- int actual_index_tmp = 0;
-
- bool part_of_branch = false;
-
- int itterations = 0;
- char co[5];
- void getbranchcontents(char * s) {
- memset(co,0,5);
- int ci = 0;
- for(; *s; s++) {
- if (*s == 'b') {
- continue;
- }
- if (*s == 'e' || *s == 'C') {
- break;
- }
- if (*s == ' ' || *s == '\n' || *s == '\t') continue;
- if (*s == 's') {
- s++;
- co[0] = *s;
- ci++;
- }
- }
- printf("c = %s\n", co);
- }
-
- void parse_branch(char * co) {
- itterations++;
- int actual_index_tmp = 0;
- char * zrule_name;
- int zrule_name_index;
- char * zkey;
- int zindex;
- if (itterations == 1) {
- zrule_name = trie_trie->rear->rule_name;
- zrule_name_index = trie_trie->rear->rule_name_index;
- zkey = trie_trie->rear->key;
- zindex = trie_trie->rear->index;
- rule_index_tmp = rule_index+1;
- final_rule = rule_index_tmp;
- }
- else if (itterations == 2) rule_index_tmp++;
- actual_index_tmp = actual_index+1;
- printf("zrule_name = %s\n", zrule_name);
- printf("zkey = %s\n", zkey);
- printf("insert(%s%d, \"%s\", %d, %s%d);\n", zrule_name, zrule_name_index, zkey, zindex, trie_rule_prefix, rule_index_tmp-(itterations==1?0:1));
- trie_queue_add3(&trie_trie, zrule_name, zrule_name_index, strdup(zkey), zindex, trie_rule_prefix, rule_index_tmp-(itterations==1?0:1));
- for (int level = 0; co[level]; level++) {
- char tmp[2];
- tmp[0] = co[level];
- tmp[1] = '\0';
- printf("insert(%s%d, \"%s\", %d, %s%d);\n", trie_rule_prefix, rule_index_tmp-1, tmp, actual_index_tmp, trie_rule_prefix, co[level+1]?rule_index_tmp:final_rule);
- if (itterations == 1) {
- if (co[level+1]) {
- puts("RULE");
- trie_queue_add(&trie_trie, trie_rule_prefix, rule_index_tmp-1, strdup(tmp), actual_index_tmp, trie_rule_prefix, rule_index_tmp);
- } else {
- puts("FINAL");
- trie_queue_add2(&trie_trie, trie_rule_prefix, rule_index_tmp-1, strdup(tmp), actual_index_tmp, trie_rule_prefix, final_rule);
- }
- } else {
- puts("RULE FINAL");
- trie_queue_add3(&trie_trie, trie_rule_prefix, rule_index_tmp-1, strdup(tmp), actual_index_tmp, trie_rule_prefix, co[level+1]?rule_index_tmp:final_rule);
- }
- rule_index_tmp++;
- if (itterations == 1 && co[level+1]) final_rule++;
- actual_index_tmp++;
- }
- }
- int main(int argc, char **argv) {
- /*
- def0:
- 35:NULL
- 85:NULL
-
- rule1 : |1|2|def0|6|
- */
-
- char * s = "\
- i:\
- s1\
- s2\
- b\
- C\
- s3\
- s5\
- C\
- s8\
- s5\
- e\
- s6"; // for the sake of simplicity branches contain full strings only, not individual characters
- rule_index++;
- for(; *s; s++) {
- if (*s == 'b') {
- puts("branch start");
- part_of_branch = true;
- itterations = 0;
- for(; *s; s++) {
- if (*s == 'C') {
- s++;
- getbranchcontents(s);
- parse_branch(co);
- memset(co,0,5);
- };
- if (*s == 'e') break;
- }
- if (*s == 'e') s--;
- continue;
- }
- if (*s == 'e') {
- puts("branch end");
- part_of_branch = false;
- itterations = 0;
- if (final_rule) {
- rule_index = final_rule;
- update_on_next_pass = true;
- final_rule = 0;
- }
- continue;
- }
- if (*s == ' ' || *s == '\n' || *s == '\t') continue;
- if (*s == 'i') {
- passed_first = true;
- continue;
- }
- if (*s == 's' || *s == ':') {
- s++;
- printf("key: %c\n", *s);
- if (!part_of_branch) {
- if (!passed_first) {
- if (passed_next) {
- if (update_on_next_pass/* && (tmp.type & STR_TYPE_DIGIT || tmp.type & STR_TYPE_BINARY)*/) {
- rule_index = rule_index_tmp-1;
- update_on_next_pass = false;
- }
- actual_index = 0;
- passed_next = false;
- char tmp[2];
- tmp[0] = *s;
- tmp[1] = '\0';
- trie_queue_add(&trie_trie, trie_sub_root, -1, strdup(tmp), actual_index, trie_rule_prefix, rule_index);
- }
- else {
- rule_index++;
- actual_index++;
- char tmp[2];
- tmp[0] = *s;
- tmp[1] = '\0';
- trie_queue_add(&trie_trie, trie_rule_prefix, rule_index-1, strdup(tmp), actual_index, trie_rule_prefix, rule_index);
- }
- } else {
- passed_first = false;
- passed_next = true;
- }
- }
- }
- }
- // 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;
- }
-