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 3.12 1997/02/21 17:10:41 ceriel Exp $ */
6 /* EXPRESSION SYNTAX PARSER */
16 #include "noRoption.h"
18 extern char options[];
19 extern struct expr *intexpr();
23 primary(register struct expr **expp;) :
27 %illegal TYPE_IDENTIFIER
34 '(' expression(expp) ')'
35 {(*expp)->ex_flags |= EX_PARENS;}
38 secundary(register struct expr **expp;) :
49 index_pack(struct expr **expp;)
52 '[' expression(&e1) ']'
53 {ch7bin(expp, '[', e1);}
56 parameter_pack(struct expr **expp;)
57 {struct expr *e1 = 0;}
59 '(' parameter_list(&e1)? ')'
60 {ch7bin(expp, '(', e1);}
63 selection(struct expr **expp;)
64 {int oper; struct idf *idf;}
69 {ch7sel(expp, oper, idf);}
72 parameter_list(struct expr **expp;)
73 {struct expr *e1 = 0;}
75 assignment_expression(expp)
76 {any2opnd(expp, PARCOMMA);}
79 assignment_expression(&e1)
80 {any2opnd(&e1, PARCOMMA);}
81 {ch7bin(expp, PARCOMMA, e1);}
86 postfixed(struct expr **expp;)
92 {ch7incr(expp, oper);}
98 %first first_of_type_specifier, type_specifier;
100 unary(register struct expr **expp;)
101 {struct type *tp; int oper;}
103 %if (first_of_type_specifier(AHEAD) && AHEAD != IDENTIFIER)
104 cast(&tp) unary(expp)
105 { ch7cast(expp, CAST, tp);
106 (*expp)->ex_flags |= EX_CAST;
111 unop(&oper) unary(expp)
112 {ch7mon(oper, expp);}
117 size_of(register struct expr **expp;)
121 [%if (first_of_type_specifier(AHEAD) && AHEAD != IDENTIFIER)
124 *expp = intexpr(size_of_type(tp, "type"), INT);
125 (*expp)->ex_flags |= EX_SIZEOF;
129 {ch7mon(SIZEOF, expp);}
134 /* The set of operators in C is stratified in 15 levels, with level
135 N being treated in RM 7.N. In principle each operator is
136 assigned a rank, ranging from 1 to 15. Such an expression can
137 be parsed by a construct like:
138 binary_expression(int maxrank;)
141 binary_expression(maxrank - 1)
142 [%if (rank_of(DOT) <= maxrank)
144 binary_expression(rank_of(oper)-1)
147 except that some call of 'unary' is necessary, depending on the
150 This simple view is marred by three complications:
151 1. Level 15 (comma operator) is not allowed in many
152 contexts and is different.
153 2. Level 13 (conditional operator) is a ternary operator,
154 which does not fit this scheme at all.
155 3. Level 14 (assignment operators) group right-to-left, as
156 opposed to 2-12, which group left-to-right (or are
158 4. The operators in level 14 start with operators in levels
159 2-13 (RM 7.14: The two parts of a compound assignment
160 operator are separate tokens.) This causes LL1 problems.
161 This forces us to have four rules:
162 binary_expression for level 2-12
163 conditional_expression for level 13
164 assignment_expression for level 14 and
165 expression for the most general expression
168 binary_expression(int maxrank; struct expr **expp;)
169 {int oper; struct expr *e1;}
172 [%while (rank_of(DOT) <= maxrank && AHEAD != '=')
173 /* '?', '=', and ',' are no binops, and the test
174 for AHEAD != '=' keeps the other assignment
178 binary_expression(rank_of(oper)-1, &e1)
180 ch7bin(expp, oper, e1);
186 conditional_expression(struct expr **expp;)
187 /* There is some unfortunate disagreement about what is allowed
188 between the '?' and the ':' of a conditional_expression.
189 Although the Ritchie compiler does not even allow
190 conditional_expressions there, some other compilers (e.g., VAX)
191 accept a full assignment_expression there, and programs
192 (like, e.g., emacs) rely on it. So we have little choice.
194 {struct expr *e1 = 0, *e2 = 0;}
196 /* allow all binary operators */
197 binary_expression(rank_of('?') - 1, expp)
202 check_conditional(e1, '?', "between ? and :");
206 assignment_expression(&e2)
209 check_conditional(e2, '=', "after :");
211 ch7bin(&e1, ':', e2);
212 opnd2test(expp, '?');
213 ch7bin(expp, '?', e1);
219 assignment_expression(struct expr **expp;)
225 conditional_expression(expp)
226 [%prefer /* (rank_of(DOT) <= maxrank) for any asgnop */
228 assignment_expression(&e1)
229 {ch7asgn(expp, oper, e1);}
231 empty /* LLgen artefact ??? */
236 expression(struct expr **expp;)
239 assignment_expression(expp)
241 assignment_expression(&e1)
243 ch7bin(expp, ',', e1);
249 ['*' | '&' | '-' | '!' | '~' | PLUSPLUS | MINMIN]
254 PLUSPLUS {*oper = POSTINCR;}
256 MINMIN {*oper = POSTDECR;}
272 '<' | '>' | LESSEQ | GREATEREQ
280 multop | addop | shiftop
286 [ arithop | relop | eqop | AND | OR ]
290 asgnop(register int *oper;):
293 '+' '=' {*oper = PLUSAB;}
295 '-' '=' {*oper = MINAB;}
297 '*' '=' {*oper = TIMESAB;}
299 '/' '=' {*oper = DIVAB;}
301 '%' '=' {*oper = MODAB;}
303 LEFT '=' {*oper = LEFTAB;}
305 RIGHT '=' {*oper = RIGHTAB;}
307 '&' '=' {*oper = ANDAB;}
309 '^' '=' {*oper = XORAB;}
311 '|' '=' {*oper = ORAB;}
314 constant(struct expr **expp;) :
323 constant_expression (struct expr **expp;) :
324 assignment_expression(expp)
325 {chk_cst_expr(expp);}
328 identifier(struct idf **idfp;) :