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
*array_expr
= alloc_expression(token
, EXPR_BINOP
);
105 array_expr
->op
= '[';
106 array_expr
->left
= expr
;
107 token
= parse_expression(token
->next
, &array_expr
->right
);
108 token
= expect(token
, ']', "at end of array dereference");
112 case SPECIAL_INCREMENT
: /* Post-increment */
113 case SPECIAL_DECREMENT
: { /* Post-decrement */
114 struct expression
*post
= alloc_expression(token
, EXPR_POSTOP
);
115 post
->op
= token
->special
;
121 case '.': /* Structure member dereference */
122 case SPECIAL_DEREFERENCE
: { /* Structure pointer member dereference */
123 struct expression
*deref
= alloc_expression(token
, EXPR_DEREF
);
124 deref
->op
= token
->special
;
127 if (token
->type
!= TOKEN_IDENT
) {
128 warn(token
, "Expected member name");
131 deref
->member
= token
;
137 case '(': { /* Function call */
138 struct expression
*call
= alloc_expression(token
, EXPR_BINOP
);
141 token
= comma_expression(token
->next
, &call
->right
);
142 token
= expect(token
, ')', "in function call");
156 static struct token
*cast_expression(struct token
*token
, struct expression
**tree
);
157 static struct token
*unary_expression(struct token
*token
, struct expression
**tree
)
159 if (token
->type
== TOKEN_IDENT
&&
160 (token
->ident
== &sizeof_ident
||
161 token
->ident
== &__alignof___ident
)) {
162 struct expression
*sizeof_ex
= alloc_expression(token
, EXPR_SIZEOF
);
164 tree
= &sizeof_ex
->unop
;
166 if (!match_op(token
, '(') || !lookup_type(token
->next
))
167 return unary_expression(token
, &sizeof_ex
->cast_expression
);
168 token
= typename(token
->next
, &sizeof_ex
->cast_type
);
169 return expect(token
, ')', "at end of sizeof type-name");
172 if (token
->type
== TOKEN_SPECIAL
) {
173 if (match_oplist(token
->special
,
174 SPECIAL_INCREMENT
, SPECIAL_DECREMENT
,
175 '&', '*', '+', '-', '~', '!', 0)) {
176 struct expression
*unary
= alloc_expression(token
, EXPR_PREOP
);
177 unary
->op
= token
->special
;
179 return cast_expression(token
->next
, &unary
->unop
);
183 return postfix_expression(token
, tree
);
187 * Ambiguity: a '(' can be either a cast-expression or
188 * a primary-expression depending on whether it is followed
191 static struct token
*cast_expression(struct token
*token
, struct expression
**tree
)
193 if (match_op(token
, '(')) {
194 struct token
*next
= token
->next
;
195 if (lookup_type(next
)) {
196 struct expression
*cast
= alloc_expression(next
, EXPR_CAST
);
198 token
= typename(next
, &cast
->cast_type
);
199 token
= expect(token
, ')', "at end of cast operator");
200 if (match_op(token
, '{'))
201 return initializer(token
, &cast
->cast_type
->ctype
);
202 token
= cast_expression(token
, &cast
->cast_expression
);
207 return unary_expression(token
, tree
);
210 /* Generic left-to-right binop parsing */
211 static struct token
*lr_binop_expression(struct token
*token
, struct expression
**tree
,
212 struct token
*(*inner
)(struct token
*, struct expression
**), ...)
214 struct expression
*left
= NULL
;
215 struct token
* next
= inner(token
, &left
);
218 while (next
->type
== TOKEN_SPECIAL
) {
219 struct expression
*top
, *right
= NULL
;
220 int op
= next
->special
;
223 va_start(args
, inner
);
225 int nextop
= va_arg(args
, int);
232 top
= alloc_expression(next
, EXPR_BINOP
);
233 next
= inner(next
->next
, &right
);
235 warn(next
, "No right hand side of '%s'-expression", show_special(op
));
249 static struct token
*multiplicative_expression(struct token
*token
, struct expression
**tree
)
251 return lr_binop_expression(token
, tree
, cast_expression
, '*', '/', '%', 0);
254 static struct token
*additive_expression(struct token
*token
, struct expression
**tree
)
256 return lr_binop_expression(token
, tree
, multiplicative_expression
, '+', '-', 0);
259 static struct token
*shift_expression(struct token
*token
, struct expression
**tree
)
261 return lr_binop_expression(token
, tree
, additive_expression
, SPECIAL_LEFTSHIFT
, SPECIAL_RIGHTSHIFT
, 0);
264 static struct token
*relational_expression(struct token
*token
, struct expression
**tree
)
266 return lr_binop_expression(token
, tree
, shift_expression
, '<', '>', SPECIAL_LTE
, SPECIAL_GTE
, 0);
269 static struct token
*equality_expression(struct token
*token
, struct expression
**tree
)
271 return lr_binop_expression(token
, tree
, relational_expression
, SPECIAL_EQUAL
, SPECIAL_NOTEQUAL
, 0);
274 static struct token
*bitwise_and_expression(struct token
*token
, struct expression
**tree
)
276 return lr_binop_expression(token
, tree
, equality_expression
, '&', 0);
279 static struct token
*bitwise_xor_expression(struct token
*token
, struct expression
**tree
)
281 return lr_binop_expression(token
, tree
, bitwise_and_expression
, '^', 0);
284 static struct token
*bitwise_or_expression(struct token
*token
, struct expression
**tree
)
286 return lr_binop_expression(token
, tree
, bitwise_xor_expression
, '|', 0);
289 static struct token
*logical_and_expression(struct token
*token
, struct expression
**tree
)
291 return lr_binop_expression(token
, tree
, bitwise_or_expression
, SPECIAL_LOGICAL_AND
, 0);
294 static struct token
*logical_or_expression(struct token
*token
, struct expression
**tree
)
296 return lr_binop_expression(token
, tree
, logical_and_expression
, SPECIAL_LOGICAL_OR
, 0);
299 struct token
*conditional_expression(struct token
*token
, struct expression
**tree
)
301 token
= logical_or_expression(token
, tree
);
302 if (match_op(token
, '?')) {
303 struct expression
*expr
= alloc_expression(token
, EXPR_CONDITIONAL
);
304 expr
->op
= token
->special
;
307 token
= parse_expression(token
->next
, &expr
->cond_true
);
308 token
= expect(token
, ':', "in conditional expression");
309 token
= conditional_expression(token
, &expr
->cond_false
);
314 struct token
*assignment_expression(struct token
*token
, struct expression
**tree
)
316 token
= conditional_expression(token
, tree
);
317 if (token
->type
== TOKEN_SPECIAL
) {
318 static const int assignments
[] = {
319 '=', SPECIAL_ADD_ASSIGN
, SPECIAL_MINUS_ASSIGN
,
320 SPECIAL_TIMES_ASSIGN
, SPECIAL_DIV_ASSIGN
,
321 SPECIAL_MOD_ASSIGN
, SPECIAL_SHL_ASSIGN
,
322 SPECIAL_SHR_ASSIGN
, SPECIAL_AND_ASSIGN
,
323 SPECIAL_OR_ASSIGN
, SPECIAL_XOR_ASSIGN
};
324 int i
, op
= token
->special
;
325 for (i
= 0; i
< sizeof(assignments
)/sizeof(int); i
++)
326 if (assignments
[i
] == op
) {
327 struct expression
* expr
= alloc_expression(token
, EXPR_BINOP
);
331 return assignment_expression(token
->next
, &expr
->right
);
337 static struct token
*comma_expression(struct token
*token
, struct expression
**tree
)
339 return lr_binop_expression(token
, tree
, assignment_expression
, ',', 0);
342 struct token
*parse_expression(struct token
*token
, struct expression
**tree
)
344 return comma_expression(token
,tree
);