Skip to content

Commit 25ed98e

Browse files
committed
Add the import file code/pcc_ast.v3.peg
The upgraded version of `code/pcc_ast.peg`. Now, `code/pcc_ast.peg` is marked as deprecated.
1 parent aa4cd7f commit 25ed98e

File tree

10 files changed

+1327
-378
lines changed

10 files changed

+1327
-378
lines changed

README.md

+17-32
Original file line numberDiff line numberDiff line change
@@ -725,7 +725,7 @@ The following import files are currently bundled.
725725
- [`char/unicode_derived_core.peg`](import/char/unicode_derived_core.peg) :
726726
This provides various rules to match a Unicode character belonging to a specific [derived core property](https://www.unicode.org/reports/tr44/#DerivedCoreProperties.txt).
727727
- **Utility Codes**
728-
- [`code/pcc_ast.peg`](import/code/pcc_ast.peg) :
728+
- [`code/pcc_ast.v3.peg`](import/code/pcc_ast.v3.peg) :
729729
This provides codes to make it easier to build an AST (abstract syntax tree).
730730
731731
For details, see [here](import).
@@ -1049,7 +1049,7 @@ primary <- < [0-9]+ > { $$ = calc_ast_node__create_0(); $$->custom
10491049
_ <- [ \t]*
10501050
EOL <- '\n' / '\r\n' / '\r' / ';'
10511051
1052-
%import "code/pcc_ast.peg" # <-- provides AST build functions
1052+
%import "code/pcc_ast.v3.peg" # <-- provides AST build functions
10531053
10541054
%%
10551055
void calc_ast_node_custom_data__initialize(calc_ast_manager_t *mgr, calc_ast_node_custom_data_t *obj) {
@@ -1062,37 +1062,22 @@ void calc_ast_node_custom_data__finalize(calc_ast_manager_t *mgr, calc_ast_node_
10621062
10631063
static void dump_ast(const calc_ast_node_t *obj, int depth) {
10641064
if (obj) {
1065-
switch (obj->type) {
1066-
case CALC_AST_NODE_TYPE_NULLARY:
1067-
printf("%*s%s: \"%s\"\n", 2 * depth, "", "nullary", obj->custom.text);
1068-
break;
1069-
case CALC_AST_NODE_TYPE_UNARY:
1070-
printf("%*s%s: \"%s\"\n", 2 * depth, "", "unary", obj->custom.text);
1071-
dump_ast(obj->data.unary.node, depth + 1);
1072-
break;
1073-
case CALC_AST_NODE_TYPE_BINARY:
1074-
printf("%*s%s: \"%s\"\n", 2 * depth, "", "binary", obj->custom.text);
1075-
dump_ast(obj->data.binary.node[0], depth + 1);
1076-
dump_ast(obj->data.binary.node[1], depth + 1);
1077-
break;
1078-
case CALC_AST_NODE_TYPE_TERNARY:
1079-
printf("%*s%s: \"%s\"\n", 2 * depth, "", "ternary", obj->custom.text);
1080-
dump_ast(obj->data.ternary.node[0], depth + 1);
1081-
dump_ast(obj->data.ternary.node[1], depth + 1);
1082-
dump_ast(obj->data.ternary.node[2], depth + 1);
1083-
break;
1084-
case CALC_AST_NODE_TYPE_VARIADIC:
1085-
printf("%*s%s: \"%s\"\n", 2 * depth, "", "variadic", obj->custom.text);
1065+
const size_t n = calc_ast_node__get_child_count(obj);
1066+
const calc_ast_node_t *const *const p = calc_ast_node__get_child_array(obj);
1067+
const calc_ast_node_custom_data_t *const d = &(obj->custom);
1068+
const int b = calc_ast_node__is_variadic(obj);
1069+
if (b || n <= 3) {
1070+
static const char *const arity_name[] = { "nullary", "unary", "binary", "ternary" };
1071+
printf("%*s%s: \"%s\"\n", 2 * depth, "", b ? "variadic" : arity_name[n], d->text);
10861072
{
10871073
size_t i;
1088-
for (i = 0; i < obj->data.variadic.len; i++) {
1089-
dump_ast(obj->data.variadic.node[i], depth + 1);
1074+
for (i = 0; i < n; i++) {
1075+
dump_ast(p[i], depth + 1);
10901076
}
10911077
}
1092-
break;
1093-
default:
1094-
printf("%*s%s: \"%s\"\n", 2 * depth, "", "(unknown)", obj->custom.text);
1095-
break;
1078+
}
1079+
else {
1080+
printf("%*s%s: \"%s\"\n", 2 * depth, "", "(unknown)", d->text);
10961081
}
10971082
}
10981083
else {
@@ -1117,9 +1102,9 @@ int main(int argc, char **argv) {
11171102
}
11181103
```
11191104
1120-
The key point is the line `%import "code/pcc_ast.peg"`.
1121-
The import file [`code/pcc_ast.peg`](import/code) makes it easier to build ASTs.
1122-
For more details, see [here](import/code/README.md).
1105+
The key point is the line `%import "code/pcc_ast.v3.peg"`.
1106+
The import file [`code/pcc_ast.v3.peg`](import/code) makes it easier to build ASTs.
1107+
For more details, see [here](import/code/pcc_ast.v3.md).
11231108
11241109
An execution example is as follows.
11251110

examples/README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ In this directory, examples are stored.
77
## Example List
88

99
- [Desktop Calculator](calc.peg)
10-
- [Simple AST builder](ast-calc.peg)
10+
- [Simple AST builder](ast-calc.peg) : using `ast-calc.peg` (deprecated)
11+
- [Simple AST builder](ast-calc.v3.peg) : using `ast-calc.v3.peg`
1112
- [AST Builder for Tiny-C](ast-tinyc)
1213

1314
For details, see PackCC [README.md](../README.md).

examples/ast-calc.v3.peg

+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# This code is hereby placed in the public domain.
2+
#
3+
# THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
4+
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
5+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
6+
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
7+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
8+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
9+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
10+
# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
11+
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
12+
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
13+
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14+
15+
%prefix "calc"
16+
17+
%value "calc_ast_node_t *" # <-- must be set
18+
19+
%auxil "calc_ast_manager_t *" # <-- must be set
20+
21+
%header {
22+
#define CALC_AST_NODE_CUSTOM_DATA_DEFINED /* <-- enables node custom data */
23+
24+
typedef struct text_data_tag { /* <-- node custom data type */
25+
char *text;
26+
} calc_ast_node_custom_data_t;
27+
}
28+
29+
%source {
30+
#include <stdio.h>
31+
#include <string.h>
32+
}
33+
34+
statement <- _ e:expression _ EOL { $$ = e; }
35+
/ ( !EOL . )* EOL { $$ = NULL; }
36+
37+
expression <- e:term { $$ = e; }
38+
39+
term <- l:term _ '+' _ r:factor { $$ = calc_ast_node__create_2(l, r); $$->custom.text = strdup("+"); }
40+
/ l:term _ '-' _ r:factor { $$ = calc_ast_node__create_2(l, r); $$->custom.text = strdup("-"); }
41+
/ e:factor { $$ = e; }
42+
43+
factor <- l:factor _ '*' _ r:unary { $$ = calc_ast_node__create_2(l, r); $$->custom.text = strdup("*"); }
44+
/ l:factor _ '/' _ r:unary { $$ = calc_ast_node__create_2(l, r); $$->custom.text = strdup("/"); }
45+
/ e:unary { $$ = e; }
46+
47+
unary <- '+' _ e:unary { $$ = calc_ast_node__create_1(e); $$->custom.text = strdup("+"); }
48+
/ '-' _ e:unary { $$ = calc_ast_node__create_1(e); $$->custom.text = strdup("-"); }
49+
/ e:primary { $$ = e; }
50+
51+
primary <- < [0-9]+ > { $$ = calc_ast_node__create_0(); $$->custom.text = strdup($1); }
52+
/ '(' _ e:expression _ ')' { $$ = e; }
53+
54+
_ <- [ \t]*
55+
EOL <- '\n' / '\r\n' / '\r' / ';'
56+
57+
%import "code/pcc_ast.v3.peg" # <-- provides AST build functions
58+
59+
%%
60+
void calc_ast_node_custom_data__initialize(calc_ast_manager_t *mgr, calc_ast_node_custom_data_t *obj) {
61+
obj->text = NULL;
62+
} /* <-- must be implemented when enabling node custom data */
63+
64+
void calc_ast_node_custom_data__finalize(calc_ast_manager_t *mgr, calc_ast_node_custom_data_t *obj) {
65+
free(obj->text);
66+
} /* <-- must be implemented when enabling node custom data */
67+
68+
static void dump_ast(const calc_ast_node_t *obj, int depth) {
69+
if (obj) {
70+
const size_t n = calc_ast_node__get_child_count(obj);
71+
const calc_ast_node_t *const *const p = calc_ast_node__get_child_array(obj);
72+
const calc_ast_node_custom_data_t *const d = &(obj->custom);
73+
const int b = calc_ast_node__is_variadic(obj);
74+
if (b || n <= 3) {
75+
static const char *const arity_name[] = { "nullary", "unary", "binary", "ternary" };
76+
printf("%*s%s: \"%s\"\n", 2 * depth, "", b ? "variadic" : arity_name[n], d->text);
77+
{
78+
size_t i;
79+
for (i = 0; i < n; i++) {
80+
dump_ast(p[i], depth + 1);
81+
}
82+
}
83+
}
84+
else {
85+
printf("%*s%s: \"%s\"\n", 2 * depth, "", "(unknown)", d->text);
86+
}
87+
}
88+
else {
89+
printf("%*s(null)\n", 2 * depth, "");
90+
}
91+
}
92+
93+
int main(int argc, char **argv) {
94+
calc_ast_manager_t mgr;
95+
calc_ast_manager__initialize(&mgr);
96+
{
97+
calc_context_t *ctx = calc_create(&mgr);
98+
calc_ast_node_t *ast = NULL;
99+
while (calc_parse(ctx, &ast)) {
100+
dump_ast(ast, 0);
101+
calc_ast_node__destroy(&mgr, ast);
102+
}
103+
calc_destroy(ctx);
104+
}
105+
calc_ast_manager__finalize(&mgr);
106+
return 0;
107+
}

0 commit comments

Comments
 (0)