2 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
3 * See the copyright notice in the ACK home directory, in the file "Copyright".
5 /* $Id: expression.g,v 1.14 1994/06/27 07:59:47 ceriel Exp $ */
6 /* EXPRESSION SYNTAX PARSER */
12 #include <flt_arith.h>
22 extern struct expr *intexpr();
23 int InSizeof = 0; /* inside a sizeof- expression */
24 int ResultKnown = 0; /* result of the expression is already known */
26 /* Since the grammar in the standard is not LL(n), it is modified so that
27 * it accepts basically the same grammar. This means that there is no 1-1
28 * mapping from the grammar in the standard to the grammar given here.
34 primary(register struct expr **expp;) :
42 '(' expression(expp) ')'
43 { (*expp)->ex_flags |= EX_PARENS; }
47 /* Character string literals that are adjacent tokens
48 * are concatenated into a single character string
51 string(register struct expr **expp;)
52 { register int i, len;
64 { /* A pasted string keeps the type of the first
66 * The pasting of normal strings and wide
67 * character strings are stated as having an
68 * undefined behaviour.
70 if (dot.tk_fund != fund)
71 warning("illegal pasting of string literals");
72 str = Realloc(str, (unsigned) (--len + dot.tk_len));
73 for (i = 0; i < dot.tk_len; i++)
74 str[len++] = dot.tk_bts[i];
77 { string2expr(expp, str, len); }
81 postfix_expression(register struct expr **expp;)
89 '[' expression(&e1) ']'
90 { ch3bin(expp, '[', e1); e1 = 0; }
92 '(' parameter_list(&e1)? ')'
93 { ch3bin(expp, '(', e1); call_proto(expp); e1 = 0; }
95 [ '.' | ARROW ] { oper = DOT; }
96 identifier(&idf) { ch3sel(expp, oper, idf); }
99 PLUSPLUS { oper = POSTINCR; }
101 MINMIN { oper = POSTDECR; }
103 { ch3incr(expp, oper); }
107 parameter_list(struct expr **expp;)
108 {struct expr *e1 = 0;}
110 assignment_expression(expp)
111 {any2opnd(expp, PARCOMMA);}
114 assignment_expression(&e1)
115 {any2opnd(&e1, PARCOMMA);}
116 {ch3bin(expp, PARCOMMA, e1);}
120 %first first_of_type_specifier, type_specifier;
123 unary(register struct expr **expp;)
124 {struct type *tp; int oper;}
126 %if (first_of_type_specifier(AHEAD) && AHEAD != IDENTIFIER)
127 cast(&tp) unary(expp)
128 { ch3cast(expp, CAST, tp);
129 (*expp)->ex_flags |= EX_CAST;
130 if (int_size != pointer_size)
131 (*expp)->ex_flags &= ~EX_PTRDIFF;
134 postfix_expression(expp)
136 unop(&oper) unary(expp)
137 {ch3mon(oper, expp);}
142 /* When an identifier is used in a sizeof()-expression, we must stil not
144 * extern int i; .... sizeof(i) .... need not have a definition for i
146 size_of(register struct expr **expp;)
149 SIZEOF { InSizeof++; } /* handle (sizeof(sizeof(int))) too */
150 [%if (first_of_type_specifier(AHEAD) && AHEAD != IDENTIFIER)
153 *expp = intexpr(size_of_type(tp, "type"), UNSIGNED);
154 (*expp)->ex_flags |= EX_SIZEOF;
158 {ch3mon(SIZEOF, expp);}
164 /* The set of operators in C is stratified in 15 levels, with level
165 N being treated in RM 7.N (although this is not the standard
166 anymore). The standard describes this in phrase-structure-grammar,
167 which we are unable to parse. The description that follows comes
168 from the old C-compiler.
170 In principle each operator is assigned a rank, ranging
171 from 1 to 15. Such an expression can be parsed by a construct
173 binary_expression(int maxrank;)
176 binary_expression(maxrank - 1)
177 [%if (rank_of(DOT) <= maxrank)
179 binary_expression(rank_of(oper)-1)
182 except that some call of 'unary' is necessary, depending on the
185 This simple view is marred by three complications:
186 1. Level 15 (comma operator) is not allowed in many
187 contexts and is different.
188 2. Level 13 (conditional operator) is a ternary operator,
189 which does not fit this scheme at all.
190 3. Level 14 (assignment operators) group right-to-left, as
191 opposed to 2-12, which group left-to-right (or are
193 4. The operators in level 14 start with operators in levels
194 2-13 (RM 7.14: The two parts of a compound assignment
195 operator are separate tokens.) This causes LL1 problems.
196 This forces us to have four rules:
197 binary_expression for level 2-12
198 conditional_expression for level 13
199 assignment_expression for level 14 and
200 expression for the most general expression
203 binary_expression(int maxrank; struct expr **expp;)
204 {int oper, OldResultKnown; struct expr *e1;}
207 [%while (rank_of(DOT) <= maxrank )
208 /* '?', '=', and ',' are no binops
211 { OldResultKnown = ResultKnown;
212 if (oper == OR || oper == AND) {
213 if (is_cp_cst(*expp) || is_fp_cst(*expp)) {
214 if (is_zero_cst(*expp)) {
215 if (oper == AND) ResultKnown++;
216 } else if (oper == OR) ResultKnown++;
220 binary_expression(rank_of(oper)-1, &e1)
222 ch3bin(expp, oper, e1);
223 ResultKnown = OldResultKnown;
229 conditional_expression(struct expr **expp;)
230 {struct expr *e1 = 0, *e2 = 0; int OldResultKnown, ConstExpr=0;}
232 /* allow all binary operators */
233 binary_expression(rank_of('?') - 1, expp)
235 { OldResultKnown = ResultKnown;
236 if (is_cp_cst(*expp) || is_fp_cst(*expp)) {
238 if (is_zero_cst(*expp)) ResultKnown++;
244 if (OldResultKnown == ResultKnown) ResultKnown++;
245 else ResultKnown = OldResultKnown;
248 conditional_expression(&e2)
250 ResultKnown = OldResultKnown;
251 ch3bin(&e1, ':', e2);
252 opnd2test(expp, '?');
253 ch3bin(expp, '?', e1);
259 assignment_expression(struct expr **expp;)
264 conditional_expression(expp)
267 assignment_expression(&e1)
268 {ch3asgn(expp, oper, e1);}
270 empty /* LLgen artefact ??? */
275 expression(struct expr **expp;)
278 assignment_expression(expp)
280 assignment_expression(&e1)
282 ch3bin(expp, ',', e1);
288 ['*' | '&' | '-' | '+' | '!' | '~' | PLUSPLUS | MINMIN]
289 { if (DOT == '&') DOT = ADDRESSOF;
307 '<' | '>' | LESSEQ | GREATEREQ
315 multop | addop | shiftop
321 [ arithop | relop | eqop | AND | OR ]
325 asgnop(register int *oper;):
326 [ '=' | PLUSAB | MINAB | TIMESAB | DIVAB | MODAB
327 | LEFTAB | RIGHTAB | ANDAB | XORAB | ORAB ]
332 constant(struct expr **expp;) :
341 constant_expression (struct expr **expp;) :
342 conditional_expression(expp)
343 { chk_cst_expr(expp); }
346 identifier(struct idf **idfp;) :
350 { *idfp = dot.tk_idf; }