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.
7 itestCFLAGS := -Wall -g -fplan9-extensions
8 itestLDLIBS:= libparser.o libscanner.o libmdcode.o -licuuc
11 itest.c itest.h : indent_test.mdc parsergen
12 ./parsergen -o itest --LALR --tag indent indent_test.mdc
13 indent_test.mk itest.code: indent_test.mdc md2c
14 ./md2c indent_test.mdc
15 itest: itest.c | $(filter %.o,$(itestLDLIBS))
16 $(CC) $(itestCFLAGS) $^ $(itestLDLIBS) -o $@
18 doitest: itest itest.code
20 checkitest: itest itest.code
21 @grep -v '^#' itest.out > .tmp.out
22 @./itest itest.code | diff -u .tmp.out - || echo itest FAILED
24 ' itest.code > itest2.code
25 @./itest itest2.code| diff -u .tmp.out - || echo itest2 FAILED
33 struct expression *left, *right;
36 struct statement *next;
37 struct expression *expr;
38 struct statement *thenpart;
39 struct statement *elsepart;
53 static void free_expression(struct expression *e)
57 free_expression(e->left);
58 free_expression(e->right);
62 static void free_statement(struct statement *s)
66 free_statement(s->next);
67 free_expression(s->expr);
68 free_statement(s->thenpart);
69 free_statement(s->elsepart);
73 static void print_expression(struct expression *e)
75 if (e->left && e->right) printf("(");
77 print_expression(e->left);
79 printf("%.*s", e->op.len, e->op.txt);
81 print_expression(e->right);
82 if (e->left && e->right) printf(")");
85 static void print_statement(struct statement *s, int depth)
90 printf("%*.s", depth, "");
91 print_expression(s->expr);
94 printf("%*.sif ", depth, "");
95 print_expression(s->expr);
97 print_statement(s->thenpart, depth+4);
99 printf("%*.selse:\n", depth, "");
100 print_statement(s->elsepart, depth+4);
103 print_statement(s->next, depth);
106 int main(int argc, char *argv[])
108 int fd = open(argv[1], O_RDONLY);
109 int len = lseek(fd, 0, 2);
110 char *file = mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0);
111 struct section *s = code_extract(file, file+len, NULL);
112 struct token_config config = {
113 .number_chars = ".,_+-",
117 parse_itest(s->code, &config, argc > 2 ? stderr : NULL);
119 struct section *t = s->next;
131 $TERM if { } : * + - / ; =
133 Program -> OptNL Statementlist ${ print_statement($S, 0); }$
142 Statementlist -> Statementlist Statement ${
144 struct statement **s;
152 | Statement ${ $0 = $<1; }$
154 Block -> { IN OptNL Statementlist OUT OptNL } ${ $0 = $<Stat; }$
155 | { SimpleStatements } ${ $0 = $<S; }$
156 | { SimpleStatements ; } ${ $0 = $<S; }$
157 | : IN OptNL Statementlist OUT ${ $0 = $<Sl; }$
158 | : SimpleStatements EOL ${ $0 = $<Si; }$
159 | : SimpleStatements ; ${ $0 = $<Si; }$
161 SimpleStatements -> SimpleStatements ; SimpleStatement ${
163 struct statement **s;
171 | SimpleStatement ${ $0 = $<1; }$
173 SimpleStatement -> Factor = Expression ${
174 $0 = calloc(1, sizeof(struct statement));
175 $0->expr = calloc(1, sizeof(struct expression));
176 $0->expr->left = $<1;
177 $0->expr->op = $2.txt;
178 $0->expr->right = $<3;
180 Statement -> SimpleStatements Newlines ${ $0 = $<SS; }$
181 | SimpleStatements ; Newlines ${ $0 = $<SS; }$
182 | IfHead Newlines ${ $0 = $<If; }$
183 | IfHead Newlines IfSuffix ${
185 $0->next = $IS->next;
191 $0->next = $IS->next;
195 | ERROR Newlines ${ printf("statement ERROR\n"); $0 = NULL; }$
199 IfHead -> if Expression Block ${
200 $0 = calloc(1, sizeof(struct statement));
205 IfSuffix -> else Block Newlines ${ $0 = $<Bl; }$
206 | else IfHead Newlines ${ $0 = $<IH; }$
207 | else IfHead IfSuffix ${
210 $0->next = $IS->next;
213 | else IfHead Newlines IfSuffix ${
216 $0->next = $IS->next;
221 Expression -> Expression + Term ${
222 $0 = calloc(1, sizeof(struct expression));
227 | Expression - Term ${
228 $0 = calloc(1, sizeof(struct expression));
233 | Term ${ $0 = $<1; }$
234 Term -> Term * Factor ${
235 $0 = calloc(1, sizeof(struct expression));
241 $0 = calloc(1, sizeof(struct expression));
246 | Factor ${ $0 = $<1; }$
247 Factor -> IDENTIFIER ${
248 $0 = calloc(1, sizeof(struct expression));
257 hello = yes; mister = no;
293 if true {yes=x;} else : no=x
294 if true: yes = no; no = yes;
295 if false: yes=ok; else: no=ok
320 (foo=((x*x)+(y/two)));
330 (foo=((x*x)+(y/two)));