spacepaste

  1.  
  2. $ ./new
  3. FOUND BRANCH START
  4. FOUND BRANCH START
  5. 0 -> 1 (data: 1)
  6. p->next = (nil)
  7. NULL
  8. printing previous
  9. NULL
  10. 3 -> 4 (data: 13)
  11. branch end
  12. branch choice end
  13. 2 -> 3 (data: 8)
  14. branch choice start
  15. branch choice end
  16. 1 -> 2 (data: 2)
  17. branch choice start
  18. branch start
  19. 0 -> 1 (data: 1)
  20. $ cat new.c
  21. #include <stdbool.h>
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #define pp(x) printf("%s = %p\n", #x, x);
  26. #define pi(x) printf("%s = %d\n", #x, x);
  27. #define pc(x) printf("%s = %c\n", #x, x);
  28. #define psize_t(x) printf("%s = %zu\n", #x, x);
  29. #define LINKED 1
  30. #define TREE 2
  31. #define NODE_TYPE TREE
  32. struct QNode
  33. {
  34. int level;
  35. int index;
  36. int ref;
  37. int data;
  38. int type;
  39. struct QNode *next;
  40. struct QNode* prev; // Pointer to previous node in DLL
  41. #if NODE_TYPE == TREE
  42. int branch_count;
  43. struct QNode **branch;
  44. #endif
  45. };
  46. // The queue, front stores the front node of LL and rear stores ths
  47. // last node of LL
  48. struct Queue
  49. {
  50. struct QNode *front, *rear;
  51. };
  52. ssize_t free_asm(struct Queue **q)
  53. {
  54. puts("");
  55. ssize_t frees = 0;
  56. if ((q) == NULL) return frees;
  57. if ((*q) == NULL) return frees;
  58. struct QNode *temp = NULL, *next = NULL;
  59. temp = (*q)->front;
  60. while (temp) {
  61. next = (*q)->front->next;
  62. frees++;
  63. free(temp);
  64. temp = NULL;
  65. (*q)->front = next;
  66. temp = next;
  67. }
  68. frees++;
  69. free(*q);
  70. *q = NULL;
  71. return frees;
  72. }
  73. // A C program to demonstrate linked list based implementation of queue
  74. // A linked list (LL) node to store a queue entry
  75. int index_start = -1;
  76. int ref_start = 0;
  77. int global_indent = 0;
  78. #if NODE_TYPE == LINKED
  79. #define node_init(t, i, r, d, n) t->index = i; t->ref = r; t->data = d; t->next = n; t->level = global_indent; t->prev = NULL;
  80. #elif NODE_TYPE == TREE
  81. #define node_init(t, i, r, d, n, bc, b) t->index = i; t->ref = r; t->data = d; t->next = n; t->branch_count = bc; t->branch = b; t->level = global_indent; t->prev = NULL;
  82. #endif
  83. #define STORE_NORMAL 1
  84. #define STORE_EMPTY 2
  85. #define NODE_TYPE_NORMAL 1
  86. #define NODE_TYPE_BRANCH_START 2
  87. #define NODE_TYPE_BRANCH_END 3
  88. #define NODE_TYPE_BRANCH_CHOICE_START 4
  89. #define NODE_TYPE_BRANCH_CHOICE_END 5
  90. #define POINTER_LIST_TYPE int
  91. POINTER_LIST_TYPE ** ptr_list = NULL;
  92. ssize_t ptr_list_size = 0;
  93. int last_ref = 0;
  94. int ptr_add(POINTER_LIST_TYPE * ptr) {
  95. if (!ptr) return -1;
  96. if (!ptr_list) {
  97. ptr_list = malloc(sizeof(*ptr_list)*2);
  98. ptr_list_size++;
  99. }
  100. else if (ptr_list) {
  101. ptr_list = realloc(ptr_list, sizeof(*ptr_list)*(ptr_list_size+1));
  102. }
  103. ptr_list[ptr_list_size-1] = ptr;
  104. ptr_list_size++;
  105. ptr_list[ptr_list_size-1] = NULL;
  106. return 0;
  107. }
  108. int ptr_print(void) {
  109. if (!ptr_list) return -1;
  110. POINTER_LIST_TYPE ** pl;
  111. for (pl = ptr_list; *pl; pl++) pp(*pl);
  112. return 0;
  113. }
  114. int ptr_set(POINTER_LIST_TYPE data) {
  115. if (!ptr_list) return -1;
  116. POINTER_LIST_TYPE ** pl;
  117. for (pl = ptr_list; *pl; pl++) **pl = data;
  118. return 0;
  119. }
  120. int ptr_set_free(void) {
  121. if (!ptr_list) return -1;
  122. POINTER_LIST_TYPE ** pl;
  123. for (pl = ptr_list; *pl; pl++) {
  124. free(*pl);
  125. *pl = NULL;
  126. }
  127. return 0;
  128. }
  129. int ptr_free(void) {
  130. if (!ptr_list) return -1;
  131. POINTER_LIST_TYPE ** pl;
  132. for (pl = ptr_list; *pl; pl++) *pl = NULL;
  133. free(ptr_list);
  134. ptr_list = NULL;
  135. ptr_list_size = 0;
  136. return 0;
  137. }
  138. // A utility function to create a new linked list node.
  139. struct QNode* newNode(int data, int type)
  140. {
  141. struct QNode *temp = (struct QNode*)malloc(sizeof(*temp));
  142. #if NODE_TYPE == LINKED
  143. if (type == STORE_NORMAL) {
  144. node_init(temp, index_start++, ref_start++, data, NULL);
  145. } else if (type == STORE_EMPTY) {
  146. node_init(temp, 0, 0, 0, 0, NULL);
  147. }
  148. #elif NODE_TYPE == TREE
  149. if (type == STORE_NORMAL) {
  150. node_init(temp, index_start++, ref_start++, data, NULL, 0, NULL);
  151. } else if (type == STORE_EMPTY) {
  152. node_init(temp, 0, 0, 0, NULL, 0, NULL);
  153. }
  154. #endif
  155. return temp;
  156. }
  157. // A utility function to create an empty queue
  158. struct Queue *createQueue()
  159. {
  160. struct Queue *q = (struct Queue*)malloc(sizeof(*q));
  161. q->front = q->rear = NULL;
  162. return q;
  163. }
  164. int prev_type = 0;
  165. int curr_type = 0;
  166. void store_asm(struct Queue *q, int data, int type)
  167. {
  168. if (curr_type) prev_type = curr_type;
  169. curr_type = type;
  170. // Create a new LL node
  171. int t = 0;
  172. if (type == NODE_TYPE_NORMAL) t = STORE_NORMAL;
  173. else if (
  174. type == NODE_TYPE_BRANCH_START
  175. ||
  176. type == NODE_TYPE_BRANCH_END
  177. ||
  178. type == NODE_TYPE_BRANCH_CHOICE_START
  179. ||
  180. type == NODE_TYPE_BRANCH_CHOICE_END
  181. ) t = STORE_EMPTY;
  182. struct QNode *temp = newNode(data, t);
  183. temp->type = type;
  184. // If queue is empty, then new node is front and rear both
  185. if (q->rear == NULL)
  186. {
  187. temp->prev = NULL;
  188. q->front = q->rear = temp;
  189. return;
  190. }
  191. if (prev_type == NODE_TYPE_NORMAL) {
  192. if (type == NODE_TYPE_BRANCH_CHOICE_END) {
  193. // we reach a the end of a branch choice, add the address of the last reference, the pointer to the next node, to an array of pointers
  194. // last_ref = q->rear->ref;
  195. // printf("adding %d to the pointer list\n", last_ref);
  196. // ptr_add(&q->rear->ref);
  197. }
  198. }
  199. else if(type == NODE_TYPE_NORMAL && prev_type == NODE_TYPE_BRANCH_END) {
  200. // we reach a node and we where previously at a branch, set all referenced logged to the value of the current node reference, then we free the pointer list
  201. // printf("setting pointer list to %d\n", last_ref);
  202. // ptr_set(last_ref);
  203. // ptr_free();
  204. }
  205. // Add the new node at the end of queue and change rear
  206. temp->prev = q->rear;
  207. // allocate a new array for our new item
  208. #if NODE_TYPE == LINKED
  209. if (!q->rear->next) {
  210. q->rear->next = malloc(sizeof(*q->rear->next));
  211. } else {
  212. abort();
  213. }
  214. // update rear->next to point to the new item
  215. q->rear->next = temp;
  216. // update rear to point to the rear->next, which is the item we just added, updating the pointer rear from our old item to our new item
  217. q->rear = q->rear->next;
  218. #elif NODE_TYPE == TREE
  219. struct QNode * p = q->rear;
  220. if (type == NODE_TYPE_BRANCH_CHOICE_START) {
  221. while(p) {
  222. if (p->type == NODE_TYPE_BRANCH_START) {
  223. puts("FOUND BRANCH START");
  224. q->rear = p;
  225. break;
  226. }
  227. if (p->prev) p = p->prev;
  228. else p = NULL;
  229. }
  230. }
  231. // allocate a new array for our new item
  232. if (!q->rear->branch) {
  233. q->rear->branch_count = 1;
  234. q->rear->branch = malloc(sizeof(struct QNode)*q->rear->branch_count);
  235. } else {
  236. q->rear->branch_count++;
  237. q->rear->branch = realloc(q->rear->branch, sizeof(struct QNode)*q->rear->branch_count);
  238. }
  239. // update rear->next to point to the new item
  240. q->rear->branch[q->rear->branch_count-1] = temp;
  241. // update rear to point to the rear->next, which is the item we just added, updating the pointer rear from our old item to our new item
  242. q->rear = q->rear->branch[q->rear->branch_count-1];
  243. #endif
  244. }
  245. struct QNode * load_asm(struct Queue **q)
  246. {
  247. // If queue is empty, return NULL.
  248. if ((q) == NULL) return NULL;
  249. if ((*q) == NULL) return NULL;
  250. if ((*q)->front == NULL)
  251. return NULL;
  252. // Store previous front and move front one node ahead
  253. struct QNode *temp = (*q)->front;
  254. // check if front->next is NULL, if NULL it means we have reached the end of the queue
  255. (*q)->front = (*q)->front->next;
  256. // If front becomes NULL, then change rear also as NULL
  257. if ((*q)->front == NULL)
  258. (*q)->rear = NULL;
  259. return temp;
  260. }
  261. #define add_indent(indent) { int i = 0; for (; i < indent; i++) printf(" "); }
  262. struct Queue * list = NULL;
  263. void printnode(struct QNode * p) {
  264. int indentation = p->level;
  265. add_indent(indentation);
  266. if (p->type == NODE_TYPE_BRANCH_START) {
  267. add_indent(indentation);
  268. printf("branch start\n");
  269. }
  270. else if (p->type == NODE_TYPE_BRANCH_END) {
  271. add_indent(indentation);
  272. printf("branch end\n");
  273. }
  274. else if (p->type == NODE_TYPE_BRANCH_CHOICE_START) {
  275. add_indent(indentation);
  276. printf("branch choice start\n");
  277. }
  278. else if (p->type == NODE_TYPE_BRANCH_CHOICE_END) {
  279. add_indent(indentation);
  280. printf("branch choice end\n");
  281. }
  282. else if (p->type == NODE_TYPE_NORMAL) {
  283. add_indent(indentation);
  284. printf("%d -> %d (data: %d)\n", p->index, p->ref, p->data);
  285. }
  286. #if NODE_TYPE == TREE
  287. // pi(p->branch_count)
  288. #endif
  289. }
  290. void print_prev(struct QNode * p) {
  291. puts("NULL");
  292. while(p) {
  293. printnode(p);
  294. if (p->prev) p = p->prev;
  295. else p = NULL;
  296. }
  297. }
  298. void print_(struct QNode * p) {
  299. while(p) {
  300. printnode(p);
  301. #if NODE_TYPE == LINKED
  302. p = p->next;
  303. #elif NODE_TYPE == TREE
  304. if (p->next) p = p->next;
  305. else p = NULL;
  306. #endif
  307. }
  308. puts("NULL");
  309. }
  310. void print(struct QNode * p) {
  311. while(p) {
  312. printnode(p);
  313. // #if NODE_TYPE == TREE
  314. // if (p->branch_count) {
  315. // pi(p->branch_count)
  316. // puts("printing branches");
  317. // for (int i = 0; i < p->branch_count; i++) {
  318. // printf("printing branch %d\n", i);
  319. // print_(p->branch[i]);
  320. // printf("finished printing branch %d\n", i);
  321. // }
  322. // }
  323. // #endif
  324. pp(p->next)
  325. p = p->next;
  326. }
  327. puts("NULL");
  328. }
  329. void fix(struct Queue *p);
  330. void add(struct Queue **q, int data) {
  331. if (!(*q)) (*q) = createQueue();
  332. store_asm((*q), data, NODE_TYPE_NORMAL);
  333. }
  334. void add_branch(struct Queue **q) {
  335. if (!(*q)) (*q) = createQueue();
  336. store_asm((*q), 0, NODE_TYPE_BRANCH_START);
  337. global_indent++;
  338. }
  339. void end_branch(struct Queue **q) {
  340. global_indent--;
  341. if (!(*q)) (*q) = createQueue();
  342. store_asm((*q), 0, NODE_TYPE_BRANCH_END);
  343. }
  344. void add_branch_choice(struct Queue **q) {
  345. if (!(*q)) (*q) = createQueue();
  346. store_asm((*q), 0, NODE_TYPE_BRANCH_CHOICE_START);
  347. global_indent++;
  348. }
  349. void end_branch_choice(struct Queue **q) {
  350. global_indent--;
  351. if (!(*q)) (*q) = createQueue();
  352. // if we have a branch_end, we need to go backwards in out linked list to the node that came before the branch start
  353. store_asm((*q), 0, NODE_TYPE_BRANCH_CHOICE_END);
  354. }
  355. int main(void) {
  356. index_start = 0;
  357. ref_start = 1;
  358. /* attempt to visualize this in a expression grammar
  359. root ::= 0 A 61
  360. A ::=
  361. 1 2 B
  362. 5 6 C
  363. B ::=
  364. 3 4
  365. C ::=
  366. 7 8 D
  367. D ::=
  368. 9 10 F R
  369. 57 58 S
  370. F ::=
  371. G 41 42 P 45 46 47
  372. 48 49 Q 52 53 54
  373. G ::=
  374. 11 12 H
  375. 15 16 I
  376. H ::=
  377. 13 14
  378. I ::=
  379. 17 18 J
  380. J ::=
  381. 19 20 K N
  382. 37 38 O
  383. K ::=
  384. 21 22 L 25 26 27
  385. 28 29 M 32 33 34
  386. L ::=
  387. 23 24
  388. M ::=
  389. 30 31
  390. N ::=
  391. 35 36
  392. O ::=
  393. 39 40
  394. P ::=
  395. 43 44
  396. Q ::=
  397. 50 51
  398. R ::=
  399. 55 56
  400. S ::=
  401. 59 60
  402. structure:
  403. root: 0 A 61 > NULL
  404. A: 1 2 B
  405. B: 3 4 > 61 // currently 4 > 25
  406. A: 5 6 C
  407. C: 7 8 D
  408. D: 9 10 F R
  409. F: G 41 42 P 45 46 47 > 55 (R) // currently 47 > 52
  410. G: 11 12 H
  411. H: 13 14 > 41 // currently 14 > 25
  412. G: 15 16 I
  413. I: 16 18 J
  414. J: 19 20 K N
  415. K: 21 22 L 25 26 27 > 35 (N) // currently 27 > 32
  416. L: 23 24 > 25
  417. K: 28 29 M 32 33 34 > 35 (N)
  418. M: 30 31 > 32
  419. N: 35 36 > 41
  420. J: 37 38 O
  421. O: 39 40 > 41
  422. P: 43 44 > 45
  423. F: 48 49 Q 52 53 54 > 55 (R)
  424. Q: 50 51 > 52
  425. R: 55 56 > 61
  426. D: 57 58 S
  427. S: 59 60 > 61
  428. add(&list, 1);
  429. add_branch(&list);
  430. add_branch_choice(&list);
  431. add(&list, 2);
  432. add(&list, 3);
  433. add_branch(&list);
  434. add_branch_choice(&list);
  435. add(&list, 4);
  436. add(&list, 5);
  437. end_branch_choice(&list);
  438. end_branch(&list);
  439. end_branch_choice(&list);
  440. add_branch_choice(&list);
  441. add(&list, 6);
  442. add(&list, 7);
  443. add_branch(&list);
  444. add_branch_choice(&list);
  445. add(&list, 8);
  446. add(&list, 9);
  447. add_branch(&list);
  448. add_branch_choice(&list);
  449. add(&list, 10);
  450. add(&list, 11);
  451. add_branch(&list);
  452. add_branch_choice(&list);
  453. add_branch(&list);
  454. add_branch_choice(&list);
  455. add(&list, 12);
  456. add(&list, 13);
  457. add_branch(&list);
  458. add_branch_choice(&list);
  459. add(&list, 14);
  460. add(&list, 15);
  461. end_branch_choice(&list);
  462. end_branch(&list);
  463. end_branch_choice(&list);
  464. add_branch_choice(&list);
  465. add(&list, 16);
  466. add(&list, 17);
  467. add_branch(&list);
  468. add_branch_choice(&list);
  469. add(&list, 18);
  470. add(&list, 19);
  471. add_branch(&list);
  472. add_branch_choice(&list);
  473. add(&list, 20);
  474. add(&list, 21);
  475. add_branch(&list);
  476. add_branch_choice(&list);
  477. add(&list, 22);
  478. add(&list, 23);
  479. add_branch(&list);
  480. add_branch_choice(&list);
  481. add(&list, 24);
  482. add(&list, 25);
  483. end_branch_choice(&list);
  484. end_branch(&list);
  485. add(&list, 26);
  486. add(&list, 27);
  487. add(&list, 28);
  488. end_branch_choice(&list);
  489. add_branch_choice(&list);
  490. add(&list, 29);
  491. add(&list, 30);
  492. add_branch(&list);
  493. add_branch_choice(&list);
  494. add(&list, 31);
  495. add(&list, 32);
  496. end_branch_choice(&list);
  497. end_branch(&list);
  498. add(&list, 33);
  499. add(&list, 34);
  500. add(&list, 35);
  501. end_branch_choice(&list);
  502. end_branch(&list);
  503. add_branch(&list);
  504. add_branch_choice(&list);
  505. add(&list, 36);
  506. add(&list, 37);
  507. end_branch_choice(&list);
  508. end_branch(&list);
  509. end_branch_choice(&list);
  510. add_branch_choice(&list);
  511. add(&list, 38);
  512. add(&list, 39);
  513. add_branch(&list);
  514. add_branch_choice(&list);
  515. add(&list, 40);
  516. add(&list, 41);
  517. end_branch_choice(&list);
  518. end_branch(&list);
  519. end_branch_choice(&list);
  520. end_branch(&list);
  521. end_branch_choice(&list);
  522. end_branch(&list);
  523. end_branch_choice(&list);
  524. end_branch(&list);
  525. add(&list, 42);
  526. add(&list, 43);
  527. add_branch(&list);
  528. add_branch_choice(&list);
  529. add(&list, 44);
  530. add(&list, 45);
  531. end_branch_choice(&list);
  532. end_branch(&list);
  533. add(&list, 46);
  534. add(&list, 47);
  535. add(&list, 48);
  536. end_branch_choice(&list);
  537. add_branch_choice(&list);
  538. add(&list, 49);
  539. add(&list, 50);
  540. add_branch(&list);
  541. add_branch_choice(&list);
  542. add(&list, 51);
  543. add(&list, 52);
  544. end_branch_choice(&list);
  545. end_branch(&list);
  546. add(&list, 53);
  547. add(&list, 54);
  548. add(&list, 55);
  549. end_branch_choice(&list);
  550. end_branch(&list);
  551. add_branch(&list);
  552. add_branch_choice(&list);
  553. add(&list, 56);
  554. add(&list, 57);
  555. end_branch_choice(&list);
  556. end_branch(&list);
  557. end_branch_choice(&list);
  558. add_branch_choice(&list);
  559. add(&list, 58);
  560. add(&list, 59);
  561. add_branch(&list);
  562. add_branch_choice(&list);
  563. add(&list, 60);
  564. add(&list, 61);
  565. end_branch_choice(&list);
  566. end_branch(&list);
  567. end_branch_choice(&list);
  568. end_branch(&list);
  569. end_branch_choice(&list);
  570. end_branch(&list);
  571. end_branch_choice(&list);
  572. end_branch(&list);
  573. add(&list, 62);
  574. */
  575. /* attempt to visualize this in a expression grammar
  576. root ::= 1 A 13
  577. A ::=
  578. 2 3 B 6
  579. 7 8 C
  580. B ::=
  581. 4
  582. C ::=
  583. 9 10 D
  584. D ::=
  585. 11
  586. structure:
  587. root: 1 A 13 > NULL
  588. A: 2 3 B 6 > 13
  589. B: 4 5 > 6
  590. A: 7 8 C
  591. C: 9 10 D
  592. D: 11 > 13
  593. */
  594. add(&list, 1);
  595. add_branch(&list);
  596. add_branch_choice(&list);
  597. add(&list, 2);
  598. // add(&list, 3);
  599. // add_branch(&list);
  600. // add_branch_choice(&list);
  601. // add(&list, 4);
  602. // add(&list, 5);
  603. // end_branch_choice(&list);
  604. // end_branch(&list);
  605. // add(&list, 6);
  606. end_branch_choice(&list);
  607. add_branch_choice(&list);
  608. // add(&list, 7);
  609. add(&list, 8);
  610. // add_branch(&list);
  611. // add_branch_choice(&list);
  612. // add(&list, 9);
  613. // add(&list, 10);
  614. // add_branch(&list);
  615. // add_branch_choice(&list);
  616. // add(&list, 11);
  617. // add(&list, 12);
  618. // end_branch_choice(&list);
  619. // end_branch(&list);
  620. // end_branch_choice(&list);
  621. // end_branch(&list);
  622. end_branch_choice(&list);
  623. end_branch(&list);
  624. add(&list, 13);
  625. print(list->front);
  626. puts("printing previous");
  627. print_prev(list->rear);
  628. // fix(list);
  629. // this part should be left to the garbage collector to clean up
  630. #if NODE_TYPE == LINKED
  631. psize_t(free_asm(&list));
  632. #endif
  633. return 0;
  634. }
  635. void print_indentation(struct QNode * p, int indentation) {
  636. printf("printing nodes with an indentation level of %d\n", indentation);
  637. while(p) {
  638. if (p->level == indentation) {
  639. add_indent(indentation);
  640. if (p->type == NODE_TYPE_BRANCH_START) {
  641. add_indent(indentation);
  642. printf("branch start\n");
  643. }
  644. else if (p->type == NODE_TYPE_BRANCH_END) {
  645. add_indent(indentation);
  646. printf("branch end\n");
  647. }
  648. else if (p->type == NODE_TYPE_BRANCH_CHOICE_START) {
  649. add_indent(indentation);
  650. printf("branch choice start\n");
  651. }
  652. else if (p->type == NODE_TYPE_BRANCH_CHOICE_END) {
  653. add_indent(indentation);
  654. printf("branch choice end\n");
  655. }
  656. else if (p->type == NODE_TYPE_NORMAL) {
  657. add_indent(indentation);
  658. printf("%d -> %d (data: %d)\n", p->index, p->ref, p->data);
  659. }
  660. }
  661. p = p->next;
  662. // #if NODE_TYPE == LINKED
  663. // #elif NODE_TYPE == TREE
  664. // else p = NULL;
  665. // #endif
  666. }
  667. }
  668. void fix(struct Queue * list) {
  669. int indent = 0;
  670. print_indentation(list->front, indent++);
  671. print_indentation(list->front, indent++);
  672. print_indentation(list->front, indent++);
  673. print_indentation(list->front, indent++);
  674. print_indentation(list->front, indent++);
  675. puts("NULL");
  676. }
  677.