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 myLDLIBS:= libparser.o libscanner.o libmdcode.o -licuuc
10 LDLIBS := $(filter-out $(myLDLIBS),$(LDLIBS)) $(myLDLIBS)
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
19 doitest: itest itest.code
21 checkitest: itest itest.code
22 @grep -v '^#' itest.out > .tmp.out
23 @./itest itest.code | diff -u - .tmp.out || echo itest FAILED
25 ' itest.code > itest2.code
26 @./itest itest2.code| diff -u - .tmp.out || echo itest2 FAILED
32 ./parsergen -o itest --LALR indent_test.cgm
33 cc -o itest itest.c lib*.o -licuuc -lgmp
38 struct expression *left, *right;
41 struct statement *next;
42 struct expression *expr;
43 struct statement *thenpart;
44 struct statement *elsepart;
58 static void free_expression(struct expression *e)
62 free_expression(e->left);
63 free_expression(e->right);
67 static void free_statement(struct statement *s)
71 free_statement(s->next);
72 free_expression(s->expr);
73 free_statement(s->thenpart);
74 free_statement(s->elsepart);
78 static void print_expression(struct expression *e)
80 if (e->left && e->right) printf("(");
82 print_expression(e->left);
84 printf("%.*s", e->op.len, e->op.txt);
86 print_expression(e->right);
87 if (e->left && e->right) printf(")");
90 static void print_statement(struct statement *s, int depth)
95 printf("%*.s", depth, "");
96 print_expression(s->expr);
99 printf("%*.sif ", depth, "");
100 print_expression(s->expr);
102 print_statement(s->thenpart, depth+4);
104 printf("%*.selse:\n", depth, "");
105 print_statement(s->elsepart, depth+4);
108 print_statement(s->next, depth);
111 int main(int argc, char *argv[])
113 int fd = open(argv[1], O_RDONLY);
114 int len = lseek(fd, 0, 2);
115 char *file = mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0);
116 struct section *s = code_extract(file, file+len, NULL);
117 struct token_config config = {
118 .ignored = (1 << TK_line_comment)
119 | (1 << TK_block_comment),
120 .number_chars = ".,_+-",
124 parse_itest(s->code, &config, argc > 2 ? stderr : NULL);
126 struct section *t = s->next;
138 Program -> Statementlist ${ print_statement($1, 0); }$
143 Statementlist -> Statements ${ $0 = $<1; }$
144 | Newlines Statements ${ $0 = $<2; }$
146 Statements -> Statements Statement ${
148 struct statement **s;
156 | Statement ${ $0 = $<1; }$
157 | ERROR ${ printf("statement ERROR\n"); $0 = NULL; }$
163 Block -> Open Statementlist Close ${ $0 = $<2; }$
164 | Open SimpleStatements } ${ $0 = $<2; }$
165 | : SimpleStatements ${ $0 = $<2; }$
166 | : StatementBlock ${ $0 = $<2; }$
167 StatementBlock -> Statementlist $$OUT ${ $0 = $<1; }$
169 SimpleStatements -> SimpleStatements ; SimpleStatement ${
171 struct statement **s;
179 | SimpleStatement ${ $0 = $<1; }$
180 | SimpleStatements ; ${ $0 = $<1; }$
182 SimpleStatement -> Factor = Expression ${
183 $0 = calloc(1, sizeof(struct statement));
184 $0->expr = calloc(1, sizeof(struct expression));
185 $0->expr->left = $<1;
186 $0->expr->op = $2.txt;
187 $0->expr->right = $<3;
189 SSline -> SimpleStatements NEWLINE ${ $0 = $<1; }$
190 Statement -> SSline ${ $0 = $<1; }$
191 | IfStatement $$NEWLINE ${ $0 = $<1; }$
192 | Statement NEWLINE ${ $0 = $<1; }$
196 IfHead -> if Expression Block ${
197 $0 = calloc(1, sizeof(struct statement));
201 | IfHead NEWLINE ${ $0 = $<1; }$
203 IfStatement -> IfHead $$else ${ $0 = $<1; }$
204 | IfHead else Block ${
208 | IfHead else IfStatement ${
214 Expression -> Expression + Term ${
215 $0 = calloc(1, sizeof(struct expression));
220 | Expression - Term ${
221 $0 = calloc(1, sizeof(struct expression));
226 | Term ${ $0 = $<1; }$
227 Term -> Term * Factor ${
228 $0 = calloc(1, sizeof(struct expression));
234 $0 = calloc(1, sizeof(struct expression));
239 | Factor ${ $0 = $<1; }$
240 Factor -> IDENTIFIER ${
241 $0 = calloc(1, sizeof(struct expression));
250 hello = yes; mister = no;
271 if true {yes=x;} else : no=x
272 if true: yes = no; no = yes;
273 if false: yes=ok; else: no=ok
296 (foo=((x*x)+(y/two)));