Mark local parsing functions 'static'.
[smatch.git] / parse.c
blobeaee642c2f91397871da594c37199437aa9f0367
1 /*
2 * Stupid C parser, version 1e-6.
4 * Let's see how hard this is to do.
5 */
6 #include <stdarg.h>
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <string.h>
10 #include <ctype.h>
11 #include <unistd.h>
12 #include <fcntl.h>
14 #include "token.h"
15 #include "parse.h"
17 void show_expression(struct expression *expr)
19 if (!expr)
20 return;
22 switch (expr->type) {
23 case EXPR_BINOP:
24 printf("< ");
25 show_expression(expr->left);
26 printf(" %s ", show_special(expr->op));
27 show_expression(expr->right);
28 printf(" >");
29 break;
30 case EXPR_PREOP:
31 printf("( ");
32 printf(" %s ", show_special(expr->op));
33 show_expression(expr->unop);
34 printf(" )");
35 break;
36 case EXPR_POSTOP:
37 printf("( ");
38 show_expression(expr->unop);
39 printf(" %s ", show_special(expr->op));
40 printf(" )");
41 break;
42 case EXPR_PRIMARY:
43 printf("%s", show_token(expr->token));
44 break;
45 case EXPR_DEREF:
46 printf("< ");
47 show_expression(expr->deref);
48 printf("%s", show_special(expr->op));
49 printf("%s", show_token(expr->member));
50 printf(" >");
51 break;
52 default:
53 printf("WTF");
57 static struct expression *alloc_expression(struct token *token, int type)
59 struct expression *expr = malloc(sizeof(struct expression));
61 if (!expr)
62 die("Unable to allocate expression");
63 memset(expr, 0, sizeof(*expr));
64 expr->type = type;
65 expr->token = token;
66 return expr;
69 static struct token *expect(struct token *token, int op)
71 if (!token ||
72 token->value.type != TOKEN_SPECIAL ||
73 token->value.special != op) {
74 warn(token, "Expected %s", show_special(op));
75 return token;
77 return token->next;
80 static struct token *comma_expression(struct token *, struct expression **);
82 static struct token *primary_expression(struct token *token, struct expression **tree)
84 struct expression *expr = NULL;
86 switch (token->value.type) {
87 case TOKEN_IDENT:
88 case TOKEN_INTEGER:
89 case TOKEN_FP:
90 case TOKEN_STRING:
91 expr = alloc_expression(token, EXPR_PRIMARY);
92 token = token->next;
93 break;
95 case TOKEN_SPECIAL:
96 if (token->value.special == '(') {
97 expr = alloc_expression(token, EXPR_PREOP);
98 expr->op = '(';
99 token = parse_expression(token->next, &expr->unop);
100 token = expect(token, ')');
101 break;
103 /* Fallthrough */
104 default:
105 warn(token, "Expected primary expression");
107 *tree = expr;
108 return token;
111 static struct token *postfix_expression(struct token *token, struct expression **tree)
113 struct expression *expr = NULL;
115 token = primary_expression(token, &expr);
116 while (expr && token && token->value.type == TOKEN_SPECIAL) {
117 switch (token->value.special) {
118 case '[': { /* Array dereference */
119 struct expression *array_expr = alloc_expression(token, EXPR_BINOP);
120 array_expr->op = '[';
121 array_expr->left = expr;
122 token = parse_expression(token->next, &array_expr->right);
123 token = expect(token, ']');
124 expr = array_expr;
125 continue;
127 case SPECIAL_INCREMENT: /* Post-increment */
128 case SPECIAL_DECREMENT: { /* Post-decrement */
129 struct expression *post = alloc_expression(token, EXPR_POSTOP);
130 post->op = token->value.special;
131 post->unop = expr;
132 expr = post;
133 token = token->next;
134 continue;
136 case '.': /* Structure member dereference */
137 case SPECIAL_DEREFERENCE: { /* Structure pointer member dereference */
138 struct expression *deref = alloc_expression(token, EXPR_DEREF);
139 deref->op = token->value.special;
140 deref->deref = expr;
141 token = token->next;
142 if (!token || token->value.type != TOKEN_IDENT) {
143 warn(token, "Expected member name");
144 break;
146 deref->member = token;
147 token = token->next;
148 expr = deref;
149 continue;
152 case '(': { /* Function call */
153 struct expression *call = alloc_expression(token, EXPR_BINOP);
154 call->op = '(';
155 call->left = expr;
156 token = comma_expression(token->next, &call->right);
157 token = expect(token, ')');
158 expr = call;
159 continue;
162 default:
163 break;
165 break;
167 *tree = expr;
168 return token;
171 static struct token *unary_expression(struct token *token, struct expression **tree)
173 return postfix_expression(token, tree);
176 static struct token *cast_expression(struct token *token, struct expression **tree)
178 return unary_expression(token, tree);
181 /* Generic left-to-right binop parsing */
182 static struct token *lr_binop_expression(struct token *token, struct expression **tree,
183 struct token *(*inner)(struct token *, struct expression **), ...)
185 struct expression *left = NULL;
186 struct token * next = inner(token, &left);
188 if (left) {
189 while (next && next->value.type == TOKEN_SPECIAL) {
190 struct expression *top, *right = NULL;
191 int op = next->value.special;
192 va_list args;
194 va_start(args, inner);
195 for (;;) {
196 int nextop = va_arg(args, int);
197 if (!nextop)
198 goto out;
199 if (op == nextop)
200 break;
202 va_end(args);
203 top = alloc_expression(next, EXPR_BINOP);
204 next = inner(next->next, &right);
205 if (!right) {
206 warn(token, "Syntax error");
207 break;
209 top->op = op;
210 top->left = left;
211 top->right = right;
212 left = top;
215 out:
216 *tree = left;
217 return next;
220 static struct token *multiplicative_expression(struct token *token, struct expression **tree)
222 return lr_binop_expression(token, tree, cast_expression, '*', '/', '%', 0);
225 static struct token *additive_expression(struct token *token, struct expression **tree)
227 return lr_binop_expression(token, tree, multiplicative_expression, '+', '-', 0);
230 static struct token *shift_expression(struct token *token, struct expression **tree)
232 return lr_binop_expression(token, tree, additive_expression, SPECIAL_LEFTSHIFT, SPECIAL_RIGHTSHIFT, 0);
235 static struct token *relational_expression(struct token *token, struct expression **tree)
237 return lr_binop_expression(token, tree, shift_expression, '<', '>', SPECIAL_LTE, SPECIAL_GTE, 0);
240 static struct token *equality_expression(struct token *token, struct expression **tree)
242 return lr_binop_expression(token, tree, relational_expression, SPECIAL_EQUAL, SPECIAL_NOTEQUAL, 0);
245 static struct token *bitwise_and_expression(struct token *token, struct expression **tree)
247 return lr_binop_expression(token, tree, equality_expression, '&', 0);
250 static struct token *bitwise_xor_expression(struct token *token, struct expression **tree)
252 return lr_binop_expression(token, tree, bitwise_and_expression, '^', 0);
255 static struct token *bitwise_or_expression(struct token *token, struct expression **tree)
257 return lr_binop_expression(token, tree, bitwise_xor_expression, '|', 0);
260 static struct token *logical_and_expression(struct token *token, struct expression **tree)
262 return lr_binop_expression(token, tree, bitwise_or_expression, SPECIAL_LOGICAL_AND, 0);
265 static struct token *logical_or_expression(struct token *token, struct expression **tree)
267 return lr_binop_expression(token, tree, logical_and_expression, SPECIAL_LOGICAL_OR, 0);
270 struct token *comma_expression(struct token *token, struct expression **tree)
272 return lr_binop_expression(token, tree, logical_or_expression, ',', 0);
275 struct token *parse_expression(struct token *token, struct expression **tree)
277 return comma_expression(token,tree);