Skip to content

Commit 36fcf5d

Browse files
committed
Support programmable predicates
1 parent 05847e3 commit 36fcf5d

File tree

14 files changed

+1114
-171
lines changed

14 files changed

+1114
-171
lines changed

README.md

Lines changed: 331 additions & 101 deletions
Large diffs are not rendered by default.

import/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ In this directory, import files are stored.
99
| Category Name | Description |
1010
| --- | --- |
1111
| [`char`](char) | Import files that define character matching rules. |
12-
| [`code`](code)| Import files that provide utility codes. |
12+
| [`code`](code) | Import files that provide utility codes. |
13+
| [`lang`](lang) | Import files that build ASTs of specific languages. |

import/code/README.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ The usage procedure is shown below.
2929
3. Create an AST node using either of the following functions in every rule action.
3030
- `pcc_ast_node_t *pcc_ast_node__create_0(void);`
3131
+ Returns a newly created nullary node.
32+
- `pcc_ast_node_t *pcc_ast_node__create_0_str(const char *str);`
33+
+ Returns a newly created nullary node retaining a copy of the specified string.
34+
+ The string can be accessed using `const char *${prefix}_ast_node__get_string(pcc_ast_node_t *node)`.
3235
- `pcc_ast_node_t *pcc_ast_node__create_1(pcc_ast_node_t *node);`
3336
+ Returns a newly created unary node with one child node specified by the argument `node`.
3437
- `pcc_ast_node_t *pcc_ast_node__create_2(pcc_ast_node_t *node0, pcc_ast_node_t *node1);`
@@ -41,7 +44,19 @@ The usage procedure is shown below.
4144
+ Adds a child node specified by the argument `node` to the variadic node `obj`.
4245
+ Can be used for `obj` as a variadic node only.
4346

44-
An example is shown below.
47+
There are the variants of the node creation functions that enable setting a label as an `int` value.
48+
The label can be used for specifying node kinds in order to make it easier to analyze the AST in the later parsing steps.
49+
- `pcc_ast_node_t *pcc_ast_node__create_0_ext(int label);`
50+
- `pcc_ast_node_t *pcc_ast_node__create_0_ext_str(int label, const char *str);`
51+
- `pcc_ast_node_t *pcc_ast_node__create_1_ext(int label, pcc_ast_node_t *node);`
52+
- `pcc_ast_node_t *pcc_ast_node__create_2_ext(int label, pcc_ast_node_t *node0, pcc_ast_node_t *node1);`
53+
- `pcc_ast_node_t *pcc_ast_node__create_3_ext(int label, pcc_ast_node_t *node0, pcc_ast_node_t *node1, pcc_ast_node_t *node2);`
54+
- `pcc_ast_node_t *pcc_ast_node__create_v_ext(int label);`
55+
56+
Every AST node retains the rule pattern matching range in the member variable `range`.
57+
Namely, `obj->range.start` and `obj->range.end` memorize `$0s` and `$0e` respectively at the time when the node `obj` was created in a rule action.
58+
59+
A usage example is shown below.
4560
```
4661
rule0 <- l:rule1 '+' r:rule1 { $$ = pcc_ast_node__create_2(l, r); }
4762
rule1 <- [0-9]+ { $$ = pcc_ast_node__create_0(); }

import/code/pcc_ast.peg

Lines changed: 89 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1919
# THE SOFTWARE.
2020

21-
# AST utility import file: version 2.0.0
21+
# AST utility import file: version 2.1.0
2222

2323
%header {
2424
#ifdef __cplusplus
@@ -28,6 +28,10 @@ extern "C" {
2828
typedef struct ${prefix}_ast_manager_tag ${prefix}_ast_manager_t;
2929
typedef struct ${prefix}_ast_node_tag ${prefix}_ast_node_t;
3030

31+
typedef struct ${prefix}_ast_range_tag {
32+
size_t start, end;
33+
} ${prefix}_ast_range_t;
34+
3135
typedef enum ${prefix}_ast_node_type_tag {
3236
${PREFIX}_AST_NODE_TYPE_NULLARY,
3337
${PREFIX}_AST_NODE_TYPE_UNARY,
@@ -67,6 +71,11 @@ struct ${prefix}_ast_node_tag {
6771
${prefix}_ast_node_t *parent;
6872
${prefix}_ast_node_type_t type;
6973
${prefix}_ast_node_data_t data;
74+
${prefix}_ast_range_t range;
75+
int label;
76+
#ifndef ${PREFIX}_AST_NODE_STRING_CAPTURING_DISABLED
77+
char *string;
78+
#endif
7079
#ifdef ${PREFIX}_AST_NODE_CUSTOM_DATA_DEFINED
7180
${prefix}_ast_node_custom_data_t custom;
7281
#endif
@@ -79,21 +88,32 @@ struct ${prefix}_ast_manager_tag {
7988
#endif
8089
};
8190

91+
${prefix}_ast_range_t ${prefix}_ast_range__new(size_t start, size_t end);
92+
8293
void ${prefix}_ast_manager__initialize(${prefix}_ast_manager_t *obj);
8394
void ${prefix}_ast_manager__finalize(${prefix}_ast_manager_t *obj);
8495

96+
char *${prefix}_ast__strdup(${prefix}_ast_manager_t *mgr, const char *str);
97+
8598
void ${prefix}_ast_node_array__initialize(${prefix}_ast_manager_t *mgr, ${prefix}_ast_node_array_t *obj);
8699
void ${prefix}_ast_node_array__finalize(${prefix}_ast_manager_t *mgr, ${prefix}_ast_node_array_t *obj);
87100
void ${prefix}_ast_node_array__add(${prefix}_ast_manager_t *mgr, ${prefix}_ast_node_array_t *obj, ${prefix}_ast_node_t *node);
88101

89-
${prefix}_ast_node_t *${prefix}_ast_node__create_nullary(${prefix}_ast_manager_t *mgr);
90-
${prefix}_ast_node_t *${prefix}_ast_node__create_unary(${prefix}_ast_manager_t *mgr, ${prefix}_ast_node_t *node);
91-
${prefix}_ast_node_t *${prefix}_ast_node__create_binary(${prefix}_ast_manager_t *mgr, ${prefix}_ast_node_t *node0, ${prefix}_ast_node_t *node1);
92-
${prefix}_ast_node_t *${prefix}_ast_node__create_ternary(${prefix}_ast_manager_t *mgr, ${prefix}_ast_node_t *node0, ${prefix}_ast_node_t *node1, ${prefix}_ast_node_t *node2);
93-
${prefix}_ast_node_t *${prefix}_ast_node__create_variadic(${prefix}_ast_manager_t *mgr);
94-
${prefix}_ast_node_t *${prefix}_ast_node__add_child(${prefix}_ast_node_t *obj, ${prefix}_ast_node_t *node); /* for variadic node only */
102+
${prefix}_ast_node_t *${prefix}_ast_node__create_nullary(${prefix}_ast_manager_t *mgr, ${prefix}_ast_range_t range, int label);
103+
${prefix}_ast_node_t *${prefix}_ast_node__create_nullary_with_literal(${prefix}_ast_manager_t *mgr, ${prefix}_ast_range_t range, int label, const char *string);
104+
${prefix}_ast_node_t *${prefix}_ast_node__create_unary(${prefix}_ast_manager_t *mgr, ${prefix}_ast_range_t range, int label, ${prefix}_ast_node_t *node);
105+
${prefix}_ast_node_t *${prefix}_ast_node__create_binary(${prefix}_ast_manager_t *mgr, ${prefix}_ast_range_t range, int label, ${prefix}_ast_node_t *node0, ${prefix}_ast_node_t *node1);
106+
${prefix}_ast_node_t *${prefix}_ast_node__create_ternary(${prefix}_ast_manager_t *mgr, ${prefix}_ast_range_t range, int label, ${prefix}_ast_node_t *node0, ${prefix}_ast_node_t *node1, ${prefix}_ast_node_t *node2);
107+
${prefix}_ast_node_t *${prefix}_ast_node__create_variadic(${prefix}_ast_manager_t *mgr, ${prefix}_ast_range_t range, int label);
108+
${prefix}_ast_node_t *${prefix}_ast_node__add_child(${prefix}_ast_node_t *obj, ${prefix}_ast_node_t *node); /* for a variadic node only */
95109
void ${prefix}_ast_node__destroy(${prefix}_ast_node_t *obj);
96110

111+
#ifndef ${PREFIX}_AST_NODE_STRING_CAPTURING_DISABLED
112+
#define ${prefix}_ast_node__get_string(obj) ((const char *)(obj->string))
113+
#else
114+
#define ${prefix}_ast_node__get_string(obj) ((const char *)NULL)
115+
#endif
116+
97117
#ifdef ${PREFIX}_AST_MANAGER_CUSTOM_DATA_DEFINED
98118
void ${prefix}_ast_manager_custom_data__initialize(${prefix}_ast_manager_custom_data_t *obj);
99119
void ${prefix}_ast_manager_custom_data__finalize(${prefix}_ast_manager_custom_data_t *obj);
@@ -116,14 +136,25 @@ void ${prefix}_ast_node_custom_data__finalize(${prefix}_ast_node_custom_data_t *
116136
}
117137

118138
%source {
119-
#define ${prefix}_ast_node__create_0() ${prefix}_ast_node__create_nullary(auxil)
120-
#define ${prefix}_ast_node__create_1(node) ${prefix}_ast_node__create_unary(auxil, node)
121-
#define ${prefix}_ast_node__create_2(node0, node1) ${prefix}_ast_node__create_binary(auxil, node0, node1)
122-
#define ${prefix}_ast_node__create_3(node0, node1, node2) ${prefix}_ast_node__create_ternary(auxil, node0, node1, node2)
123-
#define ${prefix}_ast_node__create_v() ${prefix}_ast_node__create_variadic(auxil)
139+
#define ${prefix}_ast__matched_range() ${prefix}_ast_range__new(pcc_capture__0s, pcc_capture__0e)
140+
141+
#define ${prefix}_ast_node__create_0() ${prefix}_ast_node__create_nullary(auxil, ${prefix}_ast__matched_range(), 0)
142+
#define ${prefix}_ast_node__create_0_str(str) ${prefix}_ast_node__create_nullary_with_literal(auxil, ${prefix}_ast__matched_range(), 0, str)
143+
#define ${prefix}_ast_node__create_1(node) ${prefix}_ast_node__create_unary(auxil, ${prefix}_ast__matched_range(), 0, node)
144+
#define ${prefix}_ast_node__create_2(node0, node1) ${prefix}_ast_node__create_binary(auxil, ${prefix}_ast__matched_range(), 0, node0, node1)
145+
#define ${prefix}_ast_node__create_3(node0, node1, node2) ${prefix}_ast_node__create_ternary(auxil, ${prefix}_ast__matched_range(), 0, node0, node1, node2)
146+
#define ${prefix}_ast_node__create_v() ${prefix}_ast_node__create_variadic(auxil, ${prefix}_ast__matched_range(), 0)
147+
148+
#define ${prefix}_ast_node__create_0_ext(label) ${prefix}_ast_node__create_nullary(auxil, ${prefix}_ast__matched_range(), label)
149+
#define ${prefix}_ast_node__create_0_ext_str(label, str) ${prefix}_ast_node__create_nullary_with_literal(auxil, ${prefix}_ast__matched_range(), label, str)
150+
#define ${prefix}_ast_node__create_1_ext(label, node) ${prefix}_ast_node__create_unary(auxil, ${prefix}_ast__matched_range(), label, node)
151+
#define ${prefix}_ast_node__create_2_ext(label, node0, node1) ${prefix}_ast_node__create_binary(auxil, ${prefix}_ast__matched_range(), label, node0, node1)
152+
#define ${prefix}_ast_node__create_3_ext(label, node0, node1, node2) ${prefix}_ast_node__create_ternary(auxil, ${prefix}_ast__matched_range(), label, node0, node1, node2)
153+
#define ${prefix}_ast_node__create_v_ext(label) ${prefix}_ast_node__create_variadic(auxil, ${prefix}_ast__matched_range(), label)
124154
}
125155

126156
%%
157+
#include <string.h>
127158
#include <assert.h>
128159

129160
#ifndef PCC_AST_NODE_ARRAY_MIN_SIZE
@@ -142,6 +173,13 @@ void ${prefix}_ast_node_custom_data__finalize(${prefix}_ast_node_custom_data_t *
142173
#define PCC_AST_FREE(mgr, ptr) PCC_FREE(mgr, ptr)
143174
#endif
144175

176+
${prefix}_ast_range_t ${prefix}_ast_range__new(size_t start, size_t end) {
177+
${prefix}_ast_range_t obj;
178+
obj.start = start;
179+
obj.end = end;
180+
return obj;
181+
}
182+
145183
void ${prefix}_ast_manager__initialize(${prefix}_ast_manager_t *obj) {
146184
obj->first = NULL;
147185
${prefix}_ast_manager_custom_data__initialize(&(obj->custom));
@@ -155,6 +193,18 @@ void ${prefix}_ast_manager__finalize(${prefix}_ast_manager_t *obj) {
155193
}
156194
}
157195

196+
char *${prefix}_ast__strdup(${prefix}_ast_manager_t *mgr, const char *str) {
197+
if (str) {
198+
const size_t l = strlen(str) + 1;
199+
char *const p = (char *)PCC_AST_MALLOC(mgr, l);
200+
memcpy(p, str, l);
201+
return p;
202+
}
203+
else {
204+
return NULL;
205+
}
206+
}
207+
158208
void ${prefix}_ast_node_array__initialize(${prefix}_ast_manager_t *mgr, ${prefix}_ast_node_array_t *obj) {
159209
obj->len = 0;
160210
obj->max = 0;
@@ -239,7 +289,7 @@ static void ${prefix}_ast_node__unlink_parent_(${prefix}_ast_node_t *obj) {
239289
}
240290
}
241291

242-
static ${prefix}_ast_node_t *${prefix}_ast_node__create_(${prefix}_ast_manager_t *mgr) {
292+
static ${prefix}_ast_node_t *${prefix}_ast_node__create_(${prefix}_ast_manager_t *mgr, ${prefix}_ast_range_t range, int label) {
243293
${prefix}_ast_node_t *const obj = (${prefix}_ast_node_t *)PCC_AST_MALLOC(mgr, sizeof(${prefix}_ast_node_t));
244294
obj->manager = mgr;
245295
if (mgr->first) {
@@ -253,18 +303,31 @@ static ${prefix}_ast_node_t *${prefix}_ast_node__create_(${prefix}_ast_manager_t
253303
obj->prev = NULL;
254304
mgr->first = obj;
255305
obj->parent = NULL;
306+
obj->range = range;
307+
obj->label = label;
308+
#ifndef ${PREFIX}_AST_NODE_STRING_CAPTURING_DISABLED
309+
obj->string = NULL;
310+
#endif
256311
return obj;
257312
}
258313

259-
${prefix}_ast_node_t *${prefix}_ast_node__create_nullary(${prefix}_ast_manager_t *mgr) {
260-
${prefix}_ast_node_t *const obj = ${prefix}_ast_node__create_(mgr);
314+
${prefix}_ast_node_t *${prefix}_ast_node__create_nullary(${prefix}_ast_manager_t *mgr, ${prefix}_ast_range_t range, int label) {
315+
${prefix}_ast_node_t *const obj = ${prefix}_ast_node__create_(mgr, range, label);
261316
obj->type = ${PREFIX}_AST_NODE_TYPE_NULLARY;
262317
${prefix}_ast_node_custom_data__initialize(&(obj->custom));
263318
return obj;
264319
}
265320

266-
${prefix}_ast_node_t *${prefix}_ast_node__create_unary(${prefix}_ast_manager_t *mgr, ${prefix}_ast_node_t *node) {
267-
${prefix}_ast_node_t *const obj = ${prefix}_ast_node__create_(mgr);
321+
${prefix}_ast_node_t *${prefix}_ast_node__create_nullary_with_literal(${prefix}_ast_manager_t *mgr, ${prefix}_ast_range_t range, int label, const char *string) {
322+
${prefix}_ast_node_t *const obj = ${prefix}_ast_node__create_nullary(mgr, range, label);
323+
#ifndef ${PREFIX}_AST_NODE_STRING_CAPTURING_DISABLED
324+
obj->string = ${prefix}_ast__strdup(mgr, string);
325+
#endif
326+
return obj;
327+
}
328+
329+
${prefix}_ast_node_t *${prefix}_ast_node__create_unary(${prefix}_ast_manager_t *mgr, ${prefix}_ast_range_t range, int label, ${prefix}_ast_node_t *node) {
330+
${prefix}_ast_node_t *const obj = ${prefix}_ast_node__create_(mgr, range, label);
268331
obj->type = ${PREFIX}_AST_NODE_TYPE_UNARY;
269332
obj->data.unary.node = node;
270333
if (node) {
@@ -275,8 +338,8 @@ ${prefix}_ast_node_t *${prefix}_ast_node__create_unary(${prefix}_ast_manager_t *
275338
return obj;
276339
}
277340

278-
${prefix}_ast_node_t *${prefix}_ast_node__create_binary(${prefix}_ast_manager_t *mgr, ${prefix}_ast_node_t *node0, ${prefix}_ast_node_t *node1) {
279-
${prefix}_ast_node_t *const obj = ${prefix}_ast_node__create_(mgr);
341+
${prefix}_ast_node_t *${prefix}_ast_node__create_binary(${prefix}_ast_manager_t *mgr, ${prefix}_ast_range_t range, int label, ${prefix}_ast_node_t *node0, ${prefix}_ast_node_t *node1) {
342+
${prefix}_ast_node_t *const obj = ${prefix}_ast_node__create_(mgr, range, label);
280343
obj->type = ${PREFIX}_AST_NODE_TYPE_BINARY;
281344
obj->data.binary.node[0] = node0;
282345
obj->data.binary.node[1] = node1;
@@ -294,8 +357,8 @@ ${prefix}_ast_node_t *${prefix}_ast_node__create_binary(${prefix}_ast_manager_t
294357
return obj;
295358
}
296359

297-
${prefix}_ast_node_t *${prefix}_ast_node__create_ternary(${prefix}_ast_manager_t *mgr, ${prefix}_ast_node_t *node0, ${prefix}_ast_node_t *node1, ${prefix}_ast_node_t *node2) {
298-
${prefix}_ast_node_t *const obj = ${prefix}_ast_node__create_(mgr);
360+
${prefix}_ast_node_t *${prefix}_ast_node__create_ternary(${prefix}_ast_manager_t *mgr, ${prefix}_ast_range_t range, int label, ${prefix}_ast_node_t *node0, ${prefix}_ast_node_t *node1, ${prefix}_ast_node_t *node2) {
361+
${prefix}_ast_node_t *const obj = ${prefix}_ast_node__create_(mgr, range, label);
299362
obj->type = ${PREFIX}_AST_NODE_TYPE_TERNARY;
300363
obj->data.ternary.node[0] = node0;
301364
obj->data.ternary.node[1] = node1;
@@ -314,8 +377,8 @@ ${prefix}_ast_node_t *${prefix}_ast_node__create_ternary(${prefix}_ast_manager_t
314377
return obj;
315378
}
316379

317-
${prefix}_ast_node_t *${prefix}_ast_node__create_variadic(${prefix}_ast_manager_t *mgr) {
318-
${prefix}_ast_node_t *const obj = ${prefix}_ast_node__create_(mgr);
380+
${prefix}_ast_node_t *${prefix}_ast_node__create_variadic(${prefix}_ast_manager_t *mgr, ${prefix}_ast_range_t range, int label) {
381+
${prefix}_ast_node_t *const obj = ${prefix}_ast_node__create_(mgr, range, label);
319382
obj->type = ${PREFIX}_AST_NODE_TYPE_VARIADIC;
320383
${prefix}_ast_node_array__initialize(mgr, &(obj->data.variadic));
321384
${prefix}_ast_node_custom_data__initialize(&(obj->custom));
@@ -339,6 +402,9 @@ ${prefix}_ast_node_t *${prefix}_ast_node__add_child(${prefix}_ast_node_t *obj, $
339402
void ${prefix}_ast_node__destroy(${prefix}_ast_node_t *obj) {
340403
if (obj) {
341404
${prefix}_ast_node_custom_data__finalize(&(obj->custom));
405+
#ifndef ${PREFIX}_AST_NODE_STRING_CAPTURING_DISABLED
406+
PCC_AST_FREE(obj->manager, obj->string);
407+
#endif
342408
switch (obj->type) {
343409
case ${PREFIX}_AST_NODE_TYPE_NULLARY:
344410
break;

0 commit comments

Comments
 (0)