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: 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
31 ./parsergen -o itest --LALR indent_test.cgm
32 cc -o itest itest.c lib*.o -licuuc -lgmp
37 struct expression *left, *right;
40 struct statement *next;
41 struct expression *expr;
42 struct statement *thenpart;
43 struct statement *elsepart;
57 static void free_expression(struct expression *e)
61 free_expression(e->left);
62 free_expression(e->right);
66 static void free_statement(struct statement *s)
70 free_statement(s->next);
71 free_expression(s->expr);
72 free_statement(s->thenpart);
73 free_statement(s->elsepart);
77 static void print_expression(struct expression *e)
79 if (e->left && e->right) printf("(");
81 print_expression(e->left);
83 printf("%.*s", e->op.len, e->op.txt);
85 print_expression(e->right);
86 if (e->left && e->right) printf(")");
89 static void print_statement(struct statement *s, int depth)
94 printf("%*.s", depth, "");
95 print_expression(s->expr);
98 printf("%*.sif ", depth, "");
99 print_expression(s->expr);
101 print_statement(s->thenpart, depth+4);
103 printf("%*.selse:\n", depth, "");
104 print_statement(s->elsepart, depth+4);
107 print_statement(s->next, depth);
110 int main(int argc, char *argv[])
112 int fd = open(argv[1], O_RDONLY);
113 int len = lseek(fd, 0, 2);
114 char *file = mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0);
115 struct section *s = code_extract(file, file+len, NULL);
116 struct token_config config = {
117 .number_chars = ".,_+-",
121 parse_itest(s->code, &config, argc > 2 ? stderr : NULL);
123 struct section *t = s->next;
135 $TERM if { } : * + - / ; =
137 Program -> Statementlist ${ print_statement($1, 0); }$
142 Statementlist -> Statements ${ $0 = $<S; }$
143 | Newlines Statements ${ $0 = $<S1; }$
145 Statements -> Statements Statement ${
147 struct statement **s;
155 | Statement ${ $0 = $<1; }$
156 | ERROR ${ printf("statement ERROR\n"); $0 = NULL; }$
162 Block -> Open Statementlist Close ${ $0 = $<S; }$
163 | Open SimpleStatements } ${ $0 = $<S; }$
164 | : SimpleStatements ${ $0 = $<SS; }$
165 | : StatementBlock ${ $0 = $<SB; }$
166 StatementBlock -> Statementlist $$OUT ${ $0 = $<Sl; }$
168 SimpleStatements -> SimpleStatements ; SimpleStatement ${
170 struct statement **s;
178 | SimpleStatement ${ $0 = $<1; }$
179 | SimpleStatements ; ${ $0 = $<1; }$
181 SimpleStatement -> Factor = Expression ${
182 $0 = calloc(1, sizeof(struct statement));
183 $0->expr = calloc(1, sizeof(struct expression));
184 $0->expr->left = $<1;
185 $0->expr->op = $2.txt;
186 $0->expr->right = $<3;
188 SSline -> SimpleStatements NEWLINE ${ $0 = $<1; }$
189 Statement -> SSline ${ $0 = $<1; }$
190 | IfStatement $$NEWLINE ${ $0 = $<1; }$
191 | Statement NEWLINE ${ $0 = $<1; }$
195 IfHead -> if Expression Block ${
196 $0 = calloc(1, sizeof(struct statement));
200 | IfHead NEWLINE ${ $0 = $<1; }$
202 IfStatement -> IfHead $$else ${ $0 = $<1; }$
203 | IfHead else Block ${
207 | IfHead else IfStatement ${
213 Expression -> Expression + Term ${
214 $0 = calloc(1, sizeof(struct expression));
219 | Expression - Term ${
220 $0 = calloc(1, sizeof(struct expression));
225 | Term ${ $0 = $<1; }$
226 Term -> Term * Factor ${
227 $0 = calloc(1, sizeof(struct expression));
233 $0 = calloc(1, sizeof(struct expression));
238 | Factor ${ $0 = $<1; }$
239 Factor -> IDENTIFIER ${
240 $0 = calloc(1, sizeof(struct expression));
249 hello = yes; mister = no;
270 if true {yes=x;} else : no=x
271 if true: yes = no; no = yes;
272 if false: yes=ok; else: no=ok
295 (foo=((x*x)+(y/two)));