packcr 0.0.4 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/exe/packcr +3 -0
  3. data/lib/packcr/broadcast.rb +17 -0
  4. data/lib/packcr/cli.rb +27 -0
  5. data/lib/packcr/code_block.rb +2 -4
  6. data/lib/packcr/context.rb +66 -61
  7. data/lib/packcr/generated/context.rb +440 -0
  8. data/lib/packcr/generated/node/action_node.rb +60 -0
  9. data/lib/packcr/generated/node/alternate_node.rb +98 -0
  10. data/lib/packcr/generated/node/capture_node.rb +39 -0
  11. data/lib/packcr/generated/node/charclass_node.rb +372 -0
  12. data/lib/packcr/generated/node/eof_node.rb +20 -0
  13. data/lib/packcr/generated/node/error_node.rb +67 -0
  14. data/lib/packcr/generated/node/expand_node.rb +30 -0
  15. data/lib/packcr/generated/node/predicate_node.rb +140 -0
  16. data/lib/packcr/generated/node/quantity_node.rb +167 -0
  17. data/lib/packcr/generated/node/reference_node.rb +70 -0
  18. data/lib/packcr/generated/node/rule_node.rb +63 -0
  19. data/lib/packcr/generated/node/sequence_node.rb +42 -0
  20. data/lib/packcr/generated/node/string_node.rb +60 -0
  21. data/lib/packcr/generator.rb +14 -11
  22. data/lib/packcr/node/action_node.rb +18 -7
  23. data/lib/packcr/node/alternate_node.rb +22 -12
  24. data/lib/packcr/node/capture_node.rb +14 -12
  25. data/lib/packcr/node/charclass_node.rb +44 -24
  26. data/lib/packcr/node/eof_node.rb +25 -0
  27. data/lib/packcr/node/error_node.rb +20 -13
  28. data/lib/packcr/node/expand_node.rb +18 -9
  29. data/lib/packcr/node/predicate_node.rb +19 -26
  30. data/lib/packcr/node/quantity_node.rb +31 -24
  31. data/lib/packcr/node/reference_node.rb +31 -9
  32. data/lib/packcr/node/root_node.rb +61 -0
  33. data/lib/packcr/node/rule_node.rb +29 -3
  34. data/lib/packcr/node/sequence_node.rb +48 -31
  35. data/lib/packcr/node/string_node.rb +19 -16
  36. data/lib/packcr/node.rb +34 -5
  37. data/lib/packcr/parser.rb +4493 -3896
  38. data/lib/packcr/stream.rb +22 -22
  39. data/lib/packcr/templates/context/header.c.erb +29 -0
  40. data/lib/packcr/templates/context/source.c.erb +1069 -0
  41. data/lib/packcr/templates/context/source.rb.erb +341 -0
  42. data/lib/packcr/templates/node/action.c.erb +16 -0
  43. data/lib/packcr/templates/node/action.rb.erb +21 -0
  44. data/lib/packcr/templates/node/alternate.c.erb +34 -0
  45. data/lib/packcr/templates/node/alternate.rb.erb +39 -0
  46. data/lib/packcr/templates/node/capture.c.erb +17 -0
  47. data/lib/packcr/templates/node/capture.rb.erb +14 -0
  48. data/lib/packcr/templates/node/charclass.c.erb +47 -0
  49. data/lib/packcr/templates/node/charclass.rb.erb +49 -0
  50. data/lib/packcr/templates/node/charclass_any.c.erb +5 -0
  51. data/lib/packcr/templates/node/charclass_any.rb.erb +7 -0
  52. data/lib/packcr/templates/node/charclass_fail.c.erb +1 -0
  53. data/lib/packcr/templates/node/charclass_fail.rb.erb +1 -0
  54. data/lib/packcr/templates/node/charclass_one.c.erb +19 -0
  55. data/lib/packcr/templates/node/charclass_one.rb.erb +23 -0
  56. data/lib/packcr/templates/node/charclass_utf8.c.erb +49 -0
  57. data/lib/packcr/templates/node/charclass_utf8.rb.erb +50 -0
  58. data/lib/packcr/templates/node/charclass_utf8_reverse.rb.erb +51 -0
  59. data/lib/packcr/templates/node/eof.c.erb +1 -0
  60. data/lib/packcr/templates/node/eof.rb.erb +3 -0
  61. data/lib/packcr/templates/node/error.c.erb +28 -0
  62. data/lib/packcr/templates/node/error.rb.erb +34 -0
  63. data/lib/packcr/templates/node/expand.c.erb +16 -0
  64. data/lib/packcr/templates/node/expand.rb.erb +16 -0
  65. data/lib/packcr/templates/node/predicate.c.erb +30 -0
  66. data/lib/packcr/templates/node/predicate.rb.erb +28 -0
  67. data/lib/packcr/templates/node/predicate_neg.c.erb +23 -0
  68. data/lib/packcr/templates/node/predicate_neg.rb.erb +22 -0
  69. data/lib/packcr/templates/node/quantity_many.c.erb +45 -0
  70. data/lib/packcr/templates/node/quantity_many.rb.erb +47 -0
  71. data/lib/packcr/templates/node/quantity_one.c.erb +21 -0
  72. data/lib/packcr/templates/node/quantity_one.rb.erb +23 -0
  73. data/lib/packcr/templates/node/reference.c.erb +17 -0
  74. data/lib/packcr/templates/node/reference.rb.erb +21 -0
  75. data/lib/packcr/templates/node/reference_reverse.rb.erb +21 -0
  76. data/lib/packcr/templates/node/rule.c.erb +26 -0
  77. data/lib/packcr/templates/node/rule.rb.erb +30 -0
  78. data/lib/packcr/templates/node/sequence.c.erb +12 -0
  79. data/lib/packcr/templates/node/sequence.rb.erb +12 -0
  80. data/lib/packcr/templates/node/string_many.c.erb +11 -0
  81. data/lib/packcr/templates/node/string_many.rb.erb +10 -0
  82. data/lib/packcr/templates/node/string_one.c.erb +8 -0
  83. data/lib/packcr/templates/node/string_one.rb.erb +10 -0
  84. data/lib/packcr/util.rb +21 -24
  85. data/lib/packcr/version.rb +1 -1
  86. data/lib/packcr.rb +9 -13
  87. metadata +117 -10
  88. data/lib/packcr/buffer.rb +0 -47
@@ -0,0 +1,1069 @@
1
+ /* A packrat parser generated by PackCR <%= Packcr::VERSION %> */
2
+
3
+ <%- code(:esource).each do |code| -%>
4
+ <%= stream.get_code_block(code, 0, @iname) -%>
5
+ <%- end -%>
6
+ <%- if !code(:esource).empty? -%>
7
+
8
+ <%- end -%>
9
+ #ifdef _MSC_VER
10
+ #undef _CRT_SECURE_NO_WARNINGS
11
+ #define _CRT_SECURE_NO_WARNINGS
12
+ #endif /* _MSC_VER */
13
+ #include <stdio.h>
14
+ #include <stdlib.h>
15
+ #include <string.h>
16
+
17
+ #ifndef _MSC_VER
18
+ #if defined __GNUC__ && defined _WIN32 /* MinGW */
19
+ #ifndef PCC_USE_SYSTEM_STRNLEN
20
+ #define strnlen(str, maxlen) pcc_strnlen(str, maxlen)
21
+ static size_t pcc_strnlen(const char *str, size_t maxlen) {
22
+ size_t i;
23
+ for (i = 0; i < maxlen && str[i]; i++);
24
+ return i;
25
+ }
26
+ #endif /* !PCC_USE_SYSTEM_STRNLEN */
27
+ #endif /* defined __GNUC__ && defined _WIN32 */
28
+ #endif /* !_MSC_VER */
29
+
30
+ #include "<%= @hname %>"
31
+ <%- if !code(:location).empty? -%>
32
+
33
+ <%- code(:location).each do |code| -%>
34
+ <%= stream.get_code_block(code, 4, @iname) -%>
35
+ <%- end -%>
36
+ <%- end -%>
37
+
38
+ <%- code(:source).each do |code| -%>
39
+ <%= stream.get_code_block(code, 0, @iname) -%>
40
+ <%- end -%>
41
+ #if !defined __has_attribute || defined _MSC_VER
42
+ #define __attribute__(x)
43
+ #endif
44
+
45
+ #ifdef _MSC_VER
46
+ #define MARK_FUNC_AS_USED __pragma(warning(suppress:4505))
47
+ #else
48
+ #define MARK_FUNC_AS_USED __attribute__((__unused__))
49
+ #endif
50
+
51
+ #ifndef PCC_BUFFER_MIN_SIZE
52
+ #define PCC_BUFFER_MIN_SIZE 256
53
+ #endif /* !PCC_BUFFER_MIN_SIZE */
54
+
55
+ #ifndef PCC_ARRAY_MIN_SIZE
56
+ #define PCC_ARRAY_MIN_SIZE 2
57
+ #endif /* !PCC_ARRAY_MIN_SIZE */
58
+
59
+ #ifndef PCC_POOL_MIN_SIZE
60
+ #define PCC_POOL_MIN_SIZE 65536
61
+ #endif /* !PCC_POOL_MIN_SIZE */
62
+
63
+ #define PCC_DBG_EVALUATE 0
64
+ #define PCC_DBG_MATCH 1
65
+ #define PCC_DBG_NOMATCH 2
66
+
67
+ #define PCC_VOID_VALUE (~(size_t)0)
68
+
69
+ typedef enum pcc_bool_tag {
70
+ PCC_FALSE = 0,
71
+ PCC_TRUE
72
+ } pcc_bool_t;
73
+
74
+ typedef struct pcc_char_array_tag {
75
+ char *buf;
76
+ size_t max;
77
+ size_t len;
78
+ } pcc_char_array_t;
79
+
80
+ typedef struct pcc_range_tag {
81
+ size_t start;
82
+ size_t end;
83
+ <%- if @location -%>
84
+ pcc_location_t start_loc;
85
+ pcc_location_t end_loc;
86
+ <%- end -%>
87
+ } pcc_range_t;
88
+
89
+ typedef <%= value_def %>pcc_value_t;
90
+
91
+ typedef <%= auxil_def %>pcc_auxil_t;
92
+
93
+ <% if prefix != "pcc" -%>
94
+ typedef <%= prefix%>_context_t pcc_context_t;
95
+
96
+ <% end -%>
97
+ typedef struct pcc_value_table_tag {
98
+ pcc_value_t *buf;
99
+ size_t max;
100
+ size_t len;
101
+ } pcc_value_table_t;
102
+
103
+ typedef struct pcc_value_refer_table_tag {
104
+ pcc_value_t **buf;
105
+ size_t max;
106
+ size_t len;
107
+ } pcc_value_refer_table_t;
108
+
109
+ typedef struct pcc_capture_tag {
110
+ pcc_range_t range;
111
+ char *string; /* mutable */
112
+ } pcc_capture_t;
113
+
114
+ typedef struct pcc_capture_table_tag {
115
+ pcc_capture_t *buf;
116
+ size_t max;
117
+ size_t len;
118
+ } pcc_capture_table_t;
119
+
120
+ typedef struct pcc_capture_const_table_tag {
121
+ const pcc_capture_t **buf;
122
+ size_t max;
123
+ size_t len;
124
+ } pcc_capture_const_table_t;
125
+
126
+ typedef struct pcc_thunk_tag pcc_thunk_t;
127
+ typedef struct pcc_thunk_array_tag pcc_thunk_array_t;
128
+
129
+ typedef void (*pcc_action_t)(pcc_context_t *, pcc_thunk_t *, pcc_value_t *);
130
+
131
+ typedef enum pcc_thunk_type_tag {
132
+ PCC_THUNK_LEAF,
133
+ PCC_THUNK_NODE
134
+ } pcc_thunk_type_t;
135
+
136
+ typedef struct pcc_thunk_leaf_tag {
137
+ pcc_value_refer_table_t values;
138
+ pcc_capture_const_table_t capts;
139
+ pcc_capture_t capt0;
140
+ pcc_action_t action;
141
+ } pcc_thunk_leaf_t;
142
+
143
+ typedef struct pcc_thunk_node_tag {
144
+ const pcc_thunk_array_t *thunks; /* just a reference */
145
+ pcc_value_t *value; /* just a reference */
146
+ } pcc_thunk_node_t;
147
+
148
+ typedef union pcc_thunk_data_tag {
149
+ pcc_thunk_leaf_t leaf;
150
+ pcc_thunk_node_t node;
151
+ } pcc_thunk_data_t;
152
+
153
+ struct pcc_thunk_tag {
154
+ pcc_thunk_type_t type;
155
+ pcc_thunk_data_t data;
156
+ };
157
+
158
+ struct pcc_thunk_array_tag {
159
+ pcc_thunk_t **buf;
160
+ size_t max;
161
+ size_t len;
162
+ };
163
+
164
+ typedef struct pcc_thunk_chunk_tag {
165
+ pcc_value_table_t values;
166
+ pcc_capture_table_t capts;
167
+ pcc_thunk_array_t thunks;
168
+ size_t pos; /* the starting position in the character buffer */
169
+ <%- if @location -%>
170
+ pcc_location_t pos_loc;
171
+ <%- end -%>
172
+ } pcc_thunk_chunk_t;
173
+
174
+ typedef struct pcc_lr_memo_tag pcc_lr_memo_t;
175
+
176
+ struct pcc_lr_memo_tag {
177
+ size_t offset;
178
+ <%- if @location -%>
179
+ pcc_location_t offset_loc;
180
+ <%- end -%>
181
+ pcc_lr_memo_t *hold;
182
+ pcc_thunk_chunk_t *chunk;
183
+ pcc_bool_t fail;
184
+ pcc_bool_t grow;
185
+ };
186
+
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*);
190
+
191
+ typedef struct pcc_rule_set_tag {
192
+ pcc_rule_t *buf;
193
+ size_t max;
194
+ size_t len;
195
+ } pcc_rule_set_t;
196
+
197
+ typedef struct pcc_lr_memo_map_entry_tag {
198
+ pcc_rule_t rule;
199
+ pcc_lr_memo_t *memo;
200
+ } pcc_lr_memo_map_entry_t;
201
+
202
+ typedef struct pcc_lr_memo_map_tag {
203
+ pcc_lr_memo_map_entry_t *buf;
204
+ size_t max;
205
+ size_t len;
206
+ } pcc_lr_memo_map_t;
207
+
208
+ typedef struct pcc_lr_table_tag {
209
+ pcc_lr_memo_map_t **buf;
210
+ size_t max;
211
+ size_t len;
212
+ size_t ofs;
213
+ } pcc_lr_table_t;
214
+
215
+ typedef struct pcc_memory_entry_tag pcc_memory_entry_t;
216
+ typedef struct pcc_memory_pool_tag pcc_memory_pool_t;
217
+
218
+ struct pcc_memory_entry_tag {
219
+ pcc_memory_entry_t *next;
220
+ };
221
+
222
+ struct pcc_memory_pool_tag {
223
+ pcc_memory_pool_t *next;
224
+ size_t allocated;
225
+ size_t unused;
226
+ };
227
+
228
+ typedef struct pcc_memory_recycler_tag {
229
+ pcc_memory_pool_t *pool_list;
230
+ pcc_memory_entry_t *entry_list;
231
+ size_t element_size;
232
+ } pcc_memory_recycler_t;
233
+
234
+ struct <%= prefix %>_context_tag {
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 */
237
+ <%- if @location -%>
238
+ pcc_location_t buffer_start_position_loc;
239
+ pcc_location_t position_offset_loc;
240
+ <%- end -%>
241
+ size_t level;
242
+ pcc_char_array_t buffer;
243
+ pcc_lr_table_t lrtable;
244
+ pcc_thunk_array_t thunks;
245
+ pcc_auxil_t auxil;
246
+ pcc_memory_recycler_t thunk_chunk_recycler;
247
+ pcc_memory_recycler_t lr_memo_recycler;
248
+ };
249
+
250
+ #ifndef PCC_ERROR
251
+ #define PCC_ERROR(auxil) pcc_error()
252
+ MARK_FUNC_AS_USED
253
+ static void pcc_error(void) {
254
+ fprintf(stderr, "Syntax error\n");
255
+ exit(1);
256
+ }
257
+ #endif /* !PCC_ERROR */
258
+
259
+ #ifndef PCC_GETCHAR
260
+ #define PCC_GETCHAR(auxil) getchar()
261
+ #endif /* !PCC_GETCHAR */
262
+
263
+ #ifndef PCC_MALLOC
264
+ #define PCC_MALLOC(auxil, size) pcc_malloc_e(size)
265
+ static void *pcc_malloc_e(size_t size) {
266
+ void *const p = malloc(size);
267
+ if (p == NULL) {
268
+ fprintf(stderr, "Out of memory\n");
269
+ exit(1);
270
+ }
271
+ return p;
272
+ }
273
+ #endif /* !PCC_MALLOC */
274
+
275
+ #ifndef PCC_REALLOC
276
+ #define PCC_REALLOC(auxil, ptr, size) pcc_realloc_e(ptr, size)
277
+ static void *pcc_realloc_e(void *ptr, size_t size) {
278
+ void *const p = realloc(ptr, size);
279
+ if (p == NULL) {
280
+ fprintf(stderr, "Out of memory\n");
281
+ exit(1);
282
+ }
283
+ return p;
284
+ }
285
+ #endif /* !PCC_REALLOC */
286
+
287
+ #ifndef PCC_FREE
288
+ #define PCC_FREE(auxil, ptr) free(ptr)
289
+ #endif /* !PCC_FREE */
290
+
291
+ #ifndef PCC_DEBUG
292
+ #define PCC_DEBUG(auxil, event, rule, level, pos, buffer, length) ((void)0)
293
+ #endif /* !PCC_DEBUG */
294
+
295
+ static char *pcc_strndup_e(pcc_auxil_t auxil, const char *str, size_t len) {
296
+ const size_t m = strnlen(str, len);
297
+ char *const s = (char *)PCC_MALLOC(auxil, m + 1);
298
+ memcpy(s, str, m);
299
+ s[m] = '\0';
300
+ return s;
301
+ }
302
+
303
+ static void pcc_char_array__init(pcc_auxil_t auxil, pcc_char_array_t *array) {
304
+ array->len = 0;
305
+ array->max = 0;
306
+ array->buf = NULL;
307
+ }
308
+
309
+ static void pcc_char_array__add(pcc_auxil_t auxil, pcc_char_array_t *array, char ch) {
310
+ if (array->max <= array->len) {
311
+ const size_t n = array->len + 1;
312
+ size_t m = array->max;
313
+ if (m == 0) m = PCC_BUFFER_MIN_SIZE;
314
+ while (m < n && m != 0) m <<= 1;
315
+ if (m == 0) m = n;
316
+ array->buf = (char *)PCC_REALLOC(auxil, array->buf, m);
317
+ array->max = m;
318
+ }
319
+ array->buf[array->len++] = ch;
320
+ }
321
+
322
+ static void pcc_char_array__term(pcc_auxil_t auxil, pcc_char_array_t *array) {
323
+ PCC_FREE(auxil, array->buf);
324
+ }
325
+
326
+ static void pcc_value_table__init(pcc_auxil_t auxil, pcc_value_table_t *table) {
327
+ table->len = 0;
328
+ table->max = 0;
329
+ table->buf = NULL;
330
+ }
331
+
332
+ MARK_FUNC_AS_USED
333
+ static void pcc_value_table__resize(pcc_auxil_t auxil, pcc_value_table_t *table, size_t len) {
334
+ if (table->max < len) {
335
+ size_t m = table->max;
336
+ if (m == 0) m = PCC_ARRAY_MIN_SIZE;
337
+ while (m < len && m != 0) m <<= 1;
338
+ if (m == 0) m = len;
339
+ table->buf = (pcc_value_t *)PCC_REALLOC(auxil, table->buf, sizeof(pcc_value_t) * m);
340
+ table->max = m;
341
+ }
342
+ table->len = len;
343
+ }
344
+
345
+ MARK_FUNC_AS_USED
346
+ static void pcc_value_table__clear(pcc_auxil_t auxil, pcc_value_table_t *table) {
347
+ memset(table->buf, 0, sizeof(pcc_value_t) * table->len);
348
+ }
349
+
350
+ static void pcc_value_table__term(pcc_auxil_t auxil, pcc_value_table_t *table) {
351
+ PCC_FREE(auxil, table->buf);
352
+ }
353
+
354
+ static void pcc_value_refer_table__init(pcc_auxil_t auxil, pcc_value_refer_table_t *table) {
355
+ table->len = 0;
356
+ table->max = 0;
357
+ table->buf = NULL;
358
+ }
359
+
360
+ static void pcc_value_refer_table__resize(pcc_auxil_t auxil, pcc_value_refer_table_t *table, size_t len) {
361
+ size_t i;
362
+ if (table->max < len) {
363
+ size_t m = table->max;
364
+ if (m == 0) m = PCC_ARRAY_MIN_SIZE;
365
+ while (m < len && m != 0) m <<= 1;
366
+ if (m == 0) m = len;
367
+ table->buf = (pcc_value_t **)PCC_REALLOC(auxil, table->buf, sizeof(pcc_value_t *) * m);
368
+ table->max = m;
369
+ }
370
+ for (i = table->len; i < len; i++) table->buf[i] = NULL;
371
+ table->len = len;
372
+ }
373
+
374
+ static void pcc_value_refer_table__term(pcc_auxil_t auxil, pcc_value_refer_table_t *table) {
375
+ PCC_FREE(auxil, table->buf);
376
+ }
377
+
378
+ static void pcc_capture_table__init(pcc_auxil_t auxil, pcc_capture_table_t *table) {
379
+ table->len = 0;
380
+ table->max = 0;
381
+ table->buf = NULL;
382
+ }
383
+
384
+ MARK_FUNC_AS_USED
385
+ static void pcc_capture_table__resize(pcc_auxil_t auxil, pcc_capture_table_t *table, size_t len) {
386
+ size_t i;
387
+ for (i = len; i < table->len; i++) PCC_FREE(auxil, table->buf[i].string);
388
+ if (table->max < len) {
389
+ size_t m = table->max;
390
+ if (m == 0) m = PCC_ARRAY_MIN_SIZE;
391
+ while (m < len && m != 0) m <<= 1;
392
+ if (m == 0) m = len;
393
+ table->buf = (pcc_capture_t *)PCC_REALLOC(auxil, table->buf, sizeof(pcc_capture_t) * m);
394
+ table->max = m;
395
+ }
396
+ for (i = table->len; i < len; i++) {
397
+ table->buf[i].range.start = 0;
398
+ table->buf[i].range.end = 0;
399
+ <%- if @location -%>
400
+ pcc_location_init(&table->buf[i].range.start_loc);
401
+ pcc_location_init(&table->buf[i].range.end_loc);
402
+ <%- end -%>
403
+ table->buf[i].string = NULL;
404
+ }
405
+ table->len = len;
406
+ }
407
+
408
+ static void pcc_capture_table__term(pcc_auxil_t auxil, pcc_capture_table_t *table) {
409
+ while (table->len > 0) {
410
+ table->len--;
411
+ PCC_FREE(auxil, table->buf[table->len].string);
412
+ }
413
+ PCC_FREE(auxil, table->buf);
414
+ }
415
+
416
+ static void pcc_capture_const_table__init(pcc_auxil_t auxil, pcc_capture_const_table_t *table) {
417
+ table->len = 0;
418
+ table->max = 0;
419
+ table->buf = NULL;
420
+ }
421
+
422
+ static void pcc_capture_const_table__resize(pcc_auxil_t auxil, pcc_capture_const_table_t *table, size_t len) {
423
+ size_t i;
424
+ if (table->max < len) {
425
+ size_t m = table->max;
426
+ if (m == 0) m = PCC_ARRAY_MIN_SIZE;
427
+ while (m < len && m != 0) m <<= 1;
428
+ if (m == 0) m = len;
429
+ table->buf = (const pcc_capture_t **)PCC_REALLOC(auxil, (pcc_capture_t **)table->buf, sizeof(const pcc_capture_t *) * m);
430
+ table->max = m;
431
+ }
432
+ for (i = table->len; i < len; i++) table->buf[i] = NULL;
433
+ table->len = len;
434
+ }
435
+
436
+ static void pcc_capture_const_table__term(pcc_auxil_t auxil, pcc_capture_const_table_t *table) {
437
+ PCC_FREE(auxil, (void *)table->buf);
438
+ }
439
+
440
+ MARK_FUNC_AS_USED
441
+ static pcc_thunk_t *pcc_thunk__create_leaf(pcc_auxil_t auxil, pcc_action_t action, size_t valuec, size_t captc) {
442
+ pcc_thunk_t *const thunk = (pcc_thunk_t *)PCC_MALLOC(auxil, sizeof(pcc_thunk_t));
443
+ thunk->type = PCC_THUNK_LEAF;
444
+ pcc_value_refer_table__init(auxil, &thunk->data.leaf.values);
445
+ pcc_value_refer_table__resize(auxil, &thunk->data.leaf.values, valuec);
446
+ pcc_capture_const_table__init(auxil, &thunk->data.leaf.capts);
447
+ pcc_capture_const_table__resize(auxil, &thunk->data.leaf.capts, captc);
448
+ thunk->data.leaf.capt0.range.start = 0;
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 -%>
454
+ thunk->data.leaf.capt0.string = NULL;
455
+ thunk->data.leaf.action = action;
456
+ return thunk;
457
+ }
458
+
459
+ static pcc_thunk_t *pcc_thunk__create_node(pcc_auxil_t auxil, const pcc_thunk_array_t *thunks, pcc_value_t *value) {
460
+ pcc_thunk_t *const thunk = (pcc_thunk_t *)PCC_MALLOC(auxil, sizeof(pcc_thunk_t));
461
+ thunk->type = PCC_THUNK_NODE;
462
+ thunk->data.node.thunks = thunks;
463
+ thunk->data.node.value = value;
464
+ return thunk;
465
+ }
466
+
467
+ static void pcc_thunk__destroy(pcc_auxil_t auxil, pcc_thunk_t *thunk) {
468
+ if (thunk == NULL) return;
469
+ switch (thunk->type) {
470
+ case PCC_THUNK_LEAF:
471
+ PCC_FREE(auxil, thunk->data.leaf.capt0.string);
472
+ pcc_capture_const_table__term(auxil, &thunk->data.leaf.capts);
473
+ pcc_value_refer_table__term(auxil, &thunk->data.leaf.values);
474
+ break;
475
+ case PCC_THUNK_NODE:
476
+ break;
477
+ default: /* unknown */
478
+ break;
479
+ }
480
+ PCC_FREE(auxil, thunk);
481
+ }
482
+
483
+ static void pcc_thunk_array__init(pcc_auxil_t auxil, pcc_thunk_array_t *array) {
484
+ array->len = 0;
485
+ array->max = 0;
486
+ array->buf = NULL;
487
+ }
488
+
489
+ static void pcc_thunk_array__add(pcc_auxil_t auxil, pcc_thunk_array_t *array, pcc_thunk_t *thunk) {
490
+ if (array->max <= array->len) {
491
+ const size_t n = array->len + 1;
492
+ size_t m = array->max;
493
+ if (m == 0) m = PCC_ARRAY_MIN_SIZE;
494
+ while (m < n && m != 0) m <<= 1;
495
+ if (m == 0) m = n;
496
+ array->buf = (pcc_thunk_t **)PCC_REALLOC(auxil, array->buf, sizeof(pcc_thunk_t *) * m);
497
+ array->max = m;
498
+ }
499
+ array->buf[array->len++] = thunk;
500
+ }
501
+
502
+ static void pcc_thunk_array__revert(pcc_auxil_t auxil, pcc_thunk_array_t *array, size_t len) {
503
+ while (array->len > len) {
504
+ array->len--;
505
+ pcc_thunk__destroy(auxil, array->buf[array->len]);
506
+ }
507
+ }
508
+
509
+ static void pcc_thunk_array__term(pcc_auxil_t auxil, pcc_thunk_array_t *array) {
510
+ while (array->len > 0) {
511
+ array->len--;
512
+ pcc_thunk__destroy(auxil, array->buf[array->len]);
513
+ }
514
+ PCC_FREE(auxil, array->buf);
515
+ }
516
+
517
+ static void pcc_memory_recycler__init(pcc_auxil_t auxil, pcc_memory_recycler_t *recycler, size_t element_size) {
518
+ recycler->pool_list = NULL;
519
+ recycler->entry_list = NULL;
520
+ recycler->element_size = element_size;
521
+ }
522
+
523
+ static void *pcc_memory_recycler__supply(pcc_auxil_t auxil, pcc_memory_recycler_t *recycler) {
524
+ if (recycler->entry_list) {
525
+ pcc_memory_entry_t *const tmp = recycler->entry_list;
526
+ recycler->entry_list = tmp->next;
527
+ return tmp;
528
+ }
529
+ if (!recycler->pool_list || recycler->pool_list->unused == 0) {
530
+ size_t size = PCC_POOL_MIN_SIZE;
531
+ if (recycler->pool_list) {
532
+ size = recycler->pool_list->allocated << 1;
533
+ if (size == 0) size = recycler->pool_list->allocated;
534
+ }
535
+ {
536
+ pcc_memory_pool_t *const pool = (pcc_memory_pool_t *)PCC_MALLOC(
537
+ auxil, sizeof(pcc_memory_pool_t) + recycler->element_size * size
538
+ );
539
+ pool->allocated = size;
540
+ pool->unused = size;
541
+ pool->next = recycler->pool_list;
542
+ recycler->pool_list = pool;
543
+ }
544
+ }
545
+ recycler->pool_list->unused--;
546
+ return (char *)recycler->pool_list + sizeof(pcc_memory_pool_t) + recycler->element_size * recycler->pool_list->unused;
547
+ }
548
+
549
+ static void pcc_memory_recycler__recycle(pcc_auxil_t auxil, pcc_memory_recycler_t *recycler, void *ptr) {
550
+ pcc_memory_entry_t *const tmp = (pcc_memory_entry_t *)ptr;
551
+ tmp->next = recycler->entry_list;
552
+ recycler->entry_list = tmp;
553
+ }
554
+
555
+ static void pcc_memory_recycler__term(pcc_auxil_t auxil, pcc_memory_recycler_t *recycler) {
556
+ while (recycler->pool_list) {
557
+ pcc_memory_pool_t *const tmp = recycler->pool_list;
558
+ recycler->pool_list = tmp->next;
559
+ PCC_FREE(auxil, tmp);
560
+ }
561
+ }
562
+
563
+ MARK_FUNC_AS_USED
564
+ static pcc_thunk_chunk_t *pcc_thunk_chunk__create(pcc_context_t *ctx) {
565
+ pcc_thunk_chunk_t *const chunk = (pcc_thunk_chunk_t *)pcc_memory_recycler__supply(ctx->auxil, &ctx->thunk_chunk_recycler);
566
+ pcc_value_table__init(ctx->auxil, &chunk->values);
567
+ pcc_capture_table__init(ctx->auxil, &chunk->capts);
568
+ pcc_thunk_array__init(ctx->auxil, &chunk->thunks);
569
+ chunk->pos = 0;
570
+ return chunk;
571
+ }
572
+
573
+ static void pcc_thunk_chunk__destroy(pcc_context_t *ctx, pcc_thunk_chunk_t *chunk) {
574
+ if (chunk == NULL) return;
575
+ pcc_thunk_array__term(ctx->auxil, &chunk->thunks);
576
+ pcc_capture_table__term(ctx->auxil, &chunk->capts);
577
+ pcc_value_table__term(ctx->auxil, &chunk->values);
578
+ pcc_memory_recycler__recycle(ctx->auxil, &ctx->thunk_chunk_recycler, chunk);
579
+ }
580
+
581
+ static void pcc_rule_set__init(pcc_auxil_t auxil, pcc_rule_set_t *set) {
582
+ set->len = 0;
583
+ set->max = 0;
584
+ set->buf = NULL;
585
+ }
586
+
587
+ static size_t pcc_rule_set__index(pcc_auxil_t auxil, const pcc_rule_set_t *set, pcc_rule_t rule) {
588
+ size_t i;
589
+ for (i = 0; i < set->len; i++) {
590
+ if (set->buf[i] == rule) return i;
591
+ }
592
+ return PCC_VOID_VALUE;
593
+ }
594
+
595
+ static pcc_bool_t pcc_rule_set__add(pcc_auxil_t auxil, pcc_rule_set_t *set, pcc_rule_t rule) {
596
+ const size_t i = pcc_rule_set__index(auxil, set, rule);
597
+ if (i != PCC_VOID_VALUE) return PCC_FALSE;
598
+ if (set->max <= set->len) {
599
+ const size_t n = set->len + 1;
600
+ size_t m = set->max;
601
+ if (m == 0) m = PCC_ARRAY_MIN_SIZE;
602
+ while (m < n && m != 0) m <<= 1;
603
+ if (m == 0) m = n;
604
+ set->buf = (pcc_rule_t *)PCC_REALLOC(auxil, set->buf, sizeof(pcc_rule_t) * m);
605
+ set->max = m;
606
+ }
607
+ set->buf[set->len++] = rule;
608
+ return PCC_TRUE;
609
+ }
610
+
611
+ static void pcc_rule_set__term(pcc_auxil_t auxil, pcc_rule_set_t *set) {
612
+ PCC_FREE(auxil, set->buf);
613
+ }
614
+
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;
618
+ <%- if @location -%>
619
+ memo->offset_loc = offset_loc;
620
+ <%- end -%>
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;
634
+ }
635
+ memo->chunk = chunk;
636
+ memo->fail = PCC_FALSE;
637
+ }
638
+
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;
645
+ }
646
+ }
647
+
648
+ static void pcc_lr_memo_map__init(pcc_auxil_t auxil, pcc_lr_memo_map_t *map) {
649
+ map->len = 0;
650
+ map->max = 0;
651
+ map->buf = NULL;
652
+ }
653
+
654
+ static size_t pcc_lr_memo_map__index(pcc_context_t *ctx, pcc_lr_memo_map_t *map, pcc_rule_t rule) {
655
+ size_t i;
656
+ for (i = 0; i < map->len; i++) {
657
+ if (map->buf[i].rule == rule) return i;
658
+ }
659
+ return PCC_VOID_VALUE;
660
+ }
661
+
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) {
663
+ const size_t i = pcc_lr_memo_map__index(ctx, map, rule);
664
+ if (i != PCC_VOID_VALUE) {
665
+ pcc_lr_memo__destroy(ctx, map->buf[i].memo);
666
+ map->buf[i].memo = memo;
667
+ }
668
+ else {
669
+ if (map->max <= map->len) {
670
+ const size_t n = map->len + 1;
671
+ size_t m = map->max;
672
+ if (m == 0) m = PCC_ARRAY_MIN_SIZE;
673
+ while (m < n && m != 0) m <<= 1;
674
+ if (m == 0) m = n;
675
+ map->buf = (pcc_lr_memo_map_entry_t *)PCC_REALLOC(ctx->auxil, map->buf, sizeof(pcc_lr_memo_map_entry_t) * m);
676
+ map->max = m;
677
+ }
678
+ map->buf[map->len].rule = rule;
679
+ map->buf[map->len].memo = memo;
680
+ map->len++;
681
+ }
682
+ }
683
+
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) {
685
+ const size_t i = pcc_lr_memo_map__index(ctx, map, rule);
686
+ return (i != PCC_VOID_VALUE) ? map->buf[i].memo : NULL;
687
+ }
688
+
689
+ static void pcc_lr_memo_map__term(pcc_context_t *ctx, pcc_lr_memo_map_t *map) {
690
+ while (map->len > 0) {
691
+ map->len--;
692
+ pcc_lr_memo__destroy(ctx, map->buf[map->len].memo);
693
+ }
694
+ PCC_FREE(ctx->auxil, map->buf);
695
+ }
696
+
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;
701
+ }
702
+
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);
707
+ }
708
+
709
+ static void pcc_lr_table__init(pcc_auxil_t auxil, pcc_lr_table_t *table) {
710
+ table->ofs = 0;
711
+ table->len = 0;
712
+ table->max = 0;
713
+ table->buf = NULL;
714
+ }
715
+
716
+ static void pcc_lr_table__resize(pcc_context_t *ctx, pcc_lr_table_t *table, size_t len) {
717
+ size_t i;
718
+ for (i = len; i < table->len; i++) pcc_lr_memo_map__destroy(ctx, table->buf[i]);
719
+ if (table->max < len) {
720
+ size_t m = table->max;
721
+ if (m == 0) m = PCC_ARRAY_MIN_SIZE;
722
+ while (m < len && m != 0) m <<= 1;
723
+ if (m == 0) m = len;
724
+ table->buf = (pcc_lr_memo_map_t **)PCC_REALLOC(ctx->auxil, table->buf, sizeof(pcc_lr_memo_map_t *) * m);
725
+ table->max = m;
726
+ }
727
+ for (i = table->len; i < len; i++) table->buf[i] = NULL;
728
+ table->len = len;
729
+ }
730
+
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) {
732
+ index += table->ofs;
733
+ if (index >= table->len) pcc_lr_table__resize(ctx, table, index + 1);
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);
736
+ }
737
+
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) {
739
+ index += table->ofs;
740
+ if (index >= table->len || table->buf[index] == NULL) return NULL;
741
+ return pcc_lr_memo_map__get(ctx, table->buf[index], rule);
742
+ }
743
+
744
+ static void pcc_lr_table__shift(pcc_context_t *ctx, pcc_lr_table_t *table, size_t count) {
745
+ size_t i;
746
+ if (count > table->len - table->ofs) count = table->len - table->ofs;
747
+ for (i = 0; i < count; i++) pcc_lr_memo_map__destroy(ctx, table->buf[table->ofs++]);
748
+ if (table->ofs > (table->max >> 1)) {
749
+ memmove(table->buf, table->buf + table->ofs, sizeof(pcc_lr_memo_map_t *) * (table->len - table->ofs));
750
+ table->len -= table->ofs;
751
+ table->ofs = 0;
752
+ }
753
+ }
754
+
755
+ static void pcc_lr_table__term(pcc_context_t *ctx, pcc_lr_table_t *table) {
756
+ while (table->len > table->ofs) {
757
+ table->len--;
758
+ pcc_lr_memo_map__destroy(ctx, table->buf[table->len]);
759
+ }
760
+ PCC_FREE(ctx->auxil, table->buf);
761
+ }
762
+
763
+ static pcc_context_t *pcc_context__create(pcc_auxil_t auxil) {
764
+ pcc_context_t *const ctx = (pcc_context_t *)PCC_MALLOC(auxil, sizeof(pcc_context_t));
765
+ ctx->buffer_start_position = 0;
766
+ ctx->position_offset = 0;
767
+ <%- if @location -%>
768
+ pcc_location_init(&ctx->buffer_start_position_loc);
769
+ pcc_location_init(&ctx->position_offset_loc);
770
+ <%- end -%>
771
+ ctx->level = 0;
772
+ pcc_char_array__init(auxil, &ctx->buffer);
773
+ pcc_lr_table__init(auxil, &ctx->lrtable);
774
+ pcc_thunk_array__init(auxil, &ctx->thunks);
775
+ pcc_memory_recycler__init(auxil, &ctx->thunk_chunk_recycler, sizeof(pcc_thunk_chunk_t));
776
+ pcc_memory_recycler__init(auxil, &ctx->lr_memo_recycler, sizeof(pcc_lr_memo_t));
777
+ ctx->auxil = auxil;
778
+ return ctx;
779
+ }
780
+
781
+ static void pcc_context__destroy(pcc_context_t *ctx) {
782
+ if (ctx == NULL) return;
783
+ pcc_thunk_array__term(ctx->auxil, &ctx->thunks);
784
+ pcc_lr_table__term(ctx, &ctx->lrtable);
785
+ pcc_char_array__term(ctx->auxil, &ctx->buffer);
786
+ pcc_memory_recycler__term(ctx->auxil, &ctx->thunk_chunk_recycler);
787
+ pcc_memory_recycler__term(ctx->auxil, &ctx->lr_memo_recycler);
788
+ PCC_FREE(ctx->auxil, ctx);
789
+ }
790
+
791
+ static size_t pcc_refill_buffer(pcc_context_t *ctx, size_t 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) {
794
+ const int c = PCC_GETCHAR(ctx->auxil);
795
+ if (c < 0) break;
796
+ pcc_char_array__add(ctx->auxil, &ctx->buffer, (char)c);
797
+ }
798
+ return ctx->buffer.len - ctx->position_offset;
799
+ }
800
+
801
+ MARK_FUNC_AS_USED
802
+ static void pcc_commit_buffer(pcc_context_t *ctx) {
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;
808
+ <%- if @location -%>
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);
811
+ <%- end -%>
812
+ }
813
+
814
+ MARK_FUNC_AS_USED
815
+ static const char *pcc_get_capture_string(pcc_context_t *ctx, const pcc_capture_t *capt) {
816
+ if (capt->string == NULL)
817
+ ((pcc_capture_t *)capt)->string =
818
+ pcc_strndup_e(ctx->auxil, ctx->buffer.buf + capt->range.start, capt->range.end - capt->range.start);
819
+ return capt->string;
820
+ }
821
+
822
+ <% if @utf8 -%>
823
+ static size_t pcc_get_char_as_utf32(pcc_context_t *ctx, int *out) { /* with checking UTF-8 validity */
824
+ int c, u;
825
+ size_t n;
826
+ if (pcc_refill_buffer(ctx, 1) < 1) return 0;
827
+ c = (int)(unsigned char)ctx->buffer.buf[ctx->position_offset];
828
+ n = (c < 0x80) ? 1 :
829
+ ((c & 0xe0) == 0xc0) ? 2 :
830
+ ((c & 0xf0) == 0xe0) ? 3 :
831
+ ((c & 0xf8) == 0xf0) ? 4 : 0;
832
+ if (n < 1) return 0;
833
+ if (pcc_refill_buffer(ctx, n) < n) return 0;
834
+ switch (n) {
835
+ case 1:
836
+ u = c;
837
+ break;
838
+ case 2:
839
+ u = c & 0x1f;
840
+ c = (int)(unsigned char)ctx->buffer.buf[ctx->position_offset + 1];
841
+ if ((c & 0xc0) != 0x80) return 0;
842
+ u <<= 6; u |= c & 0x3f;
843
+ if (u < 0x80) return 0;
844
+ break;
845
+ case 3:
846
+ u = c & 0x0f;
847
+ c = (int)(unsigned char)ctx->buffer.buf[ctx->position_offset + 1];
848
+ if ((c & 0xc0) != 0x80) return 0;
849
+ u <<= 6; u |= c & 0x3f;
850
+ c = (int)(unsigned char)ctx->buffer.buf[ctx->position_offset + 2];
851
+ if ((c & 0xc0) != 0x80) return 0;
852
+ u <<= 6; u |= c & 0x3f;
853
+ if (u < 0x800) return 0;
854
+ break;
855
+ case 4:
856
+ u = c & 0x07;
857
+ c = (int)(unsigned char)ctx->buffer.buf[ctx->position_offset + 1];
858
+ if ((c & 0xc0) != 0x80) return 0;
859
+ u <<= 6; u |= c & 0x3f;
860
+ c = (int)(unsigned char)ctx->buffer.buf[ctx->position_offset + 2];
861
+ if ((c & 0xc0) != 0x80) return 0;
862
+ u <<= 6; u |= c & 0x3f;
863
+ c = (int)(unsigned char)ctx->buffer.buf[ctx->position_offset + 3];
864
+ if ((c & 0xc0) != 0x80) return 0;
865
+ u <<= 6; u |= c & 0x3f;
866
+ if (u < 0x10000 || u > 0x10ffff) return 0;
867
+ break;
868
+ default:
869
+ return 0;
870
+ }
871
+ if (out) *out = u;
872
+ return n;
873
+ }
874
+
875
+ <% end -%>
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;
883
+ <%- if @location -%>
884
+ ctx->position_offset_loc = offset_loc;
885
+ <%- end -%>
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;
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 -%>
902
+ }
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;
909
+ <%- if @location -%>
910
+ pcc_location_t offset_loc = ctx->position_offset_loc;
911
+ <%- end -%>
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;
920
+ <%- if @location -%>
921
+ a->offset_loc = ctx->position_offset_loc;
922
+ <%- end -%>
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;
954
+ }
955
+ } else {
956
+ c = pcc_get_rule_thunk_chunk(ctx, rule);
957
+ }
958
+ if (c == NULL) return PCC_FALSE;
959
+ if (value == NULL) value = &null;
960
+ memset(value, 0, sizeof(pcc_value_t)); /* in case */
961
+ pcc_thunk_array__add(ctx->auxil, thunks, pcc_thunk__create_node(ctx->auxil, &c->thunks, value));
962
+ return PCC_TRUE;
963
+ }
964
+
965
+ MARK_FUNC_AS_USED
966
+ static void pcc_do_action(pcc_context_t *ctx, const pcc_thunk_array_t *thunks, pcc_value_t *value) {
967
+ size_t i;
968
+ for (i = 0; i < thunks->len; i++) {
969
+ pcc_thunk_t *const thunk = thunks->buf[i];
970
+ switch (thunk->type) {
971
+ case PCC_THUNK_LEAF:
972
+ thunk->data.leaf.action(ctx, thunk, value);
973
+ break;
974
+ case PCC_THUNK_NODE:
975
+ pcc_do_action(ctx, thunk->data.node.thunks, thunk->data.node.value);
976
+ break;
977
+ default: /* unknown */
978
+ break;
979
+ }
980
+ }
981
+ }
982
+
983
+ <%- @root.rules.each do |rule| -%>
984
+ <%- rule.codes.each do |code| -%>
985
+ static void pcc_action_<%= rule.name %>_<%= code.index %>(<%= prefix %>_context_t *__pcc_ctx, pcc_thunk_t *__pcc_in, pcc_value_t *__pcc_out) {
986
+ #define auxil (__pcc_ctx->auxil)
987
+ #define __ (*__pcc_out)
988
+ <%- code.vars.each do |ref| -%>
989
+ #define <%= ref.var %> (*__pcc_in->data.leaf.values.buf[<%= ref.index %>])
990
+ <% end -%>
991
+ #define _0 pcc_get_capture_string(__pcc_ctx, &__pcc_in->data.leaf.capt0)
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))
994
+ <%- if @location -%>
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)))
997
+ <%- end -%>
998
+ <%- if @capture_in_code -%>
999
+ #define _0c __pcc_in->data.leaf.capt0
1000
+ <%- end -%>
1001
+ <% code.capts.each do |capture| -%>
1002
+ #define _<%= capture.index + 1 %> pcc_get_capture_string(__pcc_ctx, __pcc_in->data.leaf.capts.buf[<%= capture.index %>])
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))
1005
+ <%- if @location -%>
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)))
1008
+ <%- end -%>
1009
+ <%- if @capture_in_code -%>
1010
+ #define _<%= capture.index + 1 %>c (*__pcc_in->data.leaf.capts.buf[<%= capture.index %>])
1011
+ <%- end -%>
1012
+ <%- end -%>
1013
+ <%= stream.get_code_block(code.code, 4, @iname) -%>
1014
+ <%- code.capts.reverse_each do |capture| -%>
1015
+ <%- if @location -%>
1016
+ #undef _<%= capture.index + 1 %>el
1017
+ #undef _<%= capture.index + 1 %>sl
1018
+ <%- end -%>
1019
+ #undef _<%= capture.index + 1 %>e
1020
+ #undef _<%= capture.index + 1 %>s
1021
+ #undef _<%= capture.index + 1 %>
1022
+ <%- end -%>
1023
+ #undef _0e
1024
+ #undef _0s
1025
+ #undef _0
1026
+ <%- code.vars.reverse_each do |ref| -%>
1027
+ #undef <%= ref.var %>
1028
+ <%- end -%>
1029
+ #undef __
1030
+ #undef auxil
1031
+ }
1032
+
1033
+ <%- end -%>
1034
+ <%- end -%>
1035
+ <%- @root.rules.each do |rule| -%>
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);
1037
+ <%- end -%>
1038
+
1039
+ <%- @root.rules.each do |rule| -%>
1040
+ <%- gen = ::Packcr::Generator.new(rule, @ascii, @location) -%>
1041
+ <%= gen.generate_code(rule, 0, 0, false) -%>
1042
+
1043
+ <%- end -%>
1044
+ <%= prefix %>_context_t *<%= prefix %>_create(<%= auxil_def %>auxil) {
1045
+ return pcc_context__create(auxil);
1046
+ }
1047
+
1048
+ int <%= prefix %>_parse(<%= prefix %>_context_t *ctx, <%= value_def %>*ret) {
1049
+ size_t pos = ctx->buffer_start_position;
1050
+ <%- if !@root.rules.empty? -%>
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))
1052
+ pcc_do_action(ctx, &ctx->thunks, ret);
1053
+ else
1054
+ PCC_ERROR(ctx->auxil);
1055
+ pcc_commit_buffer(ctx);
1056
+ <%- end -%>
1057
+ pcc_thunk_array__revert(ctx->auxil, &ctx->thunks, 0);
1058
+ return pos != ctx->buffer_start_position && pcc_refill_buffer(ctx, 1) >= 1;
1059
+ }
1060
+
1061
+ void <%= prefix %>_destroy(<%= prefix %>_context_t *ctx) {
1062
+ pcc_context__destroy(ctx);
1063
+ }
1064
+ <%- if !code(:lsource).empty? -%>
1065
+
1066
+ <%- code(:lsource).each do |code| -%>
1067
+ <%= stream.get_code_block(code, 0, @iname) -%>
1068
+ <%- end -%>
1069
+ <%- end -%>