#include #include #include #include // 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; }