packcr 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
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) {