packcr 0.0.6 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/lib/packcr/cli.rb +18 -16
  3. data/lib/packcr/code_block.rb +0 -1
  4. data/lib/packcr/context.rb +19 -17
  5. data/lib/packcr/generated/context.rb +440 -0
  6. data/lib/packcr/generated/node/action_node.rb +60 -0
  7. data/lib/packcr/generated/node/alternate_node.rb +98 -0
  8. data/lib/packcr/generated/node/capture_node.rb +39 -0
  9. data/lib/packcr/generated/node/charclass_node.rb +372 -0
  10. data/lib/packcr/generated/node/eof_node.rb +20 -0
  11. data/lib/packcr/generated/node/error_node.rb +67 -0
  12. data/lib/packcr/generated/node/expand_node.rb +30 -0
  13. data/lib/packcr/generated/node/predicate_node.rb +140 -0
  14. data/lib/packcr/generated/node/quantity_node.rb +167 -0
  15. data/lib/packcr/generated/node/reference_node.rb +70 -0
  16. data/lib/packcr/generated/node/rule_node.rb +63 -0
  17. data/lib/packcr/generated/node/sequence_node.rb +42 -0
  18. data/lib/packcr/generated/node/string_node.rb +60 -0
  19. data/lib/packcr/generator.rb +2 -1
  20. data/lib/packcr/node/action_node.rb +4 -2
  21. data/lib/packcr/node/alternate_node.rb +3 -1
  22. data/lib/packcr/node/capture_node.rb +3 -1
  23. data/lib/packcr/node/charclass_node.rb +24 -28
  24. data/lib/packcr/node/eof_node.rb +4 -2
  25. data/lib/packcr/node/error_node.rb +3 -1
  26. data/lib/packcr/node/expand_node.rb +8 -5
  27. data/lib/packcr/node/predicate_node.rb +4 -2
  28. data/lib/packcr/node/quantity_node.rb +12 -10
  29. data/lib/packcr/node/reference_node.rb +11 -5
  30. data/lib/packcr/node/root_node.rb +1 -0
  31. data/lib/packcr/node/rule_node.rb +7 -4
  32. data/lib/packcr/node/sequence_node.rb +3 -1
  33. data/lib/packcr/node/string_node.rb +9 -6
  34. data/lib/packcr/node.rb +3 -5
  35. data/lib/packcr/parser.rb +4375 -4056
  36. data/lib/packcr/stream.rb +17 -12
  37. data/lib/packcr/templates/context/source.c.erb +187 -410
  38. data/lib/packcr/templates/context/source.rb.erb +91 -156
  39. data/lib/packcr/templates/node/action.c.erb +3 -3
  40. data/lib/packcr/templates/node/action.rb.erb +2 -2
  41. data/lib/packcr/templates/node/alternate.c.erb +8 -8
  42. data/lib/packcr/templates/node/alternate.rb.erb +4 -5
  43. data/lib/packcr/templates/node/capture.c.erb +6 -6
  44. data/lib/packcr/templates/node/capture.rb.erb +4 -4
  45. data/lib/packcr/templates/node/charclass.c.erb +12 -12
  46. data/lib/packcr/templates/node/charclass.rb.erb +6 -6
  47. data/lib/packcr/templates/node/charclass_any.c.erb +3 -3
  48. data/lib/packcr/templates/node/charclass_any.rb.erb +2 -2
  49. data/lib/packcr/templates/node/charclass_fail.c.erb +1 -1
  50. data/lib/packcr/templates/node/charclass_one.c.erb +8 -8
  51. data/lib/packcr/templates/node/charclass_one.rb.erb +6 -6
  52. data/lib/packcr/templates/node/charclass_utf8.c.erb +7 -7
  53. data/lib/packcr/templates/node/charclass_utf8.rb.erb +3 -3
  54. data/lib/packcr/templates/node/charclass_utf8_reverse.rb.erb +5 -5
  55. data/lib/packcr/templates/node/eof.c.erb +1 -1
  56. data/lib/packcr/templates/node/error.c.erb +7 -7
  57. data/lib/packcr/templates/node/error.rb.erb +2 -2
  58. data/lib/packcr/templates/node/expand.c.erb +5 -5
  59. data/lib/packcr/templates/node/expand.rb.erb +3 -3
  60. data/lib/packcr/templates/node/predicate.c.erb +10 -10
  61. data/lib/packcr/templates/node/predicate.rb.erb +6 -6
  62. data/lib/packcr/templates/node/predicate_neg.c.erb +8 -8
  63. data/lib/packcr/templates/node/predicate_neg.rb.erb +6 -6
  64. data/lib/packcr/templates/node/{quantify_many.c.erb → quantity_many.c.erb} +11 -11
  65. data/lib/packcr/templates/node/{quantify_many.rb.erb → quantity_many.rb.erb} +9 -9
  66. data/lib/packcr/templates/node/{quantify_one.c.erb → quantity_one.c.erb} +7 -7
  67. data/lib/packcr/templates/node/{quantify_one.rb.erb → quantity_one.rb.erb} +4 -4
  68. data/lib/packcr/templates/node/reference.c.erb +14 -2
  69. data/lib/packcr/templates/node/reference.rb.erb +16 -4
  70. data/lib/packcr/templates/node/reference_reverse.rb.erb +16 -4
  71. data/lib/packcr/templates/node/rule.c.erb +9 -2
  72. data/lib/packcr/templates/node/rule.rb.erb +26 -19
  73. data/lib/packcr/templates/node/string_many.c.erb +5 -5
  74. data/lib/packcr/templates/node/string_many.rb.erb +3 -3
  75. data/lib/packcr/templates/node/string_one.c.erb +4 -4
  76. data/lib/packcr/templates/node/string_one.rb.erb +3 -3
  77. data/lib/packcr/util.rb +21 -16
  78. data/lib/packcr/version.rb +1 -1
  79. data/lib/packcr.rb +8 -11
  80. metadata +37 -9
  81. data/lib/packcr/tokenizer.rb +0 -2948
@@ -81,8 +81,8 @@ typedef struct pcc_range_tag {
81
81
  size_t start;
82
82
  size_t end;
83
83
  <%- if @location -%>
84
- pcc_location_t *start_loc_ptr;
85
- pcc_location_t *end_loc_ptr;
84
+ pcc_location_t start_loc;
85
+ pcc_location_t end_loc;
86
86
  <%- end -%>
87
87
  } pcc_range_t;
88
88
 
@@ -171,31 +171,22 @@ typedef struct pcc_thunk_chunk_tag {
171
171
  <%- end -%>
172
172
  } pcc_thunk_chunk_t;
173
173
 
174
- typedef struct pcc_lr_entry_tag pcc_lr_entry_t;
174
+ typedef struct pcc_lr_memo_tag pcc_lr_memo_t;
175
175
 
176
- typedef enum pcc_lr_answer_type_tag {
177
- PCC_LR_ANSWER_LR,
178
- PCC_LR_ANSWER_CHUNK
179
- } pcc_lr_answer_type_t;
180
-
181
- typedef union pcc_lr_answer_data_tag {
182
- pcc_lr_entry_t *lr;
183
- pcc_thunk_chunk_t *chunk;
184
- } pcc_lr_answer_data_t;
185
-
186
- typedef struct pcc_lr_answer_tag pcc_lr_answer_t;
187
-
188
- struct pcc_lr_answer_tag {
189
- pcc_lr_answer_type_t type;
190
- pcc_lr_answer_data_t data;
191
- size_t pos; /* the absolute position in the input */
176
+ struct pcc_lr_memo_tag {
177
+ size_t offset;
192
178
  <%- if @location -%>
193
- pcc_location_t pos_loc;
179
+ pcc_location_t offset_loc;
194
180
  <%- end -%>
195
- pcc_lr_answer_t *hold;
181
+ pcc_lr_memo_t *hold;
182
+ pcc_thunk_chunk_t *chunk;
183
+ pcc_bool_t fail;
184
+ pcc_bool_t grow;
196
185
  };
197
186
 
198
- typedef pcc_thunk_chunk_t *(*pcc_rule_t)(pcc_context_t *);
187
+ typedef struct pcc_rule_set_tag pcc_rule_set_t;
188
+
189
+ typedef pcc_thunk_chunk_t *(*pcc_rule_t)(pcc_context_t *, size_t<% if @location %>, pcc_location_t<% end %>, pcc_rule_set_t*);
199
190
 
200
191
  typedef struct pcc_rule_set_tag {
201
192
  pcc_rule_t *buf;
@@ -203,52 +194,24 @@ typedef struct pcc_rule_set_tag {
203
194
  size_t len;
204
195
  } pcc_rule_set_t;
205
196
 
206
- typedef struct pcc_lr_head_tag pcc_lr_head_t;
207
-
208
- struct pcc_lr_head_tag {
209
- pcc_rule_t rule;
210
- pcc_rule_set_t invol;
211
- pcc_rule_set_t eval;
212
- pcc_lr_head_t *hold;
213
- };
214
-
215
- typedef struct pcc_lr_memo_tag {
197
+ typedef struct pcc_lr_memo_map_entry_tag {
216
198
  pcc_rule_t rule;
217
- pcc_lr_answer_t *answer;
218
- } pcc_lr_memo_t;
199
+ pcc_lr_memo_t *memo;
200
+ } pcc_lr_memo_map_entry_t;
219
201
 
220
202
  typedef struct pcc_lr_memo_map_tag {
221
- pcc_lr_memo_t *buf;
203
+ pcc_lr_memo_map_entry_t *buf;
222
204
  size_t max;
223
205
  size_t len;
224
206
  } pcc_lr_memo_map_t;
225
207
 
226
- typedef struct pcc_lr_table_entry_tag {
227
- pcc_lr_head_t *head; /* just a reference */
228
- pcc_lr_memo_map_t memos;
229
- pcc_lr_answer_t *hold_a;
230
- pcc_lr_head_t *hold_h;
231
- } pcc_lr_table_entry_t;
232
-
233
208
  typedef struct pcc_lr_table_tag {
234
- pcc_lr_table_entry_t **buf;
209
+ pcc_lr_memo_map_t **buf;
235
210
  size_t max;
236
211
  size_t len;
237
212
  size_t ofs;
238
213
  } pcc_lr_table_t;
239
214
 
240
- struct pcc_lr_entry_tag {
241
- pcc_rule_t rule;
242
- pcc_thunk_chunk_t *seed; /* just a reference */
243
- pcc_lr_head_t *head; /* just a reference */
244
- };
245
-
246
- typedef struct pcc_lr_stack_tag {
247
- pcc_lr_entry_t **buf;
248
- size_t max;
249
- size_t len;
250
- } pcc_lr_stack_t;
251
-
252
215
  typedef struct pcc_memory_entry_tag pcc_memory_entry_t;
253
216
  typedef struct pcc_memory_pool_tag pcc_memory_pool_t;
254
217
 
@@ -269,21 +232,19 @@ typedef struct pcc_memory_recycler_tag {
269
232
  } pcc_memory_recycler_t;
270
233
 
271
234
  struct <%= prefix %>_context_tag {
272
- size_t pos; /* the position in the input of the first character currently buffered */
273
- size_t cur; /* the current parsing position in the character buffer */
235
+ size_t buffer_start_position; /* the position in the input of the first character currently buffered */
236
+ size_t position_offset; /* the current parsing position in the character buffer */
274
237
  <%- if @location -%>
275
- pcc_location_t pos_loc;
276
- pcc_location_t cur_loc;
238
+ pcc_location_t buffer_start_position_loc;
239
+ pcc_location_t position_offset_loc;
277
240
  <%- end -%>
278
241
  size_t level;
279
242
  pcc_char_array_t buffer;
280
243
  pcc_lr_table_t lrtable;
281
- pcc_lr_stack_t lrstack;
282
244
  pcc_thunk_array_t thunks;
283
245
  pcc_auxil_t auxil;
284
246
  pcc_memory_recycler_t thunk_chunk_recycler;
285
- pcc_memory_recycler_t lr_head_recycler;
286
- pcc_memory_recycler_t lr_answer_recycler;
247
+ pcc_memory_recycler_t lr_memo_recycler;
287
248
  };
288
249
 
289
250
  #ifndef PCC_ERROR
@@ -424,12 +385,6 @@ MARK_FUNC_AS_USED
424
385
  static void pcc_capture_table__resize(pcc_auxil_t auxil, pcc_capture_table_t *table, size_t len) {
425
386
  size_t i;
426
387
  for (i = len; i < table->len; i++) PCC_FREE(auxil, table->buf[i].string);
427
- <%- if @location -%>
428
- for (i = len; i < table->len; i++) {
429
- PCC_FREE(auxil, table->buf[i].range.start_loc_ptr);
430
- PCC_FREE(auxil, table->buf[i].range.end_loc_ptr);
431
- }
432
- <%- end -%>
433
388
  if (table->max < len) {
434
389
  size_t m = table->max;
435
390
  if (m == 0) m = PCC_ARRAY_MIN_SIZE;
@@ -442,10 +397,8 @@ static void pcc_capture_table__resize(pcc_auxil_t auxil, pcc_capture_table_t *ta
442
397
  table->buf[i].range.start = 0;
443
398
  table->buf[i].range.end = 0;
444
399
  <%- if @location -%>
445
- table->buf[i].range.start_loc_ptr = (pcc_location_t *)PCC_MALLOC(auxil, sizeof(pcc_location_t));
446
- table->buf[i].range.end_loc_ptr = (pcc_location_t *)PCC_MALLOC(auxil, sizeof(pcc_location_t));
447
- pcc_location_init(table->buf[i].range.start_loc_ptr);
448
- pcc_location_init(table->buf[i].range.end_loc_ptr);
400
+ pcc_location_init(&table->buf[i].range.start_loc);
401
+ pcc_location_init(&table->buf[i].range.end_loc);
449
402
  <%- end -%>
450
403
  table->buf[i].string = NULL;
451
404
  }
@@ -456,10 +409,6 @@ static void pcc_capture_table__term(pcc_auxil_t auxil, pcc_capture_table_t *tabl
456
409
  while (table->len > 0) {
457
410
  table->len--;
458
411
  PCC_FREE(auxil, table->buf[table->len].string);
459
- <%- if @location -%>
460
- PCC_FREE(auxil, table->buf[table->len].range.start_loc_ptr);
461
- PCC_FREE(auxil, table->buf[table->len].range.end_loc_ptr);
462
- <%- end -%>
463
412
  }
464
413
  PCC_FREE(auxil, table->buf);
465
414
  }
@@ -498,6 +447,10 @@ static pcc_thunk_t *pcc_thunk__create_leaf(pcc_auxil_t auxil, pcc_action_t actio
498
447
  pcc_capture_const_table__resize(auxil, &thunk->data.leaf.capts, captc);
499
448
  thunk->data.leaf.capt0.range.start = 0;
500
449
  thunk->data.leaf.capt0.range.end = 0;
450
+ <%- if @location -%>
451
+ pcc_location_init(&thunk->data.leaf.capt0.range.start_loc);
452
+ pcc_location_init(&thunk->data.leaf.capt0.range.end_loc);
453
+ <%- end -%>
501
454
  thunk->data.leaf.capt0.string = NULL;
502
455
  thunk->data.leaf.action = action;
503
456
  return thunk;
@@ -655,103 +608,40 @@ static pcc_bool_t pcc_rule_set__add(pcc_auxil_t auxil, pcc_rule_set_t *set, pcc_
655
608
  return PCC_TRUE;
656
609
  }
657
610
 
658
- static pcc_bool_t pcc_rule_set__remove(pcc_auxil_t auxil, pcc_rule_set_t *set, pcc_rule_t rule) {
659
- const size_t i = pcc_rule_set__index(auxil, set, rule);
660
- if (i == PCC_VOID_VALUE) return PCC_FALSE;
661
- memmove(set->buf + i, set->buf + (i + 1), sizeof(pcc_rule_t) * (set->len - (i + 1)));
662
- return PCC_TRUE;
663
- }
664
-
665
- static void pcc_rule_set__clear(pcc_auxil_t auxil, pcc_rule_set_t *set) {
666
- set->len = 0;
667
- }
668
-
669
- static void pcc_rule_set__copy(pcc_auxil_t auxil, pcc_rule_set_t *set, const pcc_rule_set_t *src) {
670
- size_t i;
671
- pcc_rule_set__clear(auxil, set);
672
- for (i = 0; i < src->len; i++) {
673
- pcc_rule_set__add(auxil, set, src->buf[i]);
674
- }
675
- }
676
-
677
611
  static void pcc_rule_set__term(pcc_auxil_t auxil, pcc_rule_set_t *set) {
678
612
  PCC_FREE(auxil, set->buf);
679
613
  }
680
614
 
681
- static pcc_lr_head_t *pcc_lr_head__create(pcc_context_t *ctx, pcc_rule_t rule) {
682
- pcc_lr_head_t *const head = (pcc_lr_head_t *)pcc_memory_recycler__supply(ctx->auxil, &ctx->lr_head_recycler);
683
- head->rule = rule;
684
- pcc_rule_set__init(ctx->auxil, &head->invol);
685
- pcc_rule_set__init(ctx->auxil, &head->eval);
686
- head->hold = NULL;
687
- return head;
688
- }
689
-
690
- static void pcc_lr_head__destroy(pcc_context_t *ctx, pcc_lr_head_t *head) {
691
- if (head == NULL) return;
692
- pcc_lr_head__destroy(ctx, head->hold);
693
- pcc_rule_set__term(ctx->auxil, &head->eval);
694
- pcc_rule_set__term(ctx->auxil, &head->invol);
695
- pcc_memory_recycler__recycle(ctx->auxil, &ctx->lr_head_recycler, head);
696
- }
697
-
698
- static void pcc_lr_entry__destroy(pcc_auxil_t auxil, pcc_lr_entry_t *lr);
699
-
700
- static pcc_lr_answer_t *pcc_lr_answer__create(pcc_context_t *ctx, pcc_lr_answer_type_t type, size_t pos<% if @location %>, pcc_location_t pos_loc<% end %>) {
701
- pcc_lr_answer_t *answer = (pcc_lr_answer_t *)pcc_memory_recycler__supply(ctx->auxil, &ctx->lr_answer_recycler);
702
- answer->type = type;
703
- answer->pos = pos;
615
+ static pcc_lr_memo_t *pcc_lr_memo__create(pcc_context_t *ctx, size_t offset<% if @location %>, pcc_location_t offset_loc<% end %>) {
616
+ pcc_lr_memo_t *memo = (pcc_lr_memo_t *)pcc_memory_recycler__supply(ctx->auxil, &ctx->lr_memo_recycler);
617
+ memo->offset = offset;
704
618
  <%- if @location -%>
705
- answer->pos_loc = pos_loc;
619
+ memo->offset_loc = offset_loc;
706
620
  <%- end -%>
707
- answer->hold = NULL;
708
- switch (answer->type) {
709
- case PCC_LR_ANSWER_LR:
710
- answer->data.lr = NULL;
711
- break;
712
- case PCC_LR_ANSWER_CHUNK:
713
- answer->data.chunk = NULL;
714
- break;
715
- default: /* unknown */
716
- PCC_FREE(ctx->auxil, answer);
717
- answer = NULL;
621
+ memo->chunk = NULL;
622
+ memo->fail = PCC_TRUE;
623
+ memo->grow = PCC_FALSE;
624
+ memo->hold = NULL;
625
+ return memo;
626
+ }
627
+
628
+ static void pcc_lr_memo__set_chunk(pcc_context_t *ctx, pcc_lr_memo_t *memo, pcc_thunk_chunk_t *chunk) {
629
+ if (memo->chunk) {
630
+ pcc_lr_memo_t *const a = pcc_lr_memo__create(ctx, memo->offset<% if @location %>, memo->offset_loc<% end %>);
631
+ a->chunk = memo->chunk;
632
+ a->hold = memo->hold;
633
+ memo->hold = a;
718
634
  }
719
- return answer;
635
+ memo->chunk = chunk;
636
+ memo->fail = PCC_FALSE;
720
637
  }
721
638
 
722
- static void pcc_lr_answer__set_chunk(pcc_context_t *ctx, pcc_lr_answer_t *answer, pcc_thunk_chunk_t *chunk) {
723
- pcc_lr_answer_t *const a = pcc_lr_answer__create(ctx, answer->type, answer->pos<% if @location %>, answer->pos_loc<% end %>);
724
- switch (answer->type) {
725
- case PCC_LR_ANSWER_LR:
726
- a->data.lr = answer->data.lr;
727
- break;
728
- case PCC_LR_ANSWER_CHUNK:
729
- a->data.chunk = answer->data.chunk;
730
- break;
731
- default: /* unknown */
732
- break;
733
- }
734
- a->hold = answer->hold;
735
- answer->hold = a;
736
- answer->type = PCC_LR_ANSWER_CHUNK;
737
- answer->data.chunk = chunk;
738
- }
739
-
740
- static void pcc_lr_answer__destroy(pcc_context_t *ctx, pcc_lr_answer_t *answer) {
741
- while (answer != NULL) {
742
- pcc_lr_answer_t *const a = answer->hold;
743
- switch (answer->type) {
744
- case PCC_LR_ANSWER_LR:
745
- pcc_lr_entry__destroy(ctx->auxil, answer->data.lr);
746
- break;
747
- case PCC_LR_ANSWER_CHUNK:
748
- pcc_thunk_chunk__destroy(ctx, answer->data.chunk);
749
- break;
750
- default: /* unknown */
751
- break;
752
- }
753
- pcc_memory_recycler__recycle(ctx->auxil, &ctx->lr_answer_recycler, answer);
754
- answer = a;
639
+ static void pcc_lr_memo__destroy(pcc_context_t *ctx, pcc_lr_memo_t *memo) {
640
+ while (memo != NULL) {
641
+ pcc_lr_memo_t *const a = memo->hold;
642
+ pcc_thunk_chunk__destroy(ctx, memo->chunk);
643
+ pcc_memory_recycler__recycle(ctx->auxil, &ctx->lr_memo_recycler, memo);
644
+ memo = a;
755
645
  }
756
646
  }
757
647
 
@@ -769,11 +659,11 @@ static size_t pcc_lr_memo_map__index(pcc_context_t *ctx, pcc_lr_memo_map_t *map,
769
659
  return PCC_VOID_VALUE;
770
660
  }
771
661
 
772
- static void pcc_lr_memo_map__put(pcc_context_t *ctx, pcc_lr_memo_map_t *map, pcc_rule_t rule, pcc_lr_answer_t *answer) {
662
+ static void pcc_lr_memo_map__put(pcc_context_t *ctx, pcc_lr_memo_map_t *map, pcc_rule_t rule, pcc_lr_memo_t *memo) {
773
663
  const size_t i = pcc_lr_memo_map__index(ctx, map, rule);
774
664
  if (i != PCC_VOID_VALUE) {
775
- pcc_lr_answer__destroy(ctx, map->buf[i].answer);
776
- map->buf[i].answer = answer;
665
+ pcc_lr_memo__destroy(ctx, map->buf[i].memo);
666
+ map->buf[i].memo = memo;
777
667
  }
778
668
  else {
779
669
  if (map->max <= map->len) {
@@ -782,43 +672,38 @@ static void pcc_lr_memo_map__put(pcc_context_t *ctx, pcc_lr_memo_map_t *map, pcc
782
672
  if (m == 0) m = PCC_ARRAY_MIN_SIZE;
783
673
  while (m < n && m != 0) m <<= 1;
784
674
  if (m == 0) m = n;
785
- map->buf = (pcc_lr_memo_t *)PCC_REALLOC(ctx->auxil, map->buf, sizeof(pcc_lr_memo_t) * m);
675
+ map->buf = (pcc_lr_memo_map_entry_t *)PCC_REALLOC(ctx->auxil, map->buf, sizeof(pcc_lr_memo_map_entry_t) * m);
786
676
  map->max = m;
787
677
  }
788
678
  map->buf[map->len].rule = rule;
789
- map->buf[map->len].answer = answer;
679
+ map->buf[map->len].memo = memo;
790
680
  map->len++;
791
681
  }
792
682
  }
793
683
 
794
- static pcc_lr_answer_t *pcc_lr_memo_map__get(pcc_context_t *ctx, pcc_lr_memo_map_t *map, pcc_rule_t rule) {
684
+ static pcc_lr_memo_t *pcc_lr_memo_map__get(pcc_context_t *ctx, pcc_lr_memo_map_t *map, pcc_rule_t rule) {
795
685
  const size_t i = pcc_lr_memo_map__index(ctx, map, rule);
796
- return (i != PCC_VOID_VALUE) ? map->buf[i].answer : NULL;
686
+ return (i != PCC_VOID_VALUE) ? map->buf[i].memo : NULL;
797
687
  }
798
688
 
799
689
  static void pcc_lr_memo_map__term(pcc_context_t *ctx, pcc_lr_memo_map_t *map) {
800
690
  while (map->len > 0) {
801
691
  map->len--;
802
- pcc_lr_answer__destroy(ctx, map->buf[map->len].answer);
692
+ pcc_lr_memo__destroy(ctx, map->buf[map->len].memo);
803
693
  }
804
694
  PCC_FREE(ctx->auxil, map->buf);
805
695
  }
806
696
 
807
- static pcc_lr_table_entry_t *pcc_lr_table_entry__create(pcc_context_t *ctx) {
808
- pcc_lr_table_entry_t *const entry = (pcc_lr_table_entry_t *)PCC_MALLOC(ctx->auxil, sizeof(pcc_lr_table_entry_t));
809
- entry->head = NULL;
810
- pcc_lr_memo_map__init(ctx->auxil, &entry->memos);
811
- entry->hold_a = NULL;
812
- entry->hold_h = NULL;
813
- return entry;
697
+ static pcc_lr_memo_map_t *pcc_lr_memo_map__create(pcc_context_t *ctx) {
698
+ pcc_lr_memo_map_t *const memo = (pcc_lr_memo_map_t *)PCC_MALLOC(ctx->auxil, sizeof(pcc_lr_memo_map_t));
699
+ pcc_lr_memo_map__init(ctx->auxil, memo);
700
+ return memo;
814
701
  }
815
702
 
816
- static void pcc_lr_table_entry__destroy(pcc_context_t *ctx, pcc_lr_table_entry_t *entry) {
817
- if (entry == NULL) return;
818
- pcc_lr_head__destroy(ctx, entry->hold_h);
819
- pcc_lr_answer__destroy(ctx, entry->hold_a);
820
- pcc_lr_memo_map__term(ctx, &entry->memos);
821
- PCC_FREE(ctx->auxil, entry);
703
+ static void pcc_lr_memo_map__destroy(pcc_context_t *ctx, pcc_lr_memo_map_t *memo) {
704
+ if (memo == NULL) return;
705
+ pcc_lr_memo_map__term(ctx, memo);
706
+ PCC_FREE(ctx->auxil, memo);
822
707
  }
823
708
 
824
709
  static void pcc_lr_table__init(pcc_auxil_t auxil, pcc_lr_table_t *table) {
@@ -830,67 +715,38 @@ static void pcc_lr_table__init(pcc_auxil_t auxil, pcc_lr_table_t *table) {
830
715
 
831
716
  static void pcc_lr_table__resize(pcc_context_t *ctx, pcc_lr_table_t *table, size_t len) {
832
717
  size_t i;
833
- for (i = len; i < table->len; i++) pcc_lr_table_entry__destroy(ctx, table->buf[i]);
718
+ for (i = len; i < table->len; i++) pcc_lr_memo_map__destroy(ctx, table->buf[i]);
834
719
  if (table->max < len) {
835
720
  size_t m = table->max;
836
721
  if (m == 0) m = PCC_ARRAY_MIN_SIZE;
837
722
  while (m < len && m != 0) m <<= 1;
838
723
  if (m == 0) m = len;
839
- table->buf = (pcc_lr_table_entry_t **)PCC_REALLOC(ctx->auxil, table->buf, sizeof(pcc_lr_table_entry_t *) * m);
724
+ table->buf = (pcc_lr_memo_map_t **)PCC_REALLOC(ctx->auxil, table->buf, sizeof(pcc_lr_memo_map_t *) * m);
840
725
  table->max = m;
841
726
  }
842
727
  for (i = table->len; i < len; i++) table->buf[i] = NULL;
843
728
  table->len = len;
844
729
  }
845
730
 
846
- static void pcc_lr_table__set_head(pcc_context_t *ctx, pcc_lr_table_t *table, size_t index, pcc_lr_head_t *head) {
847
- index += table->ofs;
848
- if (index >= table->len) pcc_lr_table__resize(ctx, table, index + 1);
849
- if (table->buf[index] == NULL) table->buf[index] = pcc_lr_table_entry__create(ctx);
850
- table->buf[index]->head = head;
851
- }
852
-
853
- static void pcc_lr_table__hold_head(pcc_context_t *ctx, pcc_lr_table_t *table, size_t index, pcc_lr_head_t *head) {
854
- index += table->ofs;
855
- if (index >= table->len) pcc_lr_table__resize(ctx, table, index + 1);
856
- if (table->buf[index] == NULL) table->buf[index] = pcc_lr_table_entry__create(ctx);
857
- head->hold = table->buf[index]->hold_h;
858
- table->buf[index]->hold_h = head;
859
- }
860
-
861
- static void pcc_lr_table__set_answer(pcc_context_t *ctx, pcc_lr_table_t *table, size_t index, pcc_rule_t rule, pcc_lr_answer_t *answer) {
731
+ static void pcc_lr_table__set_memo(pcc_context_t *ctx, pcc_lr_table_t *table, size_t index, pcc_rule_t rule, pcc_lr_memo_t *memo) {
862
732
  index += table->ofs;
863
733
  if (index >= table->len) pcc_lr_table__resize(ctx, table, index + 1);
864
- if (table->buf[index] == NULL) table->buf[index] = pcc_lr_table_entry__create(ctx);
865
- pcc_lr_memo_map__put(ctx, &table->buf[index]->memos, rule, answer);
866
- }
867
-
868
- static void pcc_lr_table__hold_answer(pcc_context_t *ctx, pcc_lr_table_t *table, size_t index, pcc_lr_answer_t *answer) {
869
- index += table->ofs;
870
- if (index >= table->len) pcc_lr_table__resize(ctx, table, index + 1);
871
- if (table->buf[index] == NULL) table->buf[index] = pcc_lr_table_entry__create(ctx);
872
- answer->hold = table->buf[index]->hold_a;
873
- table->buf[index]->hold_a = answer;
874
- }
875
-
876
- static pcc_lr_head_t *pcc_lr_table__get_head(pcc_context_t *ctx, pcc_lr_table_t *table, size_t index) {
877
- index += table->ofs;
878
- if (index >= table->len || table->buf[index] == NULL) return NULL;
879
- return table->buf[index]->head;
734
+ if (table->buf[index] == NULL) table->buf[index] = pcc_lr_memo_map__create(ctx);
735
+ pcc_lr_memo_map__put(ctx, table->buf[index], rule, memo);
880
736
  }
881
737
 
882
- static pcc_lr_answer_t *pcc_lr_table__get_answer(pcc_context_t *ctx, pcc_lr_table_t *table, size_t index, pcc_rule_t rule) {
738
+ static pcc_lr_memo_t *pcc_lr_table__get_memo(pcc_context_t *ctx, pcc_lr_table_t *table, size_t index, pcc_rule_t rule) {
883
739
  index += table->ofs;
884
740
  if (index >= table->len || table->buf[index] == NULL) return NULL;
885
- return pcc_lr_memo_map__get(ctx, &table->buf[index]->memos, rule);
741
+ return pcc_lr_memo_map__get(ctx, table->buf[index], rule);
886
742
  }
887
743
 
888
744
  static void pcc_lr_table__shift(pcc_context_t *ctx, pcc_lr_table_t *table, size_t count) {
889
745
  size_t i;
890
746
  if (count > table->len - table->ofs) count = table->len - table->ofs;
891
- for (i = 0; i < count; i++) pcc_lr_table_entry__destroy(ctx, table->buf[table->ofs++]);
747
+ for (i = 0; i < count; i++) pcc_lr_memo_map__destroy(ctx, table->buf[table->ofs++]);
892
748
  if (table->ofs > (table->max >> 1)) {
893
- memmove(table->buf, table->buf + table->ofs, sizeof(pcc_lr_table_entry_t *) * (table->len - table->ofs));
749
+ memmove(table->buf, table->buf + table->ofs, sizeof(pcc_lr_memo_map_t *) * (table->len - table->ofs));
894
750
  table->len -= table->ofs;
895
751
  table->ofs = 0;
896
752
  }
@@ -899,66 +755,25 @@ static void pcc_lr_table__shift(pcc_context_t *ctx, pcc_lr_table_t *table, size_
899
755
  static void pcc_lr_table__term(pcc_context_t *ctx, pcc_lr_table_t *table) {
900
756
  while (table->len > table->ofs) {
901
757
  table->len--;
902
- pcc_lr_table_entry__destroy(ctx, table->buf[table->len]);
758
+ pcc_lr_memo_map__destroy(ctx, table->buf[table->len]);
903
759
  }
904
760
  PCC_FREE(ctx->auxil, table->buf);
905
761
  }
906
762
 
907
- static pcc_lr_entry_t *pcc_lr_entry__create(pcc_auxil_t auxil, pcc_rule_t rule) {
908
- pcc_lr_entry_t *const lr = (pcc_lr_entry_t *)PCC_MALLOC(auxil, sizeof(pcc_lr_entry_t));
909
- lr->rule = rule;
910
- lr->seed = NULL;
911
- lr->head = NULL;
912
- return lr;
913
- }
914
-
915
- static void pcc_lr_entry__destroy(pcc_auxil_t auxil, pcc_lr_entry_t *lr) {
916
- PCC_FREE(auxil, lr);
917
- }
918
-
919
- static void pcc_lr_stack__init(pcc_auxil_t auxil, pcc_lr_stack_t *stack) {
920
- stack->len = 0;
921
- stack->max = 0;
922
- stack->buf = NULL;
923
- }
924
-
925
- static void pcc_lr_stack__push(pcc_auxil_t auxil, pcc_lr_stack_t *stack, pcc_lr_entry_t *lr) {
926
- if (stack->max <= stack->len) {
927
- const size_t n = stack->len + 1;
928
- size_t m = stack->max;
929
- if (m == 0) m = PCC_ARRAY_MIN_SIZE;
930
- while (m < n && m != 0) m <<= 1;
931
- if (m == 0) m = n;
932
- stack->buf = (pcc_lr_entry_t **)PCC_REALLOC(auxil, stack->buf, sizeof(pcc_lr_entry_t *) * m);
933
- stack->max = m;
934
- }
935
- stack->buf[stack->len++] = lr;
936
- }
937
-
938
- static pcc_lr_entry_t *pcc_lr_stack__pop(pcc_auxil_t auxil, pcc_lr_stack_t *stack) {
939
- return stack->buf[--stack->len];
940
- }
941
-
942
- static void pcc_lr_stack__term(pcc_auxil_t auxil, pcc_lr_stack_t *stack) {
943
- PCC_FREE(auxil, stack->buf);
944
- }
945
-
946
763
  static pcc_context_t *pcc_context__create(pcc_auxil_t auxil) {
947
764
  pcc_context_t *const ctx = (pcc_context_t *)PCC_MALLOC(auxil, sizeof(pcc_context_t));
948
- ctx->pos = 0;
949
- ctx->cur = 0;
765
+ ctx->buffer_start_position = 0;
766
+ ctx->position_offset = 0;
950
767
  <%- if @location -%>
951
- pcc_location_init(&ctx->pos_loc);
952
- pcc_location_init(&ctx->cur_loc);
768
+ pcc_location_init(&ctx->buffer_start_position_loc);
769
+ pcc_location_init(&ctx->position_offset_loc);
953
770
  <%- end -%>
954
771
  ctx->level = 0;
955
772
  pcc_char_array__init(auxil, &ctx->buffer);
956
773
  pcc_lr_table__init(auxil, &ctx->lrtable);
957
- pcc_lr_stack__init(auxil, &ctx->lrstack);
958
774
  pcc_thunk_array__init(auxil, &ctx->thunks);
959
775
  pcc_memory_recycler__init(auxil, &ctx->thunk_chunk_recycler, sizeof(pcc_thunk_chunk_t));
960
- pcc_memory_recycler__init(auxil, &ctx->lr_head_recycler, sizeof(pcc_lr_head_t));
961
- pcc_memory_recycler__init(auxil, &ctx->lr_answer_recycler, sizeof(pcc_lr_answer_t));
776
+ pcc_memory_recycler__init(auxil, &ctx->lr_memo_recycler, sizeof(pcc_lr_memo_t));
962
777
  ctx->auxil = auxil;
963
778
  return ctx;
964
779
  }
@@ -966,35 +781,33 @@ static pcc_context_t *pcc_context__create(pcc_auxil_t auxil) {
966
781
  static void pcc_context__destroy(pcc_context_t *ctx) {
967
782
  if (ctx == NULL) return;
968
783
  pcc_thunk_array__term(ctx->auxil, &ctx->thunks);
969
- pcc_lr_stack__term(ctx->auxil, &ctx->lrstack);
970
784
  pcc_lr_table__term(ctx, &ctx->lrtable);
971
785
  pcc_char_array__term(ctx->auxil, &ctx->buffer);
972
786
  pcc_memory_recycler__term(ctx->auxil, &ctx->thunk_chunk_recycler);
973
- pcc_memory_recycler__term(ctx->auxil, &ctx->lr_head_recycler);
974
- pcc_memory_recycler__term(ctx->auxil, &ctx->lr_answer_recycler);
787
+ pcc_memory_recycler__term(ctx->auxil, &ctx->lr_memo_recycler);
975
788
  PCC_FREE(ctx->auxil, ctx);
976
789
  }
977
790
 
978
791
  static size_t pcc_refill_buffer(pcc_context_t *ctx, size_t num) {
979
- if (ctx->buffer.len >= ctx->cur + num) return ctx->buffer.len - ctx->cur;
980
- while (ctx->buffer.len < ctx->cur + num) {
792
+ if (ctx->buffer.len >= ctx->position_offset + num) return ctx->buffer.len - ctx->position_offset;
793
+ while (ctx->buffer.len < ctx->position_offset + num) {
981
794
  const int c = PCC_GETCHAR(ctx->auxil);
982
795
  if (c < 0) break;
983
796
  pcc_char_array__add(ctx->auxil, &ctx->buffer, (char)c);
984
797
  }
985
- return ctx->buffer.len - ctx->cur;
798
+ return ctx->buffer.len - ctx->position_offset;
986
799
  }
987
800
 
988
801
  MARK_FUNC_AS_USED
989
802
  static void pcc_commit_buffer(pcc_context_t *ctx) {
990
- memmove(ctx->buffer.buf, ctx->buffer.buf + ctx->cur, ctx->buffer.len - ctx->cur);
991
- ctx->buffer.len -= ctx->cur;
992
- ctx->pos += ctx->cur;
993
- pcc_lr_table__shift(ctx, &ctx->lrtable, ctx->cur);
994
- ctx->cur = 0;
803
+ memmove(ctx->buffer.buf, ctx->buffer.buf + ctx->position_offset, ctx->buffer.len - ctx->position_offset);
804
+ ctx->buffer.len -= ctx->position_offset;
805
+ ctx->buffer_start_position += ctx->position_offset;
806
+ pcc_lr_table__shift(ctx, &ctx->lrtable, ctx->position_offset);
807
+ ctx->position_offset = 0;
995
808
  <%- if @location -%>
996
- ctx->pos_loc = pcc_location_add(ctx->pos_loc, ctx->cur_loc);
997
- pcc_location_init(&ctx->cur_loc);
809
+ ctx->buffer_start_position_loc = pcc_location_add(ctx->buffer_start_position_loc, ctx->position_offset_loc);
810
+ pcc_location_init(&ctx->position_offset_loc);
998
811
  <%- end -%>
999
812
  }
1000
813
 
@@ -1011,7 +824,7 @@ static size_t pcc_get_char_as_utf32(pcc_context_t *ctx, int *out) { /* with chec
1011
824
  int c, u;
1012
825
  size_t n;
1013
826
  if (pcc_refill_buffer(ctx, 1) < 1) return 0;
1014
- c = (int)(unsigned char)ctx->buffer.buf[ctx->cur];
827
+ c = (int)(unsigned char)ctx->buffer.buf[ctx->position_offset];
1015
828
  n = (c < 0x80) ? 1 :
1016
829
  ((c & 0xe0) == 0xc0) ? 2 :
1017
830
  ((c & 0xf0) == 0xe0) ? 3 :
@@ -1024,30 +837,30 @@ static size_t pcc_get_char_as_utf32(pcc_context_t *ctx, int *out) { /* with chec
1024
837
  break;
1025
838
  case 2:
1026
839
  u = c & 0x1f;
1027
- c = (int)(unsigned char)ctx->buffer.buf[ctx->cur + 1];
840
+ c = (int)(unsigned char)ctx->buffer.buf[ctx->position_offset + 1];
1028
841
  if ((c & 0xc0) != 0x80) return 0;
1029
842
  u <<= 6; u |= c & 0x3f;
1030
843
  if (u < 0x80) return 0;
1031
844
  break;
1032
845
  case 3:
1033
846
  u = c & 0x0f;
1034
- c = (int)(unsigned char)ctx->buffer.buf[ctx->cur + 1];
847
+ c = (int)(unsigned char)ctx->buffer.buf[ctx->position_offset + 1];
1035
848
  if ((c & 0xc0) != 0x80) return 0;
1036
849
  u <<= 6; u |= c & 0x3f;
1037
- c = (int)(unsigned char)ctx->buffer.buf[ctx->cur + 2];
850
+ c = (int)(unsigned char)ctx->buffer.buf[ctx->position_offset + 2];
1038
851
  if ((c & 0xc0) != 0x80) return 0;
1039
852
  u <<= 6; u |= c & 0x3f;
1040
853
  if (u < 0x800) return 0;
1041
854
  break;
1042
855
  case 4:
1043
856
  u = c & 0x07;
1044
- c = (int)(unsigned char)ctx->buffer.buf[ctx->cur + 1];
857
+ c = (int)(unsigned char)ctx->buffer.buf[ctx->position_offset + 1];
1045
858
  if ((c & 0xc0) != 0x80) return 0;
1046
859
  u <<= 6; u |= c & 0x3f;
1047
- c = (int)(unsigned char)ctx->buffer.buf[ctx->cur + 2];
860
+ c = (int)(unsigned char)ctx->buffer.buf[ctx->position_offset + 2];
1048
861
  if ((c & 0xc0) != 0x80) return 0;
1049
862
  u <<= 6; u |= c & 0x3f;
1050
- c = (int)(unsigned char)ctx->buffer.buf[ctx->cur + 3];
863
+ c = (int)(unsigned char)ctx->buffer.buf[ctx->position_offset + 3];
1051
864
  if ((c & 0xc0) != 0x80) return 0;
1052
865
  u <<= 6; u |= c & 0x3f;
1053
866
  if (u < 0x10000 || u > 0x10ffff) return 0;
@@ -1060,116 +873,87 @@ static size_t pcc_get_char_as_utf32(pcc_context_t *ctx, int *out) { /* with chec
1060
873
  }
1061
874
 
1062
875
  <% end -%>
1063
- MARK_FUNC_AS_USED
1064
- static pcc_bool_t pcc_apply_rule(pcc_context_t *ctx, pcc_rule_t rule, pcc_thunk_array_t *thunks, pcc_value_t *value) {
1065
- static pcc_value_t null;
1066
- pcc_thunk_chunk_t *c = NULL;
1067
- const size_t p = ctx->pos + ctx->cur;
876
+ static void pcc_grow_lr(pcc_context_t *ctx, pcc_rule_t rule, size_t offset<% if @location %>, pcc_location_t offset_loc<% end %>) {
877
+ while(1) {
878
+ const size_t old_offset = ctx->position_offset;
879
+ pcc_thunk_chunk_t *chunk;
880
+ pcc_lr_memo_t *memo;
881
+ pcc_rule_set_t limits;
882
+ ctx->position_offset = offset;
1068
883
  <%- if @location -%>
1069
- const pcc_location_t p_loc = pcc_location_add(ctx->pos_loc, ctx->cur_loc);
884
+ ctx->position_offset_loc = offset_loc;
1070
885
  <%- end -%>
1071
- pcc_bool_t b = PCC_TRUE;
1072
- pcc_lr_answer_t *a = pcc_lr_table__get_answer(ctx, &ctx->lrtable, p, rule);
1073
- pcc_lr_head_t *h = pcc_lr_table__get_head(ctx, &ctx->lrtable, p);
1074
- if (h != NULL) {
1075
- if (a == NULL && rule != h->rule && pcc_rule_set__index(ctx->auxil, &h->invol, rule) == PCC_VOID_VALUE) {
1076
- b = PCC_FALSE;
1077
- c = NULL;
1078
- }
1079
- else if (pcc_rule_set__remove(ctx->auxil, &h->eval, rule)) {
1080
- b = PCC_FALSE;
1081
- c = rule(ctx);
1082
- a = pcc_lr_answer__create(ctx, PCC_LR_ANSWER_CHUNK, ctx->pos + ctx->cur<% if @location %>, pcc_location_add(ctx->pos_loc, ctx->cur_loc)<% end %>);
1083
- a->data.chunk = c;
1084
- pcc_lr_table__hold_answer(ctx, &ctx->lrtable, p, a);
886
+ pcc_rule_set__init(ctx->auxil, &limits);
887
+ pcc_rule_set__add(ctx->auxil, &limits, rule);
888
+ chunk = rule(ctx, offset<% if @location %>, offset_loc<% end %>, &limits);
889
+ pcc_rule_set__term(ctx->auxil, &limits);
890
+ if (!chunk)
891
+ break;
892
+ if (ctx->position_offset <= old_offset) {
893
+ pcc_thunk_chunk__destroy(ctx, chunk);
894
+ break;
1085
895
  }
896
+ memo = pcc_lr_table__get_memo(ctx, &ctx->lrtable, offset, rule);
897
+ pcc_lr_memo__set_chunk(ctx, memo, chunk);
898
+ memo->offset = ctx->position_offset;
899
+ <%- if @location -%>
900
+ memo->offset_loc = ctx->position_offset_loc;
901
+ <%- end -%>
1086
902
  }
1087
- if (b) {
1088
- if (a != NULL) {
1089
- ctx->cur = a->pos - ctx->pos;
1090
- <%- if @location -%>
1091
- ctx->cur_loc = pcc_location_sub(a->pos_loc, ctx->pos_loc);
1092
- <%- end -%>
1093
- switch (a->type) {
1094
- case PCC_LR_ANSWER_LR:
1095
- if (a->data.lr->head == NULL) {
1096
- a->data.lr->head = pcc_lr_head__create(ctx, rule);
1097
- pcc_lr_table__hold_head(ctx, &ctx->lrtable, p, a->data.lr->head);
1098
- }
1099
- {
1100
- size_t i = ctx->lrstack.len;
1101
- while (i > 0) {
1102
- i--;
1103
- if (ctx->lrstack.buf[i]->head == a->data.lr->head) break;
1104
- ctx->lrstack.buf[i]->head = a->data.lr->head;
1105
- pcc_rule_set__add(ctx->auxil, &a->data.lr->head->invol, ctx->lrstack.buf[i]->rule);
1106
- }
1107
- }
1108
- c = a->data.lr->seed;
1109
- break;
1110
- case PCC_LR_ANSWER_CHUNK:
1111
- c = a->data.chunk;
1112
- break;
1113
- default: /* unknown */
1114
- break;
1115
- }
1116
- }
1117
- else {
1118
- pcc_lr_entry_t *const e = pcc_lr_entry__create(ctx->auxil, rule);
1119
- pcc_lr_stack__push(ctx->auxil, &ctx->lrstack, e);
1120
- a = pcc_lr_answer__create(ctx, PCC_LR_ANSWER_LR, p<% if @location %>, p_loc<% end %>);
1121
- a->data.lr = e;
1122
- pcc_lr_table__set_answer(ctx, &ctx->lrtable, p, rule, a);
1123
- c = rule(ctx);
1124
- pcc_lr_stack__pop(ctx->auxil, &ctx->lrstack);
1125
- a->pos = ctx->pos + ctx->cur;
1126
- <%- if @location -%>
1127
- a->pos_loc = pcc_location_add(ctx->pos_loc, ctx->cur_loc);
1128
- <%- end -%>
1129
- if (e->head == NULL) {
1130
- pcc_lr_answer__set_chunk(ctx, a, c);
1131
- }
1132
- else {
1133
- e->seed = c;
1134
- h = a->data.lr->head;
1135
- if (h->rule != rule) {
1136
- c = a->data.lr->seed;
1137
- a = pcc_lr_answer__create(ctx, PCC_LR_ANSWER_CHUNK, ctx->pos + ctx->cur<% if @location %>, pcc_location_add(ctx->pos_loc, ctx->cur_loc)<% end %>);
1138
- a->data.chunk = c;
1139
- pcc_lr_table__hold_answer(ctx, &ctx->lrtable, p, a);
1140
- }
1141
- else {
1142
- pcc_lr_answer__set_chunk(ctx, a, a->data.lr->seed);
1143
- if (a->data.chunk == NULL) {
1144
- c = NULL;
1145
- }
1146
- else {
1147
- pcc_lr_table__set_head(ctx, &ctx->lrtable, p, h);
1148
- for (;;) {
1149
- ctx->cur = p - ctx->pos;
1150
- <%- if @location -%>
1151
- ctx->cur_loc = pcc_location_sub(p_loc, ctx->pos_loc);
1152
- <%- end -%>
1153
- pcc_rule_set__copy(ctx->auxil, &h->eval, &h->invol);
1154
- c = rule(ctx);
1155
- if (c == NULL || ctx->pos + ctx->cur <= a->pos) break;
1156
- pcc_lr_answer__set_chunk(ctx, a, c);
1157
- a->pos = ctx->pos + ctx->cur;
903
+ }
904
+
905
+ MARK_FUNC_AS_USED
906
+ static pcc_thunk_chunk_t *pcc_get_rule_thunk_chunk(pcc_context_t *ctx, pcc_rule_t rule) {
907
+ pcc_thunk_chunk_t *c = NULL;
908
+ size_t offset = ctx->position_offset;
1158
909
  <%- if @location -%>
1159
- a->pos_loc = pcc_location_add(ctx->pos_loc, ctx->cur_loc);
910
+ pcc_location_t offset_loc = ctx->position_offset_loc;
1160
911
  <%- end -%>
1161
- }
1162
- pcc_thunk_chunk__destroy(ctx, c);
1163
- pcc_lr_table__set_head(ctx, &ctx->lrtable, p, NULL);
1164
- ctx->cur = a->pos - ctx->pos;
912
+ pcc_lr_memo_t *a = pcc_lr_table__get_memo(ctx, &ctx->lrtable, offset, rule);
913
+
914
+ if (a == NULL) {
915
+ a = pcc_lr_memo__create(ctx, offset<% if @location %>, offset_loc<% end %>);
916
+ pcc_lr_table__set_memo(ctx, &ctx->lrtable, offset, rule, a);
917
+ c = rule(ctx, offset<% if @location %>, offset_loc<% end %>, NULL);
918
+ pcc_lr_memo__set_chunk(ctx, a, c);
919
+ a->offset = ctx->position_offset;
1165
920
  <%- if @location -%>
1166
- ctx->cur_loc = pcc_location_sub(a->pos_loc, ctx->pos_loc);
921
+ a->offset_loc = ctx->position_offset_loc;
1167
922
  <%- end -%>
1168
- c = a->data.chunk;
1169
- }
1170
- }
1171
- }
923
+ if (a->grow) {
924
+ pcc_grow_lr(ctx, rule, offset<% if @location %>, offset_loc<% end %>);
925
+ a->grow = PCC_FALSE;
926
+ ctx->position_offset = a->offset;
927
+ return a->chunk;
928
+ }
929
+ return c;
930
+ } else if (a->fail) {
931
+ pcc_lr_memo__set_chunk(ctx, a, NULL);
932
+ a->grow = PCC_TRUE;
933
+ return NULL;
934
+ }
935
+ ctx->position_offset = a->offset;
936
+ return a->chunk;
937
+ }
938
+
939
+ MARK_FUNC_AS_USED
940
+ static pcc_bool_t pcc_apply_rule(pcc_context_t *ctx, pcc_rule_t rule, pcc_thunk_array_t *thunks, pcc_value_t *value, size_t offset<% if @location %>, pcc_location_t offset_loc<% end %>, pcc_rule_set_t *limits) {
941
+ static pcc_value_t null;
942
+ pcc_thunk_chunk_t *c;
943
+ if (limits != NULL) {
944
+ pcc_lr_memo_t *a;
945
+ pcc_rule_set__add(ctx->auxil, limits, rule);
946
+ c = rule(ctx, offset<% if @location %>, offset_loc<% end %>, limits);
947
+ a = pcc_lr_table__get_memo(ctx, &ctx->lrtable, offset, rule);
948
+ if (a == NULL || ctx->position_offset <= a->offset) {
949
+ c = a->chunk;
950
+ ctx->position_offset = a->offset;
951
+ } else {
952
+ pcc_lr_memo__set_chunk(ctx, a, c);
953
+ a->offset = ctx->position_offset;
1172
954
  }
955
+ } else {
956
+ c = pcc_get_rule_thunk_chunk(ctx, rule);
1173
957
  }
1174
958
  if (c == NULL) return PCC_FALSE;
1175
959
  if (value == NULL) value = &null;
@@ -1205,22 +989,22 @@ static void pcc_action_<%= rule.name %>_<%= code.index %>(<%= prefix %>_context_
1205
989
  #define <%= ref.var %> (*__pcc_in->data.leaf.values.buf[<%= ref.index %>])
1206
990
  <% end -%>
1207
991
  #define _0 pcc_get_capture_string(__pcc_ctx, &__pcc_in->data.leaf.capt0)
1208
- #define _0s ((const size_t)(__pcc_ctx->pos + __pcc_in->data.leaf.capt0.range.start))
1209
- #define _0e ((const size_t)(__pcc_ctx->pos + __pcc_in->data.leaf.capt0.range.end))
992
+ #define _0s ((const size_t)(__pcc_ctx->buffer_start_position + __pcc_in->data.leaf.capt0.range.start))
993
+ #define _0e ((const size_t)(__pcc_ctx->buffer_start_position + __pcc_in->data.leaf.capt0.range.end))
1210
994
  <%- if @location -%>
1211
- #define _0sl ((const pcc_location_t)(pcc_location_add(__pcc_ctx->pos_loc, *__pcc_in->data.leaf.capt0.range.start_loc_ptr)))
1212
- #define _0el ((const pcc_location_t)(pcc_location_add(__pcc_ctx->pos_loc, *__pcc_in->data.leaf.capt0.range.end_loc_ptr)))
995
+ #define _0sl ((const pcc_location_t)(pcc_location_add(__pcc_ctx->buffer_start_position_loc, __pcc_in->data.leaf.capt0.range.start_loc)))
996
+ #define _0el ((const pcc_location_t)(pcc_location_add(__pcc_ctx->buffer_start_position_loc, __pcc_in->data.leaf.capt0.range.end_loc)))
1213
997
  <%- end -%>
1214
998
  <%- if @capture_in_code -%>
1215
999
  #define _0c __pcc_in->data.leaf.capt0
1216
1000
  <%- end -%>
1217
1001
  <% code.capts.each do |capture| -%>
1218
1002
  #define _<%= capture.index + 1 %> pcc_get_capture_string(__pcc_ctx, __pcc_in->data.leaf.capts.buf[<%= capture.index %>])
1219
- #define _<%= capture.index + 1 %>s ((const size_t)(__pcc_ctx->pos + __pcc_in->data.leaf.capts.buf[<%= capture.index %>]->range.start))
1220
- #define _<%= capture.index + 1 %>e ((const size_t)(__pcc_ctx->pos + __pcc_in->data.leaf.capts.buf[<%= capture.index %>]->range.end))
1003
+ #define _<%= capture.index + 1 %>s ((const size_t)(__pcc_ctx->buffer_start_position + __pcc_in->data.leaf.capts.buf[<%= capture.index %>]->range.start))
1004
+ #define _<%= capture.index + 1 %>e ((const size_t)(__pcc_ctx->buffer_start_position + __pcc_in->data.leaf.capts.buf[<%= capture.index %>]->range.end))
1221
1005
  <%- if @location -%>
1222
- #define _<%= capture.index + 1 %>sl ((const pcc_location_t)(pcc_location_add(__pcc_ctx->pos_loc, *__pcc_in->data.leaf.capts.buf[<%= capture.index %>]->range.start_loc_ptr)))
1223
- #define _<%= capture.index + 1 %>el ((const pcc_location_t)(pcc_location_add(__pcc_ctx->pos_loc, *__pcc_in->data.leaf.capts.buf[<%= capture.index %>]->range.end_loc_ptr)))
1006
+ #define _<%= capture.index + 1 %>sl ((const pcc_location_t)(pcc_location_add(__pcc_ctx->buffer_start_position_loc, __pcc_in->data.leaf.capts.buf[<%= capture.index %>]->range.start_loc)))
1007
+ #define _<%= capture.index + 1 %>el ((const pcc_location_t)(pcc_location_add(__pcc_ctx->buffer_start_position_loc, __pcc_in->data.leaf.capts.buf[<%= capture.index %>]->range.end_loc)))
1224
1008
  <%- end -%>
1225
1009
  <%- if @capture_in_code -%>
1226
1010
  #define _<%= capture.index + 1 %>c (*__pcc_in->data.leaf.capts.buf[<%= capture.index %>])
@@ -1249,19 +1033,12 @@ static void pcc_action_<%= rule.name %>_<%= code.index %>(<%= prefix %>_context_
1249
1033
  <%- end -%>
1250
1034
  <%- end -%>
1251
1035
  <%- @root.rules.each do |rule| -%>
1252
- static pcc_thunk_chunk_t *pcc_evaluate_rule_<%= rule.name %>(pcc_context_t *ctx);
1036
+ static pcc_thunk_chunk_t *pcc_evaluate_rule_<%= rule.name %>(pcc_context_t *ctx, size_t offset<% if @location %>, pcc_location_t offset_loc<% end %>, pcc_rule_set_t *limits);
1253
1037
  <%- end -%>
1254
1038
 
1255
1039
  <%- @root.rules.each do |rule| -%>
1256
- static pcc_thunk_chunk_t *pcc_evaluate_rule_<%= rule.name %>(pcc_context_t *ctx) {
1257
- pcc_thunk_chunk_t *const chunk = pcc_thunk_chunk__create(ctx);
1258
- chunk->pos = ctx->cur;
1259
- <%- if @location -%>
1260
- chunk->pos_loc = ctx->cur_loc;
1261
- <%- end -%>
1262
1040
  <%- gen = ::Packcr::Generator.new(rule, @ascii, @location) -%>
1263
1041
  <%= gen.generate_code(rule, 0, 0, false) -%>
1264
- }
1265
1042
 
1266
1043
  <%- end -%>
1267
1044
  <%= prefix %>_context_t *<%= prefix %>_create(<%= auxil_def %>auxil) {
@@ -1269,16 +1046,16 @@ static pcc_thunk_chunk_t *pcc_evaluate_rule_<%= rule.name %>(pcc_context_t *ctx)
1269
1046
  }
1270
1047
 
1271
1048
  int <%= prefix %>_parse(<%= prefix %>_context_t *ctx, <%= value_def %>*ret) {
1272
- size_t pos = ctx->pos;
1049
+ size_t pos = ctx->buffer_start_position;
1273
1050
  <%- if !@root.rules.empty? -%>
1274
- if (pcc_apply_rule(ctx, pcc_evaluate_rule_<%= @root.rules[0].name %>, &ctx->thunks, ret))
1051
+ if (pcc_apply_rule(ctx, pcc_evaluate_rule_<%= @root.rules[0].name %>, &ctx->thunks, ret, ctx->position_offset<% if @location %>, ctx->position_offset_loc<% end %>, NULL))
1275
1052
  pcc_do_action(ctx, &ctx->thunks, ret);
1276
1053
  else
1277
1054
  PCC_ERROR(ctx->auxil);
1278
1055
  pcc_commit_buffer(ctx);
1279
1056
  <%- end -%>
1280
1057
  pcc_thunk_array__revert(ctx->auxil, &ctx->thunks, 0);
1281
- return pos != ctx->pos && pcc_refill_buffer(ctx, 1) >= 1;
1058
+ return pos != ctx->buffer_start_position && pcc_refill_buffer(ctx, 1) >= 1;
1282
1059
  }
1283
1060
 
1284
1061
  void <%= prefix %>_destroy(<%= prefix %>_context_t *ctx) {