Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20080622152459

Diff

Diff from 1.206 to:

Annotations

Annotate by Age | Author | Mixed | None
/fisheye/browse/pcc/pcc/cc/ccom/cgram.y

Annotated File View

ragge
1.206
1 /*      $Id: cgram.y,v 1.206 2008/06/22 15:25:00 ragge Exp $    */
ragge
1.75
2
3 /*
4  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 /*
31  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
32  *
33  * Redistribution and use in source and binary forms, with or without
34  * modification, are permitted provided that the following conditions
35  * are met:
36  *
37  * Redistributions of source code and documentation must retain the above
38  * copyright notice, this list of conditions and the following disclaimer.
39  * Redistributions in binary form must reproduce the above copyright
ragge
1.87
40  * notice, this list of conditions and the following disclaimer in the
ragge
1.75
41  * documentation and/or other materials provided with the distribution.
42  * All advertising materials mentioning features or use of this software
43  * must display the following acknowledgement:
44  *      This product includes software developed or owned by Caldera
45  *      International, Inc.
46  * Neither the name of Caldera International, Inc. nor the names of other
47  * contributors may be used to endorse or promote products derived from
48  * this software without specific prior written permission.
49  *
50  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
51  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
52  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
53  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
54  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
55  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
56  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
57  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
59  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
60  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
61  * POSSIBILITY OF SUCH DAMAGE.
62  */
ragge
1.88
63
ragge
1.1
64 /*
ragge
1.19
65  * Comments for this grammar file. Ragge 021123
66  *
67  * ANSI support required rewrite of the function header and declaration
ragge
1.75
68  * rules almost totally.
ragge
1.19
69  *
ragge
1.75
70  * The lex/yacc shared keywords are now split from the keywords used
71  * in the rest of the compiler, to simplify use of other frontends.
ragge
1.19
72  */
73
ragge
1.17
74 /*
ragge
1.86
75  * At last count, there were 3 shift/reduce and no reduce/reduce conflicts
76  * Two was funct_idn and the third was "dangling else".
ragge
1.17
77  */
78
79 /*
ragge
1.72
80  * Token used in C lex/yacc communications.
ragge
1.50
81  */
ragge
1.165
82 %token  C_WSTRING       /* a wide string constant */
ragge
1.71
83 %token  C_STRING        /* a string constant */
84 %token  C_ICON          /* an integer constant */
85 %token  C_FCON          /* a floating point constant */
86 %token  C_NAME          /* an identifier */
ragge
1.72
87 %token  C_TYPENAME      /* a typedef'd name */
ragge
1.71
88 %token  C_ANDAND        /* && */
89 %token  C_OROR          /* || */
90 %token  C_GOTO          /* unconditional goto */
91 %token  C_RETURN        /* return from function */
92 %token  C_TYPE          /* a type */
93 %token  C_CLASS         /* a storage class */
94 %token  C_ASOP          /* assignment ops */
95 %token  C_RELOP         /* <=, <, >=, > */
96 %token  C_EQUOP         /* ==, != */
97 %token  C_DIVOP         /* /, % */
98 %token  C_SHIFTOP       /* <<, >> */
99 %token  C_INCOP         /* ++, -- */
100 %token  C_UNOP          /* !, ~ */
101 %token  C_STROP         /* ., -> */
102 %token  C_STRUCT
103 %token  C_IF
104 %token  C_ELSE
105 %token  C_SWITCH
106 %token  C_BREAK
107 %token  C_CONTINUE
108 %token  C_WHILE 
109 %token  C_DO
110 %token  C_FOR
111 %token  C_DEFAULT
112 %token  C_CASE
113 %token  C_SIZEOF
114 %token  C_ENUM
115 %token  C_ELLIPSIS
116 %token  C_QUALIFIER
117 %token  C_FUNSPEC
118 %token  C_ASM
ragge
1.184
119 %token  NOMATCH
ragge
1.172
120
121 /*
ragge
1.19
122  * Precedence
123  */
ragge
1.71
124 %left ','
125 %right '=' C_ASOP
126 %right '?' ':'
ragge
1.70
127 %left C_OROR
128 %left C_ANDAND
ragge
1.71
129 %left '|'
130 %left '^'
131 %left '&'
ragge
1.70
132 %left C_EQUOP
133 %left C_RELOP
134 %left C_SHIFTOP
ragge
1.71
135 %left '+' '-'
136 %left '*' C_DIVOP
ragge
1.70
137 %right C_UNOP
138 %right C_INCOP C_SIZEOF
ragge
1.71
139 %left '[' '(' C_STROP
ragge
1.1
140 %{
141 # include "pass1.h"
ragge
1.72
142 # include <stdarg.h>
ragge
1.124
143 # include <string.h>
ragge
1.170
144 # include <stdlib.h>
ragge
1.136
145
ragge
1.137
146 static int fun_inline;  /* Reading an inline function */
147 int oldstyle;   /* Current function being defined */
148 int noretype;
ragge
1.167
149 static struct symtab *xnf;
ragge
1.187
150 extern int enummer, tvaloff;
ragge
1.191
151 extern struct rstack *rpole;
ragge
1.187
152 static int ctval;
ragge
1.137
153
154 static NODE *bdty(int op, ...);
155 static void fend(void);
156 static void fundef(NODE *tp, NODE *p);
157 static void olddecl(NODE *p);
ragge
1.163
158 static struct symtab *init_declarator(NODE *tn, NODE *p, int assign);
ragge
1.137
159 static void resetbc(int mask);
160 static void swend(void);
161 static void addcase(NODE *p);
162 static void adddef(void);
163 static void savebc(void);
stefan
1.177
164 static void swstart(int, TWORD);
165 static void genswitch(int, TWORD, struct swents **, int);
ragge
1.195
166 static NODE *structref(NODE *p, int f, char *name);
ragge
1.157
167 static char *mkpstr(char *str);
ragge
1.167
168 static struct symtab *clbrace(NODE *);
ragge
1.195
169 static NODE *cmop(NODE *l, NODE *r);
170 static NODE *xcmop(NODE *out, NODE *in, NODE *str);
171 static void mkxasm(char *str, NODE *p);
172 static NODE *xasmop(char *str, NODE *p);
173
ragge
1.137
174
175 /*
176  * State for saving current switch state (when nested switches).
177  */
178 struct savbc {
179         struct savbc *next;
180         int brklab;
181         int contlab;
182         int flostat;
183         int swx;
184 } *savbc, *savctx;
185
ragge
1.1
186 %}
187
ragge
1.136
188 %union {
189         int intval;
190         NODE *nodep;
191         struct symtab *symp;
192         struct rstack *rp;
193         char *strp;
194 }
195
ragge
1.1
196         /* define types */
197 %start ext_def_list
198
199 %type <intval> con_e ifelprefix ifprefix whprefix forprefix doprefix switchpart
ragge
1.184
200                 type_qualifier_list
ragge
1.39
201 %type <nodep> e .e term enum_dcl struct_dcl cast_type funct_idn declarator
ragge
1.19
202                 direct_declarator elist type_specifier merge_attribs
ragge
1.163
203                 parameter_declaration abstract_declarator initializer
ragge
1.164
204                 parameter_type_list parameter_list addrlbl
ragge
1.25
205                 declaration_specifiers pointer direct_abstract_declarator
ragge
1.68
206                 specifier_qualifier_list merge_specifiers nocon_e
ragge
1.89
207                 identifier_list arg_param_list arg_declaration arg_dcl_list
ragge
1.195
208                 designator_list designator xasm oplist oper cnstr
ragge
1.184
209 %type <strp>    string wstring C_STRING C_WSTRING
ragge
1.176
210 %type <rp>      str_head
211 %type <symp>    xnfdeclarator clbrace enum_head
ragge
1.1
212
ragge
1.168
213 %type <intval> C_CLASS C_STRUCT C_RELOP C_DIVOP C_SHIFTOP
ragge
1.105
214                 C_ANDAND C_OROR C_STROP C_INCOP C_UNOP C_ASOP C_EQUOP
ragge
1.172
215
ragge
1.168
216 %type <nodep>  C_TYPE C_QUALIFIER C_ICON C_FCON
217 %type <strp>    C_NAME C_TYPENAME
ragge
1.1
218
pj
1.135
219 %%
220
ragge
1.1
221 ext_def_list:      ext_def_list external_def
ragge
1.4
222                 | { ftnend(); }
ragge
1.1
223                 ;
ragge
1.4
224
ragge
1.33
225 external_def:      function_definition { blevel = 0; }
ragge
1.162
226                 |  declaration  { blevel = 0; symclear(0); }
ragge
1.127
227                 |  asmstatement ';'
ragge
1.71
228                 |  ';'
ragge
1.33
229                 |  error { blevel = 0; }
ragge
1.1
230                 ;
ragge
1.4
231
ragge
1.19
232 function_definition:
ragge
1.29
233         /* Ansi (or K&R header without parameter types) */
ragge
1.19
234                    declaration_specifiers declarator {
ragge
1.20
235                         fundef($1, $2);
ragge
1.29
236                 } compoundstmt { fend(); }
237         /* Same as above but without declaring function type */
ragge
1.131
238                 |  declarator {
239                         noretype = 1;
240                         fundef(mkty(INT, 0, MKSUE(INT)), $1);
241                 } compoundstmt { fend(); noretype = 0; }
ragge
1.29
242         /* K&R function without type declaration */
ragge
1.92
243                 |  declarator {
ragge
1.131
244                         noretype = 1;
ragge
1.29
245                         if (oldstyle == 0)
246                                 uerror("bad declaration in ansi function");
ragge
1.81
247                         fundef(mkty(INT, 0, MKSUE(INT)), $1);
ragge
1.131
248                 } arg_dcl_list compoundstmt { fend(); noretype = 0; }
ragge
1.29
249         /* K&R function with type declaration */
ragge
1.92
250                 |  declaration_specifiers declarator {
ragge
1.29
251                         if (oldstyle == 0)
252                                 uerror("bad declaration in ansi function");
253                         fundef($1, $2);
ragge
1.112
254                 } arg_dcl_list compoundstmt { fend(); }
ragge
1.1
255                 ;
256
ragge
1.19
257 /*
258  * Returns a node pointer or NULL, if no types at all given.
259  * Type trees are checked for correctness and merged into one
260  * type node in typenode().
261  */
262 declaration_specifiers:
ragge
1.162
263                    merge_attribs { $$ = typenode($1); }
ragge
1.19
264                 ;
265
ragge
1.70
266 merge_attribs:     C_CLASS { $$ = block(CLASS, NIL, NIL, $1, 0, 0); }
267                 |  C_CLASS merge_attribs { $$ = block(CLASS, $2, NIL, $1,0,0);}
ragge
1.19
268                 |  type_specifier { $$ = $1; }
ragge
1.71
269                 |  type_specifier merge_attribs { $1->n_left = $2; $$ = $1; }
ragge
1.70
270                 |  C_QUALIFIER { $$ = $1; }
ragge
1.71
271                 |  C_QUALIFIER merge_attribs { $1->n_left = $2; $$ = $1; }
ragge
1.50
272                 |  function_specifiers { $$ = NIL; }
273                 |  function_specifiers merge_attribs { $$ = $2; }
274                 ;
275
276 function_specifiers:
ragge
1.70
277                    C_FUNSPEC {
ragge
1.50
278                         if (fun_inline)
279                                 uerror("too many inline");
280                         fun_inline = 1;
281                 }
ragge
1.1
282                 ;
ragge
1.19
283
ragge
1.70
284 type_specifier:    C_TYPE { $$ = $1; }
ragge
1.72
285                 |  C_TYPENAME { 
286                         struct symtab *sp = lookup($1, 0);
ragge
1.84
287                         $$ = mkty(sp->stype, sp->sdf, sp->ssue);
ragge
1.72
288                         $$->n_sp = sp;
289                 }
ragge
1.19
290                 |  struct_dcl { $$ = $1; }
291                 |  enum_dcl { $$ = $1; }
292                 ;
293
294 /*
ragge
1.23
295  * Adds a pointer list to front of the declarators.
ragge
1.121
296  * Note the UMUL right node pointer usage.
ragge
1.19
297  */
298 declarator:        pointer direct_declarator {
ragge
1.71
299                         $$ = $1; $1->n_right->n_left = $2;
ragge
1.10
300                 }
ragge
1.23
301                 |  direct_declarator { $$ = $1; }
ragge
1.1
302                 ;
303
ragge
1.19
304 /*
ragge
1.121
305  * Return an UMUL node type linked list of indirections.
ragge
1.19
306  */
ragge
1.121
307 pointer:           '*' { $$ = bdty(UMUL, NIL); $$->n_right = $$; }
ragge
1.71
308                 |  '*' type_qualifier_list {
ragge
1.121
309                         $$ = bdty(UMUL, NIL);
ragge
1.112
310                         $$->n_qual = $2;
311                         $$->n_right = $$;
ragge
1.23
312                 }
ragge
1.71
313                 |  '*' pointer {
ragge
1.121
314                         $$ = bdty(UMUL, $2);
ragge
1.71
315                         $$->n_right = $2->n_right;
ragge
1.23
316                 }
ragge
1.71
317                 |  '*' type_qualifier_list pointer {
ragge
1.121
318                         $$ = bdty(UMUL, $3);
ragge
1.112
319                         $$->n_qual = $2;
ragge
1.71
320                         $$->n_right = $3->n_right;
ragge
1.23
321                 }
ragge
1.19
322                 ;
323
324 type_qualifier_list:
ragge
1.112
325                    C_QUALIFIER { $$ = $1->n_type; nfree($1); }
326                 |  type_qualifier_list C_QUALIFIER {
327                         $$ = $1 | $2->n_type; nfree($2);
328                 }
ragge
1.19
329                 ;
330
331 /*
332  * Sets up a function declarator. The call node will have its parameters
333  * connected to its right node pointer.
334  */
ragge
1.72
335 direct_declarator: C_NAME { $$ = bdty(NAME, $1); }
ragge
1.71
336                 |  '(' declarator ')' { $$ = $2; }
337                 |  direct_declarator '[' nocon_e ']' { 
ragge
1.193
338                         $3 = optim($3);
339                         if (blevel == 0 && !nncon($3))
340                                 uerror("array size not constant");
stefan
1.183
341                         if (!ISINTEGER($3->n_type))
342                                 werror("array size is not an integer");
343                         else if ($3->n_op == ICON && $3->n_lval < 0) {
344                                 uerror("array size must be non-negative");
345                                 $3->n_lval = 1;
346                         }
ragge
1.81
347                         $$ = block(LB, $1, $3, INT, 0, MKSUE(INT));
ragge
1.19
348                 }
ragge
1.71
349                 |  direct_declarator '[' ']' { $$ = bdty(LB, $1, 0); }
ragge
1.187
350                 |  direct_declarator '(' fundcl parameter_type_list ')' {
351                         if (blevel-- > 1)
352                                 symclear(blevel);
353                         $$ = bdty(CALL, $1, $4);
354                 }
355                 |  direct_declarator '(' fundcl identifier_list ')' { 
356                         if (blevel-- > 1)
357                                 symclear(blevel);
358                         $$ = bdty(CALL, $1, $4);
ragge
1.89
359                         if (blevel != 0)
ragge
1.29
360                                 uerror("function declaration in bad context");
361                         oldstyle = 1;
362                 }
ragge
1.187
363                 |  direct_declarator '(' ')' {
364                         ctval = tvaloff;
365                         $$ = bdty(UCALL, $1);
366                 }
367                 ;
368
ragge
1.198
369 fundcl:            { if (++blevel == 1) argoff = ARGINIT; ctval = tvaloff; }
ragge
1.19
370                 ;
371
ragge
1.187
372 identifier_list:   C_NAME {
373                         $$ = mkty(FARG, NULL, MKSUE(INT));
374                         $$->n_sp = lookup($1, 0);
375                         defid($$, PARAM);
376                 }
ragge
1.89
377                 |  identifier_list ',' C_NAME { 
ragge
1.187
378                         $$ = mkty(FARG, NULL, MKSUE(INT));
379                         $$->n_sp = lookup($3, 0);
380                         defid($$, PARAM);
ragge
1.91
381                         $$ = block(CM, $1, $$, 0, 0, 0);
ragge
1.89
382                 }
ragge
1.19
383                 ;
384
385 /*
386  * Returns as parameter_list, but can add an additional ELLIPSIS node.
387  */
388 parameter_type_list:
ragge
1.55
389                    parameter_list { $$ = $1; }
ragge
1.71
390                 |  parameter_list ',' C_ELLIPSIS {
ragge
1.55
391                         $$ = block(CM, $1, block(ELLIPSIS, NIL, NIL, 0, 0, 0),
392                             0, 0, 0);
ragge
1.19
393                 }
394                 ;
395
396 /*
ragge
1.55
397  * Returns a linked lists of nodes of op CM with parameters on
398  * its right and additional CM nodes of its left pointer.
399  * No CM nodes if only one parameter.
ragge
1.19
400  */
ragge
1.162
401 parameter_list:    parameter_declaration { $$ = $1; }
ragge
1.71
402                 |  parameter_list ',' parameter_declaration {
403                         $$ = block(CM, $1, $3, 0, 0, 0);
ragge
1.19
404                 }
405                 ;
406
407 /*
408  * Returns a node pointer to the declaration.
409  */
410 parameter_declaration:
411                    declaration_specifiers declarator {
ragge
1.187
412                         if ($1->n_lval == AUTO || $1->n_lval == TYPEDEF ||
413                             $1->n_lval == EXTERN || $1->n_lval == STATIC)
414                                 uerror("illegal parameter class");
ragge
1.88
415                         $$ = tymerge($1, $2);
ragge
1.200
416                         if (blevel == 1) {
417                                 $$->n_sp = lookup((char *)$$->n_sp, 0);/* XXX */
418                                 if (ISFTN($$->n_type))
419                                         $$->n_type = INCREF($$->n_type);
420                                 defid($$, PARAM);
421                         }
ragge
1.104
422                         nfree($1);
ragge
1.200
423                 
ragge
1.19
424                 }
ragge
1.21
425                 |  declaration_specifiers abstract_declarator { 
ragge
1.88
426                         $$ = tymerge($1, $2);
ragge
1.104
427                         nfree($1);
ragge
1.21
428                 }
429                 |  declaration_specifiers {
ragge
1.88
430                         $$ = tymerge($1, bdty(NAME, NULL));
ragge
1.104
431                         nfree($1);
ragge
1.21
432                 }
ragge
1.19
433                 ;
434
435 abstract_declarator:
ragge
1.162
436                    pointer { $$ = $1; $1->n_right->n_left = bdty(NAME, NULL); }
ragge
1.25
437                 |  direct_abstract_declarator { $$ = $1; }
ragge
1.40
438                 |  pointer direct_abstract_declarator { 
ragge
1.71
439                         $$ = $1; $1->n_right->n_left = $2;
ragge
1.40
440                 }
ragge
1.19
441                 ;
442
443 direct_abstract_declarator:
ragge
1.71
444                    '(' abstract_declarator ')' { $$ = $2; }
ragge
1.72
445                 |  '[' ']' { $$ = bdty(LB, bdty(NAME, NULL), 0); }
446                 |  '[' con_e ']' { $$ = bdty(LB, bdty(NAME, NULL), $2); }
ragge
1.71
447                 |  direct_abstract_declarator '[' ']' { $$ = bdty(LB, $1, 0); }
448                 |  direct_abstract_declarator '[' con_e ']' {
ragge
1.56
449                         $$ = bdty(LB, $1, $3);
450                 }
ragge
1.122
451                 |  '(' ')' { $$ = bdty(UCALL, bdty(NAME, NULL)); }
stefan
1.186
452                 |  '(' parameter_type_list ')' {
453                         $$ = bdty(CALL, bdty(NAME, NULL), $2);
ragge
1.56
454                 }
ragge
1.71
455                 |  direct_abstract_declarator '(' ')' {
ragge
1.122
456                         $$ = bdty(UCALL, $1);
ragge
1.56
457                 }
stefan
1.186
458                 |  direct_abstract_declarator '(' parameter_type_list ')' {
459                         $$ = bdty(CALL, $1, $3);
ragge
1.25
460                 }
ragge
1.19
461                 ;
462
ragge
1.29
463 /*
464  * K&R arg declaration, between ) and {
465  */
466 arg_dcl_list:      arg_declaration
ragge
1.92
467                 |  arg_dcl_list arg_declaration
ragge
1.29
468                 ;
469
470
ragge
1.89
471 arg_declaration:   declaration_specifiers arg_param_list ';' {
ragge
1.104
472                         nfree($1);
ragge
1.89
473                 }
ragge
1.29
474                 ;
475
ragge
1.92
476 arg_param_list:    declarator { olddecl(tymerge($<nodep>0, $1)); }
477                 |  arg_param_list ',' declarator {
478                         olddecl(tymerge($<nodep>0, $3));
ragge
1.29
479                 }
480                 ;
ragge
1.19
481
482 /*
ragge
1.30
483  * Declarations in beginning of blocks.
484  */
ragge
1.182
485 block_item_list:   block_item
486                 |  block_item_list block_item
487                 ;
488
489 block_item:        declaration
490                 |  statement
ragge
1.30
491                 ;
492
493 /*
ragge
1.19
494  * Here starts the old YACC code.
495  */
496
ragge
1.30
497 /*
ragge
1.29
498  * Variables are declared in init_declarator.
ragge
1.19
499  */
ragge
1.104
500 declaration:       declaration_specifiers ';' { nfree($1); goto inl; }
ragge
1.71
501                 |  declaration_specifiers init_declarator_list ';' {
ragge
1.104
502                         nfree($1);
ragge
1.50
503                         inl:
504                         fun_inline = 0;
ragge
1.19
505                 }
ragge
1.1
506                 ;
ragge
1.4
507
ragge
1.19
508 /*
509  * Normal declaration of variables. curtype contains the current type node.
510  * Returns nothing, variables are declared in init_declarator.
511  */
512 init_declarator_list:
513                    init_declarator
ragge
1.71
514                 |  init_declarator_list ',' { $<nodep>$ = $<nodep>0; } init_declarator
ragge
1.1
515                 ;
ragge
1.4
516
ragge
1.176
517 enum_dcl:          enum_head '{' moe_list optcomma '}' { $$ = enumdcl($1); }
518                 |  C_ENUM C_NAME {  $$ = enumref($2); }
ragge
1.1
519                 ;
520
ragge
1.176
521 enum_head:         C_ENUM { $$ = enumhd(NULL); }
522                 |  C_ENUM C_NAME {  $$ = enumhd($2); }
ragge
1.1
523                 ;
524
525 moe_list:          moe
ragge
1.71
526                 |  moe_list ',' moe
ragge
1.1
527                 ;
528
ragge
1.176
529 moe:               C_NAME {  moedef($1); }
ragge
1.188
530                 |  C_TYPENAME {  moedef($1); }
ragge
1.176
531                 |  C_NAME '=' con_e { enummer = $3; moedef($1); }
ragge
1.188
532                 |  C_TYPENAME '=' con_e { enummer = $3; moedef($1); }
ragge
1.8
533                 ;
534
ragge
1.184
535 struct_dcl:        str_head '{' struct_dcl_list '}' empty {
536                         $$ = dclstruct($1); 
ragge
1.172
537                 }
ragge
1.162
538                 |  C_STRUCT C_NAME {  $$ = rstruct($2,$1); }
ragge
1.132
539                 |  str_head '{' '}' {
540 #ifndef GCC_COMPAT
ragge
1.133
541                         werror("gcc extension");
ragge
1.132
542 #endif
ragge
1.184
543                         $$ = dclstruct($1); 
ragge
1.132
544                 }
ragge
1.8
545                 ;
546
ragge
1.184
547 empty:             { /* Get yacc read the next token before reducing */ }
548                 |  NOMATCH
ragge
1.172
549                 ;
550
ragge
1.162
551 str_head:          C_STRUCT {  $$ = bstruct(NULL, $1);  }
552                 |  C_STRUCT C_NAME {  $$ = bstruct($2,$1);  }
ragge
1.1
553                 ;
554
ragge
1.25
555 struct_dcl_list:   struct_declaration
556                 |  struct_dcl_list struct_declaration
ragge
1.1
557                 ;
558
ragge
1.25
559 struct_declaration:
ragge
1.71
560                    specifier_qualifier_list struct_declarator_list ';' {
ragge
1.104
561                         nfree($1);
ragge
1.4
562                 }
ragge
1.1
563                 ;
564
ragge
1.25
565 specifier_qualifier_list:
ragge
1.72
566                    merge_specifiers { $$ = typenode($1); }
ragge
1.25
567                 ;
568
ragge
1.71
569 merge_specifiers:  type_specifier merge_specifiers { $1->n_left = $2;$$ = $1; }
ragge
1.25
570                 |  type_specifier { $$ = $1; }
ragge
1.71
571                 |  C_QUALIFIER merge_specifiers { $1->n_left = $2; $$ = $1; }
ragge
1.70
572                 |  C_QUALIFIER { $$ = $1; }
ragge
1.25
573                 ;
ragge
1.1
574
ragge
1.25
575 struct_declarator_list:
ragge
1.73
576                    struct_declarator { }
ragge
1.71
577                 |  struct_declarator_list ',' { $<nodep>$=$<nodep>0; } 
ragge
1.73
578                         struct_declarator { }
ragge
1.25
579                 ;
580
ragge
1.89
581 struct_declarator: declarator {
582                         tymerge($<nodep>0, $1);
ragge
1.190
583                         soumemb($1, (char *)$1->n_sp,
584                             $<nodep>0->n_lval); /* XXX */
ragge
1.104
585                         nfree($1);
ragge
1.89
586                 }
ragge
1.71
587                 |  ':' con_e {
ragge
1.191
588                         if (fldchk($2))
stefan
1.178
589                                 $2 = 1;
ragge
1.80
590                         falloc(NULL, $2, -1, $<nodep>0);
ragge
1.25
591                 }
ragge
1.71
592                 |  declarator ':' con_e {
ragge
1.191
593                         if (fldchk($3))
ragge
1.25
594                                 $3 = 1;
ragge
1.72
595                         if ($1->n_op == NAME) {
ragge
1.129
596                                 tymerge($<nodep>0, $1);
ragge
1.190
597                                 soumemb($1, (char *)$1->n_sp, FIELD | $3);
ragge
1.104
598                                 nfree($1);
ragge
1.72
599                         } else
600                                 uerror("illegal declarator");
ragge
1.4
601                 }
ragge
1.1
602                 ;
ragge
1.4
603
ragge
1.1
604                 /* always preceeded by attributes */
ragge
1.167
605 xnfdeclarator:     declarator { $$ = xnf = init_declarator($<nodep>0, $1, 1); }
ragge
1.1
606                 ;
ragge
1.6
607
ragge
1.19
608 /*
609  * Handles declarations and assignments.
610  * Returns nothing.
611  */
ragge
1.88
612 init_declarator:   declarator { init_declarator($<nodep>0, $1, 0); }
ragge
1.125
613                 |  declarator C_ASM '(' string ')' {
614 #ifdef GCC_COMPAT
ragge
1.184
615                         pragma_renamed = newstring($4, strlen($4));
ragge
1.125
616                         init_declarator($<nodep>0, $1, 0);
617 #else
ragge
1.133
618                         werror("gcc extension");
ragge
1.125
619                         init_declarator($<nodep>0, $1, 0);
620 #endif
621                 }
ragge
1.167
622                 |  xnfdeclarator '=' e { simpleinit($1, $3); xnf = NULL; }
623                 |  xnfdeclarator '=' begbr init_list optcomma '}' {
624                         endinit();
625                         xnf = NULL;
626                 }
627                 |  xnfdeclarator '=' addrlbl { simpleinit($1, $3); xnf = NULL; }
ragge
1.163
628                 ;
629
630 begbr:             '{' { beginit($<symp>-1); }
631                 ;
632
633 initializer:       e %prec ',' {  $$ = $1; }
634                 |  addrlbl {  $$ = $1; }
635                 |  ibrace init_list optcomma '}' { $$ = NULL; }
636                 ;
637
ragge
1.164
638 init_list:         designation initializer { asginit($2); }
639                 |  init_list ','  designation initializer { asginit($4); }
ragge
1.163
640                 ;
641
ragge
1.164
642 designation:       designator_list '=' { desinit($1); }
643                 |  { /* empty */ }
ragge
1.19
644                 ;
ragge
1.1
645
ragge
1.163
646 designator_list:   designator { $$ = $1; }
647                 |  designator_list designator { $$ = $2; $$->n_left = $1; }
ragge
1.1
648                 ;
ragge
1.6
649
stefan
1.183
650 designator:        '[' con_e ']' {
651                         if ($2 < 0) {
652                                 uerror("designator must be non-negative");
653                                 $2 = 0;
654                         }
655                         $$ = bdty(LB, NULL, $2);
656                 }
stefan
1.186
657                 |  C_STROP C_NAME {
658                         if ($1 != DOT)
659                                 uerror("invalid designator");
660                         $$ = bdty(NAME, $2);
661                 }
ragge
1.1
662                 ;
663
664 optcomma        :       /* VOID */
ragge
1.71
665                 |  ','
ragge
1.1
666                 ;
667
ragge
1.71
668 ibrace:            '{' {  ilbrace(); }
ragge
1.1
669                 ;
670
671 /*      STATEMENTS      */
672
ragge
1.182
673 compoundstmt:      begin block_item_list '}' {  
gmcgarry
1.204
674                         if (sspflag && blevel == 2)
675                                 sspend();
ragge
1.138
676 #ifdef STABS
ragge
1.141
677                         if (gflag && blevel > 2)
ragge
1.139
678                                 stabs_rbrac(blevel);
ragge
1.138
679 #endif
ragge
1.8
680                         --blevel;
681                         if( blevel == 1 )
682                                 blevel = 0;
ragge
1.108
683                         symclear(blevel); /* Clean ut the symbol table */
ragge
1.150
684                         if (autooff > maxautooff)
685                                 maxautooff = autooff;
ragge
1.83
686                         autooff = savctx->contlab;
687                         savctx = savctx->next;
ragge
1.8
688                 }
ragge
1.182
689                 |  begin '}' {
gmcgarry
1.204
690                         if (sspflag && blevel == 2)
691                                 sspend();
ragge
1.138
692 #ifdef STABS
ragge
1.141
693                         if (gflag && blevel > 2)
ragge
1.139
694                                 stabs_rbrac(blevel);
ragge
1.138
695 #endif
ragge
1.8
696                         --blevel;
697                         if( blevel == 1 )
698                                 blevel = 0;
ragge
1.108
699                         symclear(blevel); /* Clean ut the symbol table */
ragge
1.150
700                         if (autooff > maxautooff)
701                                 maxautooff = autooff;
ragge
1.83
702                         autooff = savctx->contlab;
703                         savctx = savctx->next;
ragge
1.8
704                 }
ragge
1.1
705                 ;
706
ragge
1.71
707 begin:            '{' {
ragge
1.83
708                         struct savbc *bc = tmpalloc(sizeof(struct savbc));
ragge
1.138
709                         if (blevel == 1) {
710 #ifdef STABS
711                                 if (gflag)
ragge
1.139
712                                         stabs_line(lineno);
ragge
1.138
713 #endif
ragge
1.92
714                                 dclargs();
ragge
1.140
715                         }
ragge
1.138
716 #ifdef STABS
ragge
1.141
717                         if (gflag && blevel > 1)
ragge
1.140
718                                 stabs_lbrac(blevel+1);
ragge
1.138
719 #endif
ragge
1.8
720                         ++blevel;
ragge
1.112
721                         oldstyle = 0;
ragge
1.83
722                         bc->contlab = autooff;
723                         bc->next = savctx;
724                         savctx = bc;
ragge
1.182
725                         bccode();
gmcgarry
1.204
726                         if (sspflag && blevel == 2)
727                                 sspstart();
ragge
1.8
728                 }
ragge
1.1
729                 ;
730
ragge
1.189
731 statement:         e ';' { ecomp( $1 ); symclear(blevel); }
ragge
1.1
732                 |  compoundstmt
ragge
1.142
733                 |  ifprefix statement { plabel($1); reached = 1; }
ragge
1.8
734                 |  ifelprefix statement {
ragge
1.72
735                         if ($1 != NOLAB) {
ragge
1.142
736                                 plabel( $1);
ragge
1.1
737                                 reached = 1;
ragge
1.8
738                         }
739                 }
740                 |  whprefix statement {
ragge
1.98
741                         branch(contlab);
ragge
1.142
742                         plabel( brklab );
ragge
1.8
743                         if( (flostat&FBRK) || !(flostat&FLOOP))
744                                 reached = 1;
745                         else
746                                 reached = 0;
747                         resetbc(0);
748                 }
ragge
1.71
749                 |  doprefix statement C_WHILE '(' e ')' ';' {
ragge
1.142
750                         plabel(contlab);
ragge
1.48
751                         if (flostat & FCONT)
ragge
1.8
752                                 reached = 1;
ragge
1.128
753                         if (reached)
754                                 cbranch($5, bcon($1));
ragge
1.130
755                         else
756                                 tfree($5);
ragge
1.142
757                         plabel( brklab);
ragge
1.8
758                         reached = 1;
759                         resetbc(0);
760                 }
ragge
1.71
761                 |  forprefix .e ')' statement
ragge
1.142
762                         {  plabel( contlab );
ragge
1.1
763                             if( flostat&FCONT ) reached = 1;
764                             if( $2 ) ecomp( $2 );
ragge
1.98
765                             branch($1);
ragge
1.142
766                             plabel( brklab );
ragge
1.1
767                             if( (flostat&FBRK) || !(flostat&FLOOP) ) reached = 1;
768                             else reached = 0;
769                             resetbc(0);
770                             }
771                 | switchpart statement
ragge
1.154
772                         { if( reached ) branch( brklab );
ragge
1.142
773                             plabel( $1 );
ragge
1.154
774                             swend();
ragge
1.142
775                             plabel( brklab);
ragge
1.1
776                             if( (flostat&FBRK) || !(flostat&FDEF) ) reached = 1;
777                             resetbc(FCONT);
778                             }
ragge
1.72
779                 |  C_BREAK  ';' {
780                         if (brklab == NOLAB)
781                                 uerror("illegal break");
782                         else if (reached)
783                                 branch(brklab);
784                         flostat |= FBRK;
785                         reached = 0;
786                 }
787                 |  C_CONTINUE  ';' {
788                         if (contlab == NOLAB)
789                                 uerror("illegal continue");
790                         else
791                                 branch(contlab);
792                         flostat |= FCONT;
793                         goto rch;
794                 }
ragge
1.106
795                 |  C_RETURN  ';' {
796                         branch(retlab);
ragge
1.203
797                         if (cftnsp->stype != VOID && noretype == 0 &&
ragge
1.131
798                             cftnsp->stype != VOID+FTN)
ragge
1.106
799                                 uerror("return value required");
ragge
1.1
800                         rch:
ragge
1.106
801                         if (!reached)
802                                 werror( "statement is not reached");
803                         reached = 0;
804                 }
ragge
1.71
805                 |  C_RETURN e  ';' {
ragge
1.46
806                         register NODE *temp;
807
ragge
1.72
808                         spname = cftnsp;
ragge
1.46
809                         temp = buildtree( NAME, NIL, NIL );
ragge
1.106
810                         temp->n_type = DECREF(temp->n_type);
811                         temp = buildtree(RETURN, temp, $2);
812
ragge
1.109
813                         if (temp->n_type == VOID)
814                                 ecomp(temp->n_right);
815                         else
816                                 ecomp(buildtree(FORCE, temp->n_right, NIL));
gmcgarry
1.175
817                         tfree(temp->n_left);
ragge
1.104
818                         nfree(temp);
ragge
1.46
819                         branch(retlab);
820                         reached = 0;
821                 }
ragge
1.71
822                 |  C_GOTO C_NAME ';' { gotolabel($2); goto rch; }
ragge
1.133
823                 |  C_GOTO '*' e ';' {
824                         ecomp(block(GOTO, $3, NIL, INT, 0, 0));
825                 }
ragge
1.136
826                 |  asmstatement ';'
ragge
1.71
827                 |   ';'
828                 |  error  ';'
829                 |  error '}'
ragge
1.1
830                 |  label statement
831                 ;
ragge
1.52
832
ragge
1.201
833 asmstatement:      C_ASM mvol '(' string ')' { send_passt(IP_ASM, mkpstr($4)); }
834                 |  C_ASM mvol '(' string xasm ')' { mkxasm($4, $5); }
835                 ;
836
837 mvol:              /* empty */
838                 |  C_QUALIFIER { nfree($1); }
ragge
1.195
839                 ;
840
841 xasm:              ':' oplist { $$ = xcmop($2, NIL, NIL); }
842                 |  ':' oplist ':' oplist { $$ = xcmop($2, $4, NIL); }
843                 |  ':' oplist ':' oplist ':' cnstr { $$ = xcmop($2, $4, $6); }
844                 ;
845
846 oplist:            /* nothing */ { $$ = NIL; }
847                 |  oper { $$ = $1; }
848                 ;
849
850 oper:              string '(' e ')' { $$ = xasmop($1, $3); }
851                 |  oper ',' string '(' e ')' { $$ = cmop($1, xasmop($3, $5)); }
ragge
1.52
852                 ;
853
ragge
1.195
854 cnstr:             string { $$ = xasmop($1, bcon(0)); }
855                 |  cnstr ',' string { $$ = cmop($1, xasmop($3, bcon(0))); }
856                 ;
857
ragge
1.71
858 label:             C_NAME ':' { deflabel($1); reached = 1; }
859                 |  C_CASE e ':' { addcase($2); reached = 1; }
860                 |  C_DEFAULT ':' { reached = 1; adddef(); flostat |= FDEF; }
ragge
1.1
861                 ;
ragge
1.8
862
ragge
1.114
863 doprefix:       C_DO {
864                         savebc();
865                         brklab = getlab();
866                         contlab = getlab();
ragge
1.142
867                         plabel(  $$ = getlab());
ragge
1.114
868                         reached = 1;
869                 }
ragge
1.1
870                 ;
ragge
1.113
871 ifprefix:       C_IF '(' e ')' {
ragge
1.128
872                         cbranch(buildtree(NOT, $3, NIL), bcon($$ = getlab()));
ragge
1.113
873                         reached = 1;
874                 }
ragge
1.1
875                 ;
ragge
1.72
876