]> ocean-lang.org Git - ocean/blob - csrc/indent_test.mdc
55a0fe65a468a9d7217e28fedc51852c36b401b5
[ocean] / csrc / indent_test.mdc
1 This parser is primarily for testing indent and linebreak handling.
2 It reads a very simple code fragment with if/else statements and
3 simple assignments with expressions, and then prints out the same
4 with complete bracketing and indenting.
5
6 # File: indent_test.mk
7         myCFLAGS := -Wall -g -fplan9-extensions
8         CFLAGS := $(filter-out $(myCFLAGS),$(CFLAGS)) $(myCFLAGS)
9         myLDLIBS:= libparser.o libscanner.o libmdcode.o -licuuc
10         LDLIBS := $(filter-out $(myLDLIBS),$(LDLIBS)) $(myLDLIBS)
11
12         all :: itest
13         itest.c itest.h : indent_test.mdc parsergen libparser.o libscanner.o libmdcode.o
14                 ./parsergen -o itest --LALR --tag indent indent_test.mdc
15         indent_test.mk: indent_test.mdc md2c
16                 ./md2c indent_test.mdc
17         itest: itest.c
18
19         demos:: itest itest.code
20                 ./itest itest.code
21
22 # indent: header
23
24  ./parsergen -o itest --LALR indent_test.cgm
25  cc -o itest itest.c lib*.o -licuuc -lgmp
26  ./itest itest.code
27
28         struct expression {
29                 struct text op;
30                 struct expression *left, *right;
31         };
32         struct statement {
33                 struct statement *next;
34                 struct expression *expr;
35                 struct statement *thenpart;
36                 struct statement *elsepart;
37         };
38
39 # indent: code
40         #include <unistd.h>
41         #include <stdlib.h>
42         #include <fcntl.h>
43         #include <sys/mman.h>
44         #include <stdio.h>
45         #include "mdcode.h"
46         #include "scanner.h"
47         #include "parser.h"
48         #include "itest.h"
49
50         static void free_expression(struct expression *e)
51         {
52                 if (!e)
53                         return;
54                 free_expression(e->left);
55                 free_expression(e->right);
56                 free(e);
57         }
58
59         static void free_statement(struct statement *s)
60         {
61                 if (!s)
62                         return;
63                 free_statement(s->next);
64                 free_expression(s->expr);
65                 free_statement(s->thenpart);
66                 free_statement(s->elsepart);
67                 free(s);
68         }
69
70         static void print_expression(struct expression *e)
71         {
72                 if (e->left && e->right) printf("(");
73                 if (e->left)
74                         print_expression(e->left);
75                 if (e->op.len)
76                         printf("%.*s", e->op.len, e->op.txt);
77                 if (e->right)
78                         print_expression(e->right);
79                 if (e->left && e->right) printf(")");
80         }
81
82         static void print_statement(struct statement *s, int depth)
83         {
84                 if (!s)
85                         return;
86                 if (!s->thenpart) {
87                         printf("%*.s", depth, "");
88                         print_expression(s->expr);
89                         printf(";\n");
90                 } else {
91                         printf("%*.sif ", depth, "");
92                         print_expression(s->expr);
93                         printf(":\n");
94                         print_statement(s->thenpart, depth+4);
95                         if (s->elsepart) {
96                                 printf("%*.selse:\n", depth, "");
97                                 print_statement(s->elsepart, depth+4);
98                         }
99                 }
100                 print_statement(s->next, depth);
101         }
102
103         int main(int argc, char *argv[])
104         {
105                 int fd = open(argv[1], O_RDONLY);
106                 int len = lseek(fd, 0, 2);
107                 char *file = mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0);
108                 struct section *s = code_extract(file, file+len, NULL);
109                 struct token_config config = {
110                         .ignored = (1 << TK_line_comment)
111                                  | (1 << TK_block_comment),
112                         .number_chars = ".,_+-",
113                         .word_start = "",
114                         .word_cont = "",
115                 };
116                 parse_itest(s->code, &config, argc > 2 ? stderr : NULL);
117                 while (s) {
118                         struct section *t = s->next;
119                         code_free(s->code);
120                         free(s);
121                         s = t;
122                 }
123                 exit(0);
124         }
125
126 # indent: grammar
127
128 ~~~~~~
129
130 Program -> Statementlist ${ print_statement($1, 0); }$
131
132 OptNL -> NEWLINE
133         |
134
135 $*statement
136         Statementlist ->  Statements ${ $0 = $<1; }$
137
138         Statements -> Statements Statement ${
139                                 {
140                                         struct statement **s;
141                                         $0 = $<1;
142                                         s = &$0;
143                                         while (*s)
144                                                 s = &(*s)->next;
145                                         *s = $<2;
146                                 }
147                                 }$
148                         | Statement ${ $0 = $<1; }$
149                         | ERROR ${ printf("statement ERROR\n"); $0 = NULL; }$
150
151         Open -> {
152                 | NEWLINE {
153         Close -> }
154                 | NEWLINE }
155         Block -> Open Statementlist Close ${ $0 = $<2; }$
156                 | Open SimpleStatements } ${ $0 = $<2; }$
157                 | : Statementlist ${ $0 = $2; $2 = NULL; }$
158
159         SimpleStatements -> SimpleStatements ; SimpleStatement ${
160                         {
161                                 struct statement **s;
162                                 $0 = $<1;
163                                 s = &$0;
164                                 while (*s)
165                                         s = &(*s)->next;
166                                 *s = $<3;
167                         }
168                         }$
169                 | SimpleStatement ${ $0 = $<1; }$
170                 | SimpleStatements ; ${ $0 = $<1; }$
171
172         SimpleStatement -> Factor = Expression ${
173                         $0 = calloc(1, sizeof(struct statement));
174                         $0->expr = calloc(1, sizeof(struct expression));
175                         $0->expr->left = $<1;
176                         $0->expr->op = $2.txt;
177                         $0->expr->right = $<3;
178                         }$
179         Statement -> SimpleStatements NEWLINE ${
180                         $0 = $<1;
181                         }$
182                 | IfStatement ${ $0 = $<1; }$
183                 | Statement NEWLINE ${ $0 = $<1; }$
184
185         IfStatement -> if Expression Block OptNL ${
186                                 $0 = calloc(1, sizeof(struct statement));
187                                 $0->expr = $<2;
188                                 $0->thenpart = $<3;
189                                 }$
190                 | if Expression : SimpleStatements ${
191                                 $0 = calloc(1, sizeof(struct statement));
192                                 $0->expr = $<2;
193                                 $0->thenpart = $<4;
194                                 }$
195                 | if Expression Block OptNL else Block ${
196                                 $0 = calloc(1, sizeof(struct statement));
197                                 $0->expr = $<2;
198                                 $0->thenpart = $<3;
199                                 $0->elsepart = $<6;
200                                 }$
201                 | if Expression Block OptNL else : SimpleStatements ${
202                                 $0 = calloc(1, sizeof(struct statement));
203                                 $0->expr = $<2;
204                                 $0->thenpart = $<3;
205                                 $0->elsepart = $<7;
206                                 }$
207                 | if Expression Block OptNL else IfStatement ${
208                                 $0 = calloc(1, sizeof(struct statement));
209                                 $0->expr = $<2;
210                                 $0->thenpart = $<3;
211                                 $0->elsepart = $<6;
212                                 }$
213
214 $*expression
215         Expression -> Expression + Term ${
216                                 $0 = calloc(1, sizeof(struct expression));
217                                 $0->op = $2.txt;
218                                 $0->left = $<1;
219                                 $0->right = $<3;
220                         }$
221                     | Expression - Term ${
222                                 $0 = calloc(1, sizeof(struct expression));
223                                 $0->op = $2.txt;
224                                 $0->left = $<1;
225                                 $0->right = $<3;
226                         }$
227                     | Term ${ $0 = $1; $1 = NULL; }$
228         Term -> Term * Factor ${
229                                 $0 = calloc(1, sizeof(struct expression));
230                                 $0->op = $2.txt;
231                                 $0->left = $<1;
232                                 $0->right = $<3;
233                         }$
234               | Term / Factor ${
235                                 $0 = calloc(1, sizeof(struct expression));
236                                 $0->op = $2.txt;
237                                 $0->left = $<1;
238                                 $0->right = $<3;
239                         }$
240               | Factor ${ $0 = $1; $1 = NULL; }$
241         Factor -> IDENTIFIER ${
242                                 $0 = calloc(1, sizeof(struct expression));
243                                 $0->op = $1.txt;
244                         }$
245 ~~~~~~
246
247 # File: itest.code
248
249         # test code
250         ~~~~~~
251         hello = yes; mister = no;
252         there = x;
253         all = y;
254         if cond + cond2 :
255                 hello = x;
256                 hello2 = x;
257
258                 sum = val +
259                  val;
260
261                 if condX:
262                  foo = x *
263                     x +
264                     y
265                     / two;
266          else if cond2:
267                 there1 =x
268                 there1a=x
269         there2=x
270         there3=x;
271         all = y;
272         if true {yes=x;} else : no=x
273         if true: yes = no; no = yes;
274
275         if false {
276                 print = OK
277         } else {
278                 print = not_OK
279         }
280
281         if a:
282                 if b:
283                         c= d
284         x = y
285