4 * Copyright (C) 2003 Linus Torvalds, all rights reserved.
6 * This is the expression parsing part of parsing C.
21 #include "expression.h"
23 static int match_oplist(int op
, ...)
29 int nextop
= va_arg(args
, int);
37 static struct token
*comma_expression(struct token
*, struct expression
**);
39 struct token
*parens_expression(struct token
*token
, struct expression
**expr
, const char *where
)
41 token
= expect(token
, '(', where
);
42 if (match_op(token
, '{')) {
43 struct expression
*e
= alloc_expression(token
, EXPR_STATEMENT
);
44 struct statement
*stmt
= alloc_statement(token
, STMT_COMPOUND
);
48 token
= compound_statement(token
->next
, stmt
);
50 token
= expect(token
, '}', "at end of statement expression");
52 token
= parse_expression(token
, expr
);
53 return expect(token
, ')', where
);
56 struct token
*primary_expression(struct token
*token
, struct expression
**tree
)
58 struct expression
*expr
= NULL
;
60 switch (token
->type
) {
64 expr
= alloc_expression(token
, EXPR_CONSTANT
);
69 expr
= alloc_expression(token
, EXPR_SYMBOL
);
70 expr
->symbol
= lookup_symbol(token
->ident
, NS_SYMBOL
);
76 expr
= alloc_expression(token
, EXPR_CONSTANT
);
79 } while (token
->type
== TOKEN_STRING
);
83 if (token
->special
== '(') {
84 expr
= alloc_expression(token
, EXPR_PREOP
);
86 token
= parens_expression(token
, &expr
->unop
, "in expression");
96 static struct token
*postfix_expression(struct token
*token
, struct expression
**tree
)
98 struct expression
*expr
= NULL
;
100 token
= primary_expression(token
, &expr
);
101 while (expr
&& token
->type
== TOKEN_SPECIAL
) {
102 switch (token
->special
) {
103 case '[': { /* Array dereference */
104 struct expression
*deref
= alloc_expression(token
, EXPR_PREOP
);
105 struct expression
*add
= alloc_expression(token
, EXPR_BINOP
);
112 token
= parse_expression(token
->next
, &add
->right
);
113 token
= expect(token
, ']', "at end of array dereference");
117 case SPECIAL_INCREMENT
: /* Post-increment */
118 case SPECIAL_DECREMENT
: { /* Post-decrement */
119 struct expression
*post
= alloc_expression(token
, EXPR_POSTOP
);
120 post
->op
= token
->special
;
126 case '.': /* Structure member dereference */
127 case SPECIAL_DEREFERENCE
: { /* Structure pointer member dereference */
128 struct expression
*deref
= alloc_expression(token
, EXPR_DEREF
);
129 deref
->op
= token
->special
;
132 if (token
->type
!= TOKEN_IDENT
) {
133 warn(token
, "Expected member name");
136 deref
->member
= token
;
142 case '(': { /* Function call */
143 struct expression
*call
= alloc_expression(token
, EXPR_CALL
);
146 token
= comma_expression(token
->next
, &call
->right
);
147 token
= expect(token
, ')', "in function call");
161 static struct token
*cast_expression(struct token
*token
, struct expression
**tree
);
162 static struct token
*unary_expression(struct token
*token
, struct expression
**tree
)
164 if (token
->type
== TOKEN_IDENT
&&
165 (token
->ident
== &sizeof_ident
||
166 token
->ident
== &__alignof___ident
)) {
167 struct expression
*sizeof_ex
= alloc_expression(token
, EXPR_SIZEOF
);
169 tree
= &sizeof_ex
->unop
;
171 if (!match_op(token
, '(') || !lookup_type(token
->next
))
172 return unary_expression(token
, &sizeof_ex
->cast_expression
);
173 token
= typename(token
->next
, &sizeof_ex
->cast_type
);
174 return expect(token
, ')', "at end of sizeof type-name");
177 if (token
->type
== TOKEN_SPECIAL
) {
178 if (match_oplist(token
->special
,
179 SPECIAL_INCREMENT
, SPECIAL_DECREMENT
,
180 '&', '*', '+', '-', '~', '!', 0)) {
181 struct expression
*unary
= alloc_expression(token
, EXPR_PREOP
);
182 unary
->op
= token
->special
;
184 return cast_expression(token
->next
, &unary
->unop
);
188 return postfix_expression(token
, tree
);
192 * Ambiguity: a '(' can be either a cast-expression or
193 * a primary-expression depending on whether it is followed
196 static struct token
*cast_expression(struct token
*token
, struct expression
**tree
)
198 if (match_op(token
, '(')) {
199 struct token
*next
= token
->next
;
200 if (lookup_type(next
)) {
201 struct expression
*cast
= alloc_expression(next
, EXPR_CAST
);
203 token
= typename(next
, &cast
->cast_type
);
204 token
= expect(token
, ')', "at end of cast operator");
205 if (match_op(token
, '{'))
206 return initializer(token
, &cast
->cast_type
->ctype
);
207 token
= cast_expression(token
, &cast
->cast_expression
);
212 return unary_expression(token
, tree
);
215 /* Generic left-to-right binop parsing */
216 static struct token
*lr_binop_expression(struct token
*token
, struct expression
**tree
,
217 struct token
*(*inner
)(struct token
*, struct expression
**), ...)
219 struct expression
*left
= NULL
;
220 struct token
* next
= inner(token
, &left
);
223 while (next
->type
== TOKEN_SPECIAL
) {
224 struct expression
*top
, *right
= NULL
;
225 int op
= next
->special
;
228 va_start(args
, inner
);
230 int nextop
= va_arg(args
, int);
237 top
= alloc_expression(next
, EXPR_BINOP
);
238 next
= inner(next
->next
, &right
);
240 warn(next
, "No right hand side of '%s'-expression", show_special(op
));
254 static struct token
*multiplicative_expression(struct token
*token
, struct expression
**tree
)
256 return lr_binop_expression(token
, tree
, cast_expression
, '*', '/', '%', 0);
259 static struct token
*additive_expression(struct token
*token
, struct expression
**tree
)
261 return lr_binop_expression(token
, tree
, multiplicative_expression
, '+', '-', 0);
264 static struct token
*shift_expression(struct token
*token
, struct expression
**tree
)
266 return lr_binop_expression(token
, tree
, additive_expression
, SPECIAL_LEFTSHIFT
, SPECIAL_RIGHTSHIFT
, 0);
269 static struct token
*relational_expression(struct token
*token
, struct expression
**tree
)
271 return lr_binop_expression(token
, tree
, shift_expression
, '<', '>', SPECIAL_LTE
, SPECIAL_GTE
, 0);
274 static struct token
*equality_expression(struct token
*token
, struct expression
**tree
)
276 return lr_binop_expression(token
, tree
, relational_expression
, SPECIAL_EQUAL
, SPECIAL_NOTEQUAL
, 0);
279 static struct token
*bitwise_and_expression(struct token
*token
, struct expression
**tree
)
281 return lr_binop_expression(token
, tree
, equality_expression
, '&', 0);
284 static struct token
*bitwise_xor_expression(struct token
*token
, struct expression
**tree
)
286 return lr_binop_expression(token
, tree
, bitwise_and_expression
, '^', 0);
289 static struct token
*bitwise_or_expression(struct token
*token
, struct expression
**tree
)
291 return lr_binop_expression(token
, tree
, bitwise_xor_expression
, '|', 0);
294 static struct token
*logical_and_expression(struct token
*token
, struct expression
**tree
)
296 return lr_binop_expression(token
, tree
, bitwise_or_expression
, SPECIAL_LOGICAL_AND
, 0);
299 static struct token
*logical_or_expression(struct token
*token
, struct expression
**tree
)
301 return lr_binop_expression(token
, tree
, logical_and_expression
, SPECIAL_LOGICAL_OR
, 0);
304 struct token
*conditional_expression(struct token
*token
, struct expression
**tree
)
306 token
= logical_or_expression(token
, tree
);
307 if (match_op(token
, '?')) {
308 struct expression
*expr
= alloc_expression(token
, EXPR_CONDITIONAL
);
309 expr
->op
= token
->special
;
312 token
= parse_expression(token
->next
, &expr
->cond_true
);
313 token
= expect(token
, ':', "in conditional expression");
314 token
= conditional_expression(token
, &expr
->cond_false
);
319 struct token
*assignment_expression(struct token
*token
, struct expression
**tree
)
321 token
= conditional_expression(token
, tree
);
322 if (token
->type
== TOKEN_SPECIAL
) {
323 static const int assignments
[] = {
324 '=', SPECIAL_ADD_ASSIGN
, SPECIAL_MINUS_ASSIGN
,
325 SPECIAL_TIMES_ASSIGN
, SPECIAL_DIV_ASSIGN
,
326 SPECIAL_MOD_ASSIGN
, SPECIAL_SHL_ASSIGN
,
327 SPECIAL_SHR_ASSIGN
, SPECIAL_AND_ASSIGN
,
328 SPECIAL_OR_ASSIGN
, SPECIAL_XOR_ASSIGN
};
329 int i
, op
= token
->special
;
330 for (i
= 0; i
< sizeof(assignments
)/sizeof(int); i
++)
331 if (assignments
[i
] == op
) {
332 struct expression
* expr
= alloc_expression(token
, EXPR_BINOP
);
336 return assignment_expression(token
->next
, &expr
->right
);
342 static struct token
*comma_expression(struct token
*token
, struct expression
**tree
)
344 return lr_binop_expression(token
, tree
, assignment_expression
, ',', 0);
347 struct token
*parse_expression(struct token
*token
, struct expression
**tree
)
349 return comma_expression(token
,tree
);