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 myCFLAGS := -Wall -g -fplan9-extensions
8 CFLAGS := $(filter-out $(myCFLAGS),$(CFLAGS)) $(myCFLAGS)
9 LDLIBS:= libparser.o libscanner.o libmdcode.o -licuuc
12 itest.c itest.h : indent_test.mdc parsergen libparser.o libscanner.o libmdcode.o
13 ./parsergen -o itest --LALR --tag indent indent_test.mdc
14 indent_test.mk: indent_test.mdc md2c
15 ./md2c indent_test.mdc
18 tests:: itest itest.code
23 ./parsergen -o itest --LALR indent_test.cgm
24 cc -o itest itest.c lib*.o -licuuc -lgmp
29 struct expression *left, *right;
32 struct statement *next;
33 struct expression *expr;
34 struct statement *thenpart;
35 struct statement *elsepart;
49 static void free_expression(struct expression *e)
53 free_expression(e->left);
54 free_expression(e->right);
58 static void free_statement(struct statement *s)
62 free_statement(s->next);
63 free_expression(s->expr);
64 free_statement(s->thenpart);
65 free_statement(s->elsepart);
69 static void print_expression(struct expression *e)
71 if (e->left && e->right) printf("(");
73 print_expression(e->left);
75 printf("%.*s", e->op.len, e->op.txt);
77 print_expression(e->right);
78 if (e->left && e->right) printf(")");
81 static void print_statement(struct statement *s, int depth)
86 printf("%*.s", depth, "");
87 print_expression(s->expr);
90 printf("%*.sif ", depth, "");
91 print_expression(s->expr);
93 print_statement(s->thenpart, depth+4);
95 printf("%*.selse:\n", depth, "");
96 print_statement(s->elsepart, depth+4);
99 print_statement(s->next, depth);
102 int main(int argc, char *argv[])
104 int fd = open(argv[1], O_RDONLY);
105 int len = lseek(fd, 0, 2);
106 char *file = mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0);
107 struct section *s = code_extract(file, file+len, NULL);
108 struct token_config config = {
109 .ignored = (1 << TK_line_comment)
110 | (1 << TK_block_comment),
111 .number_chars = ".,_+-",
115 parse_itest(s->code, &config, argc > 2 ? stderr : NULL);
117 struct section *t = s->next;
130 Program -> Statementlist ${ print_statement($1, 0); }$
136 Statementlist -> Statements ${ $0 = $<1; }$
138 Statements -> Statements Statement ${
140 struct statement **s;
148 | Statement ${ $0 = $<1; }$
149 | ERROR ${ printf("statement ERROR\n"); $0 = NULL; }$
155 Block -> Open Statementlist Close ${ $0 = $<2; }$
156 | Open SimpleStatements } ${ $0 = $<2; }$
157 | : Statementlist ${ $0 = $2; $2 = NULL; }$
159 SimpleStatements -> SimpleStatements ; SimpleStatement ${
161 struct statement **s;
169 | SimpleStatement ${ $0 = $<1; }$
170 | SimpleStatements ; ${ $0 = $<1; }$
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;
179 Statement -> SimpleStatements NEWLINE ${
182 | IfStatement ${ $0 = $<1; }$
183 | Statement NEWLINE ${ $0 = $<1; }$
185 IfStatement -> if Expression Block OptNL ${
186 $0 = calloc(1, sizeof(struct statement));
190 | if Expression : SimpleStatements ${
191 $0 = calloc(1, sizeof(struct statement));
195 | if Expression Block OptNL else Block ${
196 $0 = calloc(1, sizeof(struct statement));
201 | if Expression Block OptNL else : SimpleStatements ${
202 $0 = calloc(1, sizeof(struct statement));
207 | if Expression Block OptNL else IfStatement ${
208 $0 = calloc(1, sizeof(struct statement));
215 Expression -> Expression + Term ${
216 $0 = calloc(1, sizeof(struct expression));
221 | Expression - Term ${
222 $0 = calloc(1, sizeof(struct expression));
227 | Term ${ $0 = $1; $1 = NULL; }$
228 Term -> Term * Factor ${
229 $0 = calloc(1, sizeof(struct expression));
235 $0 = calloc(1, sizeof(struct expression));
240 | Factor ${ $0 = $1; $1 = NULL; }$
241 Factor -> IDENTIFIER ${
242 $0 = calloc(1, sizeof(struct expression));
251 hello = yes; mister = no;
272 if true {yes=x;} else : no=x
273 if true: yes = no; no = yes;