]> andersk Git - splint.git/blob - src/cgrammar.y
Initial revision
[splint.git] / src / cgrammar.y
1 /*;-*-C-*-;
2 ** Copyright (c) Massachusetts Institute of Technology 1994-1998.
3 **          All Rights Reserved.
4 **          Unpublished rights reserved under the copyright laws of
5 **          the United States.
6 **
7 ** THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
8 ** OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
9 **
10 ** This code is distributed freely and may be used freely under the 
11 ** following conditions:
12 **
13 **     1. This notice may not be removed or altered.
14 **
15 **     2. Works derived from this code are not distributed for
16 **        commercial gain without explicit permission from MIT 
17 **        (for permission contact lclint-request@sds.lcs.mit.edu).
18 */
19 %{
20 /*
21 **
22 ** cgrammar.y
23 **
24 ** Yacc/Bison grammar for extended ANSI C used by LCLint.
25 **
26 ** original grammar by Nate Osgood ---
27 **    hacrat@catfish.lcs.mit.edu Mon Jun 14 13:06:32 1993
28 **
29 ** changes for LCLint --- handle typedef names correctly
30 ** fix struct/union parsing bug (empty struct is accepted)
31 ** add productions to handle macros --- require
32 ** error correction --- main source of conflicts in grammar.
33 ** need to process initializations sequentially, L->R
34 **
35 ** production names are cryptic, so more productions fit on one line
36 **
37 ** conflicts:  87 shift/reduce, 18 reduce/reduce
38 ** most of these are due to handling macros
39 ** a few are due to handling type expressions
40 */
41
42 /*@=allmacros@*/
43
44 extern int yylex ();
45 extern void swallowMacro (void);
46
47 # include "lclintMacros.nf"
48 # include "basic.h"
49 # include "cgrammar.h"
50 # include "exprChecks.h"
51
52 /*@-allmacros@*/
53 /*@-matchfields@*/
54
55 # define SHOWCSYM FALSE
56 void yyerror (char *s);
57
58 /*
59 ** This is necessary, or else when the bison-generated code #include's malloc.h,
60 ** there will be a parse error.
61 **
62 ** Unfortunately, it means the error checking on malloc, etc. is lost for allocations
63 ** in bison-generated files under Win32.
64 */
65
66 # ifdef WIN32
67 # undef malloc
68 # undef calloc
69 # undef realloc
70 # endif
71
72 %}
73
74 %union
75 {
76  lltok tok;
77  int count;
78  specialClauseKind sck;
79  qual typequal;
80  qualList tquallist;
81  ctype ctyp;
82  sRef sr;
83  /*@only@*/ qtype qtyp;
84  /*@only@*/ cstring cname;
85  /*@only@*/ idDecl ntyp;
86  /*@only@*/ idDeclList ntyplist;
87  /*@only@*/ uentryList flist;
88  /*@owned@*/ uentryList entrylist;
89  /*@observer@*/ /*@dependent@*/ uentry entry;
90  /*@only@*/ uentry oentry;
91  /*@only@*/ exprNode expr;
92  /*@only@*/ enumNameList enumnamelist;
93  /*@only@*/ exprNodeList alist;
94  /*@only@*/ sRefSet srset; 
95  /*@only@*/ cstringList cstringlist;
96 }
97
98 /* standard C tokens */
99
100 %token <tok> BADTOK SKIPTOK
101 %token <tok> CTOK_ELIPSIS CASE DEFAULT CIF CELSE SWITCH WHILE DO CFOR
102 %token <tok> GOTO CONTINUE BREAK RETURN
103 %token <tok> TSEMI TLBRACE TRBRACE TCOMMA TCOLON TASSIGN TLPAREN 
104 %token <tok> TRPAREN TLSQBR TRSQBR TDOT TAMPERSAND TEXCL TTILDE
105 %token <tok> TMINUS TPLUS TMULT TDIV TPERCENT TLT TGT TCIRC TBAR TQUEST
106 %token <tok> CSIZEOF CALIGNOF ARROW_OP CTYPEDEF COFFSETOF
107 %token <tok> INC_OP DEC_OP LEFT_OP RIGHT_OP
108 %token <tok> LE_OP GE_OP EQ_OP NE_OP AND_OP OR_OP
109 %token <tok> MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN SUB_ASSIGN
110 %token <tok> LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN
111 %token <tok> CSTRUCT CUNION CENUM
112 %token <tok> VA_ARG VA_DCL
113 %token <tok> QGLOBALS
114 %token <tok> QMODIFIES 
115 %token <tok> QNOMODS
116 %token <tok> QCONSTANT
117 %token <tok> QFUNCTION
118 %token <tok> QITER
119 %token <tok> QDEFINES 
120 %token <tok> QUSES
121 %token <tok> QALLOCATES
122 %token <tok> QSETS
123 %token <tok> QRELEASES 
124 %token <tok> QPRECLAUSE 
125 %token <tok> QPOSTCLAUSE 
126 %token <tok> QALT 
127 %token <tok> QUNDEF QKILLED
128 %token <tok> QENDMACRO
129
130 /* additional tokens introduced by lclint pre-processor. */
131 %token <tok> LLMACRO LLMACROITER LLMACROEND TENDMACRO
132
133 /* break comments: */
134 %token <tok> QSWITCHBREAK QLOOPBREAK QINNERBREAK QSAFEBREAK
135 %token <tok> QINNERCONTINUE
136
137 /* case fall-through marker: */
138 %token <tok> QFALLTHROUGH
139
140 /* used in scanner only */
141 %token <tok> QLINTNOTREACHED
142 %token <tok> QLINTFALLTHROUGH
143 %token <tok> QLINTFALLTHRU
144 %token <tok> QARGSUSED
145 %token <tok> QPRINTFLIKE QLINTPRINTFLIKE QSCANFLIKE QMESSAGELIKE
146
147 /* not-reached marker: (used like a label) */
148 %token <tok> QNOTREACHED
149
150 /* type qualifiers: */
151 %token <tok> QCONST QVOLATILE QINLINE QEXTENSION QEXTERN QSTATIC QAUTO QREGISTER
152 %token <tok> QOUT QIN QYIELD QONLY QTEMP QSHARED QREF QUNIQUE
153 %token <tok> QCHECKED QUNCHECKED QCHECKEDSTRICT QCHECKMOD
154 %token <tok> QKEEP QKEPT QPARTIAL QSPECIAL QOWNED QDEPENDENT
155 %token <tok> QRETURNED QEXPOSED QNULL QOBSERVER QISNULL 
156 %token <tok> QEXITS QMAYEXIT QNEVEREXIT QTRUEEXIT QFALSEEXIT
157 %token <tok> QLONG QSIGNED QUNSIGNED QSHORT QUNUSED QSEF QNOTNULL QRELNULL
158 %token <tok> QABSTRACT QCONCRETE QMUTABLE QIMMUTABLE
159 %token <tok> QTRUENULL QFALSENULL QEXTERNAL
160 %token <tok> QREFCOUNTED QREFS QNEWREF QTEMPREF QKILLREF QRELDEF
161 %token <ctyp> CGCHAR CBOOL CINT CGFLOAT CDOUBLE CVOID 
162 %token <tok> QANYTYPE QINTEGRALTYPE QUNSIGNEDINTEGRALTYPE QSIGNEDINTEGRALTYPE
163
164 /* identifiers, literals */
165 %token <entry> IDENTIFIER
166 %token <cname> NEW_IDENTIFIER TYPE_NAME_OR_ID 
167 %token <expr>  CCONSTANT
168 %token <entry> ITER_NAME ITER_ENDNAME 
169 %type <entry> endIter 
170 %type <sr> globId
171 %token <ctyp>  TYPE_NAME 
172 %type <cname> enumerator newId  /*@-varuse@*/ /* yacc declares yytranslate here */
173 %type <count> pointers /*@=varuse@*/
174
175 %type <tok> doHeader specialTag endSpecialTag stateSpecialClause endStateTag 
176 %type <sck> specialClauseType
177
178 /* type construction */
179 %type <ctyp> abstractDecl abstractDeclBase optAbstractDeclBase
180 %type <ctyp> suSpc enumSpc typeName typeSpecifier
181
182 %type <ntyp> namedDecl namedDeclBase optNamedDecl
183 %type <ntyp> plainNamedDecl plainNamedDeclBase
184 %type <ntyp> structNamedDecl
185 %type <ntyp> fcnDefHdrAux plainFcn
186
187 %type <oentry> paramDecl 
188 %type <entry> id 
189
190 %type <ntyplist> structNamedDeclList
191
192 %type <entrylist> genericParamList paramTypeList paramList idList paramIdList
193 %type <alist> argumentExprList iterArgList
194 %type <alist> initList
195 %type <flist> structDeclList structDecl
196 %type <srset> locModifies locPlainModifies modList specClauseList
197 %type <sr>    mExpr modListExpr specClauseListExpr
198 %type <enumnamelist> enumeratorList 
199 %type <cstringlist> fieldDesignator
200
201 %type <expr> sizeofExpr sizeofExprAux offsetofExpr
202 %type <expr> openScope closeScope 
203 %type <expr> instanceDecl namedInitializer optDeclarators
204 %type <expr> primaryExpr postfixExpr primaryIterExpr postfixIterExpr
205 %type <expr> unaryExpr castExpr timesExpr plusExpr
206 %type <expr> unaryIterExpr castIterExpr timesIterExpr plusIterExpr
207 %type <expr> shiftExpr relationalExpr equalityExpr bitandExpr
208 %type <expr> xorExpr bitorExpr andExpr
209 %type <expr> orExpr conditionalExpr assignExpr 
210 %type <expr> shiftIterExpr relationalIterExpr equalityIterExpr bitandIterExpr
211 %type <expr> xorIterExpr bitorIterExpr andIterExpr
212 %type <expr> orIterExpr conditionalIterExpr assignIterExpr iterArgExpr
213 %type <expr> expr optExpr constantExpr
214 %type <expr> init macroBody iterBody endBody partialIterStmt iterSelectionStmt
215 %type <expr> stmt stmtList fcnBody iterStmt iterDefStmt iterDefStmtList
216 %type <expr> labeledStmt caseStmt defaultStmt 
217 %type <expr> compoundStmt compoundStmtAux compoundStmtRest compoundStmtAuxErr
218 %type <expr> expressionStmt selectionStmt iterationStmt jumpStmt iterDefIterationStmt 
219 %type <expr> stmtErr stmtListErr compoundStmtErr expressionStmtErr 
220 %type <expr> iterationStmtErr initializerList initializer ifPred whilePred forPred iterWhilePred
221
222 %type <typequal> storageSpecifier typeQualifier typeModifier globQual
223 %type <tquallist> optGlobQuals
224 %type <qtyp> completeType completeTypeSpecifier optCompleteType
225 %type <qtyp> completeTypeSpecifierAux altType typeExpression 
226
227 %start file
228
229 %%
230
231 file
232  :              
233  | externalDefs
234
235 externalDefs
236  : externalDef
237  | externalDefs externalDef 
238
239 externalDef
240  : fcnDef optSemi { uentry_clearDecl (); } 
241  | constantDecl   { uentry_clearDecl (); } 
242  | fcnDecl        { uentry_clearDecl (); }
243  | iterDecl       { uentry_clearDecl (); } 
244  | macroDef       { uentry_clearDecl (); } 
245  | initializer    { uentry_checkDecl (); exprNode_free ($1); }
246  | error          { uentry_clearDecl (); } 
247
248 constantDecl
249  : QCONSTANT completeTypeSpecifier NotType namedDecl NotType optSemi IsType QENDMACRO
250    { checkConstant ($2, $4); }
251  | QCONSTANT completeTypeSpecifier NotType namedDecl NotType TASSIGN IsType init optDeclarators optSemi QENDMACRO
252    { checkValueConstant ($2, $4, $8) ; }
253
254 fcnDecl
255  : QFUNCTION { context_enterFunctionDecl (); } plainFcn optSemi QENDMACRO 
256    { declareStaticFunction ($3); context_quietExitFunction (); 
257      context_exitFunctionDecl (); }
258
259 plainFcn
260  : plainNamedDecl
261    { 
262      qtype qint = qtype_create (ctype_int);
263      $$ = idDecl_fixBase ($1, qint);
264      qtype_free (qint);
265    }
266  | completeTypeSpecifier NotType plainNamedDecl
267    { $$ = idDecl_fixBase ($3, $1); }
268
269 plainNamedDecl
270  : plainNamedDeclBase
271  | pointers plainNamedDeclBase 
272    { $$ = $2; qtype_adjustPointers ($1, idDecl_getTyp ($$)); }
273
274 namedDeclBase
275  : newId { $$ = idDecl_create ($1, qtype_unknown ()); }
276  | IsType TLPAREN NotType namedDecl IsType TRPAREN
277    { $$ = idDecl_expectFunction ($4); }
278  | namedDeclBase TLSQBR TRSQBR 
279    { $$ = idDecl_replaceCtype ($1, ctype_makeArray (idDecl_getCtype ($1))); }
280  | namedDeclBase TLSQBR IsType constantExpr TRSQBR NotType
281    { 
282      int value;
283
284      if (exprNode_hasValue ($4) 
285          && multiVal_isInt (exprNode_getValue ($4)))
286        {
287          value = (int) multiVal_forceInt (exprNode_getValue ($4));
288        }
289      else
290        {
291          value = 0;
292        }
293
294      $$ = idDecl_replaceCtype ($1, ctype_makeFixedArray (idDecl_getCtype ($1), value));
295    }
296  | namedDeclBase PushType TLPAREN TRPAREN 
297    { setCurrentParams (uentryList_missingParams); 
298         }
299    optGlobMods 
300    { /* need to support globals and modifies here! */
301      ctype ct = ctype_makeFunction (idDecl_getCtype ($1), 
302                                     uentryList_makeMissingParams ());
303
304      $$ = idDecl_replaceCtype ($1, ct);
305      context_popLoc (); 
306    }
307  | namedDeclBase PushType TLPAREN genericParamList TRPAREN 
308    { setCurrentParams ($4); 
309         } 
310    optGlobMods
311    { clearCurrentParams ();
312      $$ = idDecl_replaceCtype ($1, ctype_makeFunction (idDecl_getCtype ($1), $4));
313      context_popLoc (); 
314    }
315
316 plainNamedDeclBase
317  : newId { $$ = idDecl_create ($1, qtype_unknown ()); }
318  | IsType TLPAREN NotType plainNamedDecl IsType TRPAREN
319    { $$ = idDecl_expectFunction ($4); }
320  | plainNamedDeclBase TLSQBR TRSQBR 
321    { $$ = idDecl_replaceCtype ($1, ctype_makeArray (idDecl_getCtype ($1))); }
322  | plainNamedDeclBase TLSQBR IsType constantExpr TRSQBR NotType
323    { 
324      int value;
325
326      if (exprNode_hasValue ($4) 
327          && multiVal_isInt (exprNode_getValue ($4)))
328        {
329          value = (int) multiVal_forceInt (exprNode_getValue ($4));
330        }
331      else
332        {
333          value = 0;
334        }
335
336      $$ = idDecl_replaceCtype ($1, ctype_makeFixedArray (idDecl_getCtype ($1), value));
337    }
338  | plainNamedDeclBase PushType TLPAREN TRPAREN 
339    { setCurrentParams (uentryList_missingParams); 
340         }
341    optPlainGlobMods 
342    { /* need to support globals and modifies here! */
343      ctype ct = ctype_makeFunction (idDecl_getCtype ($1), 
344                                     uentryList_makeMissingParams ());
345
346      $$ = idDecl_replaceCtype ($1, ct);
347      context_popLoc (); 
348    }
349  | plainNamedDeclBase PushType TLPAREN genericParamList TRPAREN 
350    { setCurrentParams ($4); 
351         } 
352    optPlainGlobMods
353    { clearCurrentParams ();
354      $$ = idDecl_replaceCtype ($1, ctype_makeFunction (idDecl_getCtype ($1), $4));
355      context_popLoc (); 
356    }
357
358 iterDecl
359  : QITER newId TLPAREN genericParamList TRPAREN 
360    { setCurrentParams ($4); } optPlainGlobMods 
361    { clearCurrentParams (); } optSemi QENDMACRO
362    { declareCIter ($2, $4); }
363
364 macroDef
365  : LLMACRO macroBody TENDMACRO     { exprNode_checkMacroBody ($2); }
366  | LLMACROITER iterBody TENDMACRO  { exprNode_checkIterBody ($2); }
367  | LLMACROEND endBody TENDMACRO    { exprNode_checkIterEnd ($2); }
368  | LLMACRO TENDMACRO /* no stmt */ { exprChecks_checkEmptyMacroBody (); } 
369
370 fcnDefHdr
371   : fcnDefHdrAux { declareFunction ($1); }
372
373 optGlobMods
374  : { setProcessingGlobMods (); } optGlobModsRest
375    { clearProcessingGlobMods (); }
376
377 optPlainGlobMods
378  : { setProcessingGlobMods (); } optPlainGlobModsRest
379    { clearProcessingGlobMods (); }
380
381 optGlobModsRest
382  : optGlobModsAux 
383  | specialClauses optGlobModsAux
384
385 optPlainGlobModsRest
386  : optPlainGlobModsAux 
387  | specialClauses optPlainGlobModsAux
388
389 specialClauses
390  : specialClause
391  | specialClause specialClauses
392  
393 globIdList
394  : globIdListExpr                     { ; }
395  | globIdList TCOMMA globIdListExpr   { ; }
396  
397 globIdListExpr 
398  : optGlobQuals globId { globListAdd ($2, $1); }
399
400 globId
401  : id             { $$ = uentry_getSref ($1); }
402  | NEW_IDENTIFIER { $$ = globListUnrecognized ($1); }
403
404 globQual
405  : QUNDEF   { $$ = qual_createUndef (); }
406  | QKILLED  { $$ = qual_createKilled (); }
407  | QOUT     { $$ = qual_createOut (); }
408  | QIN      { $$ = qual_createIn (); }
409  | QPARTIAL { $$ = qual_createPartial (); }
410
411 optGlobQuals
412  : /* empty */         { $$ = qualList_undefined; }
413  | globQual optGlobQuals { $$ = qualList_add ($2, $1); }
414
415 optGlobModsAux  
416  : QGLOBALS { setProcessingGlobalsList (); } initializerList optSemi 
417    QENDMACRO optMods
418    { unsetProcessingGlobals (); }
419  | QGLOBALS { setProcessingGlobalsList (); } globIdList optSemi 
420    QENDMACRO optMods
421    { unsetProcessingGlobals (); }
422  | QNOMODS 
423    { setFunctionNoGlobals ();
424      setFunctionModifies (sRefSet_single (sRef_makeNothing ())); 
425    }
426  | fcnMods
427  | /* empty */
428
429 optPlainGlobModsAux
430  : QGLOBALS { setProcessingGlobalsList (); } initializerList optSemi 
431    optMods
432    { unsetProcessingGlobals (); }
433  | QGLOBALS { setProcessingGlobalsList (); } globIdList optSemi 
434    optMods
435    { unsetProcessingGlobals (); }
436  | QNOMODS 
437    { setFunctionNoGlobals ();
438      setFunctionModifies (sRefSet_single (sRef_makeNothing ())); 
439    }
440  | fcnPlainMods
441  | /* empty */
442
443 optMods
444  : fcnMods
445  | /* empty */
446
447 fcnMods
448  : QMODIFIES 
449    {
450      context_setProtectVars (); enterParamsTemp (); 
451      sRef_setGlobalScopeSafe (); 
452    }
453    locModifies
454    { 
455      setFunctionModifies ($3); exitParamsTemp ();
456      sRef_clearGlobalScopeSafe (); 
457      context_releaseVars ();
458    }
459
460 fcnPlainMods
461  : QMODIFIES 
462    {
463      context_setProtectVars (); enterParamsTemp (); 
464      sRef_setGlobalScopeSafe (); 
465    }
466    locPlainModifies
467    { 
468      setFunctionModifies ($3); exitParamsTemp ();
469      sRef_clearGlobalScopeSafe (); 
470      context_releaseVars ();
471    }
472
473 specialTag
474  : QDEFINES
475  | QUSES
476  | QALLOCATES
477  | QSETS
478  | QRELEASES
479
480 endStateTag
481  : QENDMACRO
482
483 endSpecialTag
484  : QENDMACRO
485
486 stateSpecialClause
487  : QPRECLAUSE
488  | QPOSTCLAUSE
489
490 specialClauseType
491  : QONLY       { $$ = SP_ISONLY; }
492  | QOBSERVER   { $$ = SP_ISOBSERVER; }
493  | QEXPOSED    { $$ = SP_ISEXPOSED; }
494  | QDEPENDENT  { $$ = SP_ISDEPENDENT; }
495  | QOWNED      { $$ = SP_ISOWNED; }
496  | QSHARED     { $$ = SP_ISSHARED; }
497  | QISNULL     { $$ = SP_ISNULL; }
498  | QNOTNULL    { $$ = SP_ISNOTNULL; }
499  
500 specialClause
501  : specialTag NotType
502    {
503      context_setProtectVars (); 
504      enterParamsTemp (); 
505      sRef_setGlobalScopeSafe (); 
506    }
507    specClauseList optSemi endSpecialTag IsType
508    { 
509      setFunctionSpecialClause ($1, $4, $6); 
510      exitParamsTemp ();
511      sRef_clearGlobalScopeSafe (); 
512      context_releaseVars ();
513    }
514   | stateSpecialClause NotType specialClauseType 
515     {
516       context_setProtectVars (); 
517       enterParamsTemp (); 
518       sRef_setGlobalScopeSafe (); 
519     }
520     specClauseList optSemi endStateTag IsType
521     { 
522       setFunctionStateSpecialClause ($1, $3, $5, $7); 
523       exitParamsTemp ();
524       sRef_clearGlobalScopeSafe (); 
525       context_releaseVars ();
526     }
527
528 fcnDefHdrAux
529  : namedDecl                               
530    { 
531      qtype qint = qtype_create (ctype_int);
532      $$ = idDecl_fixBase ($1, qint);
533      qtype_free (qint);
534    }
535  | completeTypeSpecifier NotType namedDecl 
536    { $$ = idDecl_fixBase ($3, $1); }
537  
538 fcnBody
539  : TLBRACE { checkDoneParams (); context_enterInnerContext (); } 
540    compoundStmtRest 
541    {  
542      exprNode_checkFunctionBody ($3); $$ = $3; 
543      context_exitInner ($3); 
544    }
545  | initializerList 
546    { doneParams (); context_enterInnerContext (); }
547    compoundStmt 
548    {
549      context_exitInner ($3);
550      exprNode_checkFunctionBody ($3); 
551      $$ = $3; /* old style */ 
552    } 
553  
554 fcnDef
555  : fcnDefHdr fcnBody 
556    { 
557      context_setFunctionDefined (exprNode_loc ($2)); 
558      exprNode_checkFunction (context_getHeader (), $2); 
559      context_exitFunction ();
560    }
561
562 locModifies
563  : modList optSemi QENDMACRO { $$ = $1; }
564  | optSemi QENDMACRO         { $$ = sRefSet_new (); }
565
566 locPlainModifies
567  : modList optSemi           { $$ = $1; }
568  | optSemi                   { $$ = sRefSet_new (); }
569  
570 modListExpr
571  : id                              { $$ = uentry_getSref ($1); checkModifiesId ($1); }
572  | NEW_IDENTIFIER                  { $$ = fixModifiesId ($1); }
573  | modListExpr TLSQBR TRSQBR       { $$ = modListArrayFetch ($1, sRef_undefined); }
574  | modListExpr TLSQBR mExpr TRSQBR { $$ = modListArrayFetch ($1, $3); }
575  | TMULT modListExpr               { $$ = modListPointer ($2); }
576  | TLPAREN modListExpr TRPAREN     { $$ = $2; }  
577  | modListExpr TDOT newId          { $$ = modListFieldAccess ($1, $3); }
578  | modListExpr ARROW_OP newId      { $$ = modListArrowAccess ($1, $3); }
579
580
581 mExpr
582   : modListExpr { $$ = $1; }
583   | CCONSTANT   { $$ = sRef_makeUnknown (); /* sRef_makeConstant ($1); ? */ }
584     /* arithmetic? */
585
586 modList
587   : modListExpr                { $$ = sRefSet_single ($1); }
588   | modList TCOMMA modListExpr { $$ = sRefSet_insert ($1, $3); }
589
590 specClauseListExpr
591  : id                                     
592    { $$ = checkSpecClausesId ($1); }
593  | NEW_IDENTIFIER                         
594    { $$ = fixSpecClausesId ($1); }
595  | specClauseListExpr TLSQBR TRSQBR       { $$ = sRef_makeAnyArrayFetch ($1); }
596  | specClauseListExpr TLSQBR mExpr TRSQBR { $$ = sRef_makeAnyArrayFetch ($1); }
597  | TMULT specClauseListExpr               { $$ = sRef_constructPointer ($2); }
598  | TLPAREN specClauseListExpr TRPAREN     { $$ = $2; }  
599  | specClauseListExpr TDOT newId          { cstring_markOwned ($3);
600                                             $$ = sRef_buildField ($1, $3); }
601  | specClauseListExpr ARROW_OP newId      { cstring_markOwned ($3);
602                                             $$ = sRef_makeArrow ($1, $3); }
603
604 specClauseList
605   : specClauseListExpr                       
606     { if (sRef_isValid ($1)) { $$ = sRefSet_single ($1); } 
607       else { $$ = sRefSet_undefined; } 
608     }
609   | specClauseList TCOMMA specClauseListExpr 
610     { if (sRef_isValid ($3))
611         {
612           $$ = sRefSet_insert ($1, $3); 
613         }
614       else
615         {
616           $$ = $1;
617         }
618     }
619
620 primaryExpr
621  : id { $$ = exprNode_fromIdentifier ($1); }
622  | NEW_IDENTIFIER { $$ = exprNode_fromUIO ($1); } 
623  | CCONSTANT
624  | TLPAREN expr TRPAREN { $$ = exprNode_addParens ($1, $2); }
625  | TYPE_NAME_OR_ID { $$ = exprNode_fromIdentifier (coerceId ($1)); } 
626  | QEXTENSION { $$ = exprNode_makeError (); }
627  
628 postfixExpr
629  : primaryExpr 
630  | postfixExpr TLSQBR expr TRSQBR { $$ = exprNode_arrayFetch ($1, $3); }
631  | postfixExpr TLPAREN TRPAREN { $$ = exprNode_functionCall ($1, exprNodeList_new ()); }
632  | postfixExpr TLPAREN argumentExprList TRPAREN { $$ = exprNode_functionCall ($1, $3); }
633  | VA_ARG TLPAREN assignExpr TCOMMA typeExpression TRPAREN { $$ = exprNode_vaArg ($1, $3, $5); }
634  | postfixExpr NotType TDOT newId IsType { $$ = exprNode_fieldAccess ($1, $4); }
635  | postfixExpr NotType ARROW_OP newId IsType { $$ = exprNode_arrowAccess ($1, $4); }
636  | postfixExpr INC_OP { $$ = exprNode_postOp ($1, $2); }
637  | postfixExpr DEC_OP { $$ = exprNode_postOp ($1, $2); }
638  
639 argumentExprList
640  : assignExpr { $$ = exprNodeList_singleton ($1); }
641  | argumentExprList TCOMMA assignExpr { $$ = exprNodeList_push ($1, $3); }
642  
643 unaryExpr
644  : postfixExpr 
645  | INC_OP unaryExpr { $$ = exprNode_preOp ($2, $1); }
646  | DEC_OP unaryExpr { $$ = exprNode_preOp ($2, $1); }
647  | TAMPERSAND castExpr { $$ = exprNode_preOp ($2, $1); }
648  | TMULT castExpr  { $$ = exprNode_preOp ($2, $1); }
649  | TPLUS castExpr  { $$ = exprNode_preOp ($2, $1); }
650  | TMINUS castExpr { $$ = exprNode_preOp ($2, $1); }
651  | TTILDE castExpr { $$ = exprNode_preOp ($2, $1); }
652  | TEXCL castExpr  { $$ = exprNode_preOp ($2, $1); }
653  | sizeofExpr      { $$ = $1; }
654  | offsetofExpr    { $$ = $1; }
655
656 fieldDesignator
657  : fieldDesignator TDOT newId { $$ = cstringList_add ($1, $3); }
658  | newId                      { $$ = cstringList_single ($1); }
659
660 offsetofExpr
661  : COFFSETOF IsType TLPAREN typeExpression NotType TCOMMA fieldDesignator TRPAREN IsType
662    { $$ = exprNode_offsetof ($4, $7); }
663
664 sizeofExpr
665  : IsType { context_setProtectVars (); } 
666    sizeofExprAux { context_sizeofReleaseVars (); $$ = $3; }
667
668 sizeofExprAux 
669  : CSIZEOF TLPAREN typeExpression TRPAREN { $$ = exprNode_sizeofType ($3); } 
670  | CSIZEOF unaryExpr                      { $$ = exprNode_sizeofExpr ($2); }
671  | CALIGNOF TLPAREN typeExpression TRPAREN { $$ = exprNode_alignofType ($3); } 
672  | CALIGNOF unaryExpr                      { $$ = exprNode_alignofExpr ($2); }
673  
674 castExpr
675  : unaryExpr 
676  | TLPAREN typeExpression TRPAREN castExpr 
677    { $$ = exprNode_cast ($1, $4, $2); } 
678  
679 timesExpr
680  : castExpr 
681  | timesExpr TMULT castExpr { $$ = exprNode_op ($1, $3, $2); }
682  | timesExpr TDIV castExpr { $$ = exprNode_op ($1, $3, $2); }
683  | timesExpr TPERCENT castExpr { $$ = exprNode_op ($1, $3, $2); }
684
685 plusExpr
686  : timesExpr 
687  | plusExpr TPLUS timesExpr { $$ = exprNode_op ($1, $3, $2); }
688  | plusExpr TMINUS timesExpr { $$ = exprNode_op ($1, $3, $2); }
689
690 shiftExpr
691  : plusExpr 
692  | shiftExpr LEFT_OP plusExpr { $$ = exprNode_op ($1, $3, $2); }
693  | shiftExpr RIGHT_OP plusExpr { $$ = exprNode_op ($1, $3, $2); }
694
695 relationalExpr
696  : shiftExpr 
697  | relationalExpr TLT shiftExpr { $$ = exprNode_op ($1, $3, $2); }
698  | relationalExpr TGT shiftExpr { $$ = exprNode_op ($1, $3, $2); }
699  | relationalExpr LE_OP shiftExpr { $$ = exprNode_op ($1, $3, $2); }
700  | relationalExpr GE_OP shiftExpr { $$ = exprNode_op ($1, $3, $2); }
701  
702 equalityExpr 
703  : relationalExpr 
704  | equalityExpr EQ_OP relationalExpr { $$ = exprNode_op ($1, $3, $2); }
705  | equalityExpr NE_OP relationalExpr { $$ = exprNode_op ($1, $3, $2); }
706
707 bitandExpr
708  : equalityExpr 
709  | bitandExpr TAMPERSAND equalityExpr { $$ = exprNode_op ($1, $3, $2); }
710
711 xorExpr
712  : bitandExpr 
713  | xorExpr TCIRC bitandExpr { $$ = exprNode_op ($1, $3, $2); }
714
715
716 bitorExpr
717  : xorExpr 
718  | bitorExpr TBAR xorExpr { $$ = exprNode_op ($1, $3, $2); }
719
720 andExpr 
721  : bitorExpr 
722  | andExpr AND_OP 
723    { exprNode_produceGuards ($1); 
724      context_enterAndClause ($1); 
725    } 
726    bitorExpr 
727    { 
728      $$ = exprNode_op ($1, $4, $2); 
729      context_exitAndClause ($$, $4);
730    }
731
732 orExpr
733  : andExpr 
734  | orExpr OR_OP 
735    { 
736      exprNode_produceGuards ($1);
737      context_enterOrClause ($1); 
738    } 
739    andExpr 
740    { 
741      $$ = exprNode_op ($1, $4, $2); 
742      context_exitOrClause ($$, $4);
743    }
744
745 conditionalExpr 
746  : orExpr 
747  | orExpr TQUEST { exprNode_produceGuards ($1); context_enterTrueClause ($1); } expr TCOLON 
748    { context_enterFalseClause ($1); } conditionalExpr
749    { $$ = exprNode_cond ($1, $4, $7); context_exitClause ($1, $4, $7); }
750
751 assignExpr
752  : conditionalExpr 
753  | unaryExpr TASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
754  | unaryExpr MUL_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
755  | unaryExpr DIV_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
756  | unaryExpr MOD_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
757  | unaryExpr ADD_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
758  | unaryExpr SUB_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
759  | unaryExpr LEFT_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
760  | unaryExpr RIGHT_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
761  | unaryExpr AND_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
762  | unaryExpr XOR_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
763  | unaryExpr OR_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
764
765 expr
766  : assignExpr 
767  | expr TCOMMA assignExpr { $$ = exprNode_comma ($1, $3); } 
768
769 optExpr
770  : /* empty */ { $$ = exprNode_undefined; }
771  | expr 
772
773 constantExpr
774  : conditionalExpr 
775
776 /* instance_orTypeDecl_and_possible_initialization */
777
778 initializer
779  : instanceDecl { $$ = $1; }
780  | VA_DCL       { doVaDcl (); $$ = exprNode_makeError (); } 
781  | typeDecl     { $$ = exprNode_makeError (); }
782
783 instanceDecl
784  : completeTypeSpecifier IsType TSEMI { $$ = exprNode_makeError (); }
785     /*
786      ** This causes r/r conflicts with function definitions.
787      ** Instead we need to snarf one first. (gack)
788      **
789      ** | completeTypeSpecifier { setProcessingVars ($1); } 
790      ** NotType 
791      ** namedInitializerList IsType TSEMI 
792      ** { unsetProcessingVars (); }
793      **;
794      **
795      ** the solution is pretty ugly:
796      */
797  | completeTypeSpecifier NotType namedDecl NotType 
798    {
799                setProcessingVars ($1); 
800      processNamedDecl ($3); }
801    IsType optDeclarators TSEMI IsType { unsetProcessingVars (); $$ = $7; }
802  | completeTypeSpecifier NotType namedDecl NotType TASSIGN 
803    { setProcessingVars ($1); processNamedDecl ($3); 
804         }
805    IsType init optDeclarators TSEMI IsType 
806    { $$ = exprNode_concat ($9, exprNode_makeInitialization ($3, $8)); 
807      unsetProcessingVars ();
808    }
809 namedInitializer
810  : namedDecl NotType { processNamedDecl ($1); $$ = exprNode_makeError (); }
811  | namedDecl NotType TASSIGN { processNamedDecl ($1); } IsType init
812    { $$ = exprNode_makeInitialization ($1, $6); }
813
814
815 typeDecl
816  : CTYPEDEF completeTypeSpecifier { setProcessingTypedef ($2); } 
817    NotType namedInitializerList IsType TSEMI { unsetProcessingTypedef (); } 
818  | CTYPEDEF completeTypeSpecifier IsType TSEMI { /* in the ANSI grammar, semantics unclear */ }
819  | CTYPEDEF namedInitializerList IsType TSEMI { /* in the ANSI grammar, semantics unclear */ } 
820
821 IsType
822  : { g_expectingTypeName = TRUE; }
823
824 PushType
825  : { g_expectingTypeName = TRUE; context_pushLoc (); }
826
827 namedInitializerList
828  :  namedInitializerListAux IsType { ; }
829
830 namedInitializerListAux
831  : namedInitializer { ; }
832  | namedInitializerList TCOMMA NotType namedInitializer { ; }
833
834 optDeclarators
835  : /* empty */      { $$ = exprNode_makeError (); }
836  | optDeclarators TCOMMA NotType namedInitializer { $$ = exprNode_concat ($1, $4); }
837
838 init
839  : assignExpr                      
840  | TLBRACE initList TRBRACE        { $$ = exprNode_makeInitBlock ($1, $2); }
841  | TLBRACE initList TCOMMA TRBRACE { $$ = exprNode_makeInitBlock ($1, $2); }
842
843
844 initList
845  : init 
846    { $$ = exprNodeList_singleton ($1); }
847  | initList TCOMMA init 
848    { $$ = exprNodeList_push ($1, $3); }
849
850 /*
851 ** need to do the storage class global hack so tags are
852 ** declared with the right storage class.
853 */
854
855 storageSpecifier
856  : QEXTERN   { setStorageClass (SCEXTERN); $$ = qual_createExtern (); }
857  | QINLINE   { $$ = qual_createInline (); }
858  | QSTATIC   { setStorageClass (SCSTATIC); $$ = qual_createStatic (); }
859  | QAUTO     { $$ = qual_createAuto (); }
860  | QREGISTER { $$ = qual_createRegister (); }
861
862 typeQualifier
863  : QCONST IsType       { $$ = qual_createConst (); }
864  | QVOLATILE IsType    { $$ = qual_createVolatile (); }
865  | QOUT IsType         { $$ = qual_createOut (); }
866  | QIN IsType          { $$ = qual_createIn (); }
867  | QPARTIAL IsType     { $$ = qual_createPartial (); }
868  | QSPECIAL IsType     { $$ = qual_createSpecial (); }
869  | QOWNED IsType       { $$ = qual_createOwned (); }
870  | QDEPENDENT IsType   { $$ = qual_createDependent (); }
871  | QYIELD IsType       { $$ = qual_createYield (); }
872  | QTEMP IsType        { $$ = qual_createTemp (); }
873  | QONLY IsType        { $$ = qual_createOnly (); }
874  | QKEEP IsType        { $$ = qual_createKeep (); }
875  | QKEPT IsType        { $$ = qual_createKept (); }
876  | QSHARED IsType      { $$ = qual_createShared (); }
877  | QUNIQUE IsType      { $$ = qual_createUnique (); }
878  | QEXITS IsType       { $$ = qual_createExits (); }
879  | QMAYEXIT IsType     { $$ = qual_createMayExit (); }
880  | QTRUEEXIT IsType    { $$ = qual_createTrueExit (); }
881  | QFALSEEXIT IsType   { $$ = qual_createFalseExit (); }
882  | QNEVEREXIT IsType   { $$ = qual_createNeverExit (); }
883  | QNULL IsType        { $$ = qual_createNull (); }
884  | QRELNULL IsType     { $$ = qual_createRelNull (); }
885  | QRETURNED IsType    { $$ = qual_createReturned (); }
886  | QEXPOSED IsType     { $$ = qual_createExposed (); }
887  | QOBSERVER IsType    { $$ = qual_createObserver (); }
888  | QCHECKED IsType     { $$ = qual_createChecked (); }
889  | QCHECKMOD IsType    { $$ = qual_createCheckMod (); }
890  | QUNCHECKED IsType   { $$ = qual_createUnchecked (); }
891  | QCHECKEDSTRICT IsType  { $$ = qual_createCheckedStrict (); }
892  | QTRUENULL IsType    { $$ = qual_createTrueNull (); }
893  | QFALSENULL IsType   { $$ = qual_createFalseNull (); }
894  | QUNUSED IsType      { $$ = qual_createUnused (); }
895  | QEXTERNAL IsType    { $$ = qual_createExternal (); }
896  | QSEF IsType         { $$ = qual_createSef (); }
897  | QABSTRACT IsType    { $$ = qual_createAbstract (); }
898  | QCONCRETE IsType    { $$ = qual_createConcrete (); }
899  | QMUTABLE IsType     { $$ = qual_createMutable (); }
900  | QIMMUTABLE IsType   { $$ = qual_createImmutable (); }
901  | QNOTNULL IsType     { $$ = qual_createNotNull (); }
902  | QREFCOUNTED IsType  { $$ = qual_createRefCounted (); }
903  | QREFS IsType        { $$ = qual_createRefs (); }
904  | QKILLREF IsType     { $$ = qual_createKillRef (); }
905  | QRELDEF IsType      { $$ = qual_createRelDef (); }
906  | QNEWREF IsType      { $$ = qual_createNewRef (); }
907  | QTEMPREF IsType     { $$ = qual_createTempRef (); }
908
909 typeModifier
910  : QSHORT            { $$ = qual_createShort (); }
911  | QLONG             { $$ = qual_createLong (); }
912  | QSIGNED           { $$ = qual_createSigned (); }
913  | QUNSIGNED         { $$ = qual_createUnsigned (); }
914
915 typeSpecifier
916  : CGCHAR NotType 
917  | CINT NotType 
918  | CBOOL NotType
919  | CGFLOAT NotType
920  | CDOUBLE NotType
921  | CVOID NotType 
922  | QANYTYPE NotType              { $$ = ctype_unknown; }
923  | QINTEGRALTYPE NotType         { $$ = ctype_anyintegral; }
924  | QUNSIGNEDINTEGRALTYPE NotType { $$ = ctype_unsignedintegral; }
925  | QSIGNEDINTEGRALTYPE NotType   { $$ = ctype_signedintegral; }
926  | typeName NotType     
927  | suSpc NotType 
928  | enumSpc NotType
929  | typeModifier NotType { $$ = ctype_fromQual ($1); }
930
931 completeType
932  : IsType completeTypeSpecifier IsType
933    { $$ = qtype_resolve ($2); }
934
935 completeTypeSpecifier
936  : completeTypeSpecifierAux { $$ = $1; }
937  | completeTypeSpecifierAux QALT altType QENDMACRO  
938    { $$ = qtype_mergeAlt ($1, $3); }
939
940 altType
941  : typeExpression
942  | typeExpression TCOMMA altType
943    { $$ = qtype_mergeAlt ($1, $3); } 
944
945 completeTypeSpecifierAux
946  : storageSpecifier optCompleteType        { $$ = qtype_addQual ($2, $1); }
947  | typeQualifier optCompleteType           { $$ = qtype_addQual ($2, $1); } 
948  | typeSpecifier optCompleteType           { $$ = qtype_combine ($2, $1); }
949
950 optCompleteType
951  : /* empty */                             { $$ = qtype_unknown (); }
952  | completeTypeSpecifier                   { $$ = $1; }
953
954 suSpc
955  : NotType CSTRUCT newId IsType TLBRACE { sRef_setGlobalScopeSafe (); } 
956    CreateStructInnerScope 
957    structDeclList DeleteStructInnerScope { sRef_clearGlobalScopeSafe (); }
958    TRBRACE 
959    { $$ = declareStruct ($3, $8); }
960  | NotType CUNION  newId IsType TLBRACE { sRef_setGlobalScopeSafe (); } 
961    CreateStructInnerScope 
962    structDeclList DeleteStructInnerScope { sRef_clearGlobalScopeSafe (); } 
963    TRBRACE
964    { $$ = declareUnion ($3, $8); } 
965  | NotType CSTRUCT newId IsType TLBRACE TRBRACE 
966    { $$ = declareStruct ($3, uentryList_new ()); }
967  | NotType CUNION  newId IsType TLBRACE TRBRACE 
968    { $$ = declareUnion ($3, uentryList_new ()); }
969  | NotType CSTRUCT IsType TLBRACE { sRef_setGlobalScopeSafe (); } 
970    CreateStructInnerScope 
971    structDeclList DeleteStructInnerScope { sRef_clearGlobalScopeSafe (); }
972    TRBRACE 
973    { $$ = declareUnnamedStruct ($7); }
974  | NotType CUNION  IsType TLBRACE { sRef_setGlobalScopeSafe (); } 
975    CreateStructInnerScope 
976    structDeclList DeleteStructInnerScope { sRef_clearGlobalScopeSafe (); }
977    TRBRACE 
978    { $$ = declareUnnamedUnion ($7); } 
979  | NotType CSTRUCT IsType TLBRACE TRBRACE
980    { $$ = ctype_createUnnamedStruct (uentryList_new ()); }
981  | NotType CUNION  IsType TLBRACE TRBRACE 
982    { $$ = ctype_createUnnamedUnion (uentryList_new ()); } 
983  | NotType CSTRUCT newId NotType { $$ = handleStruct ($3); } 
984  | NotType CUNION  newId NotType { $$ = handleUnion ($3); }
985
986 NotType
987  : { g_expectingTypeName = FALSE; }
988
989 structDeclList
990  : structDecl 
991  | macroDef { $$ = uentryList_undefined; /* bogus! */ }
992  | structDeclList structDecl { $$ = uentryList_mergeFields ($1, $2); }
993
994 structDecl
995  : completeTypeSpecifier NotType structNamedDeclList IsType TSEMI 
996    { $$ = fixUentryList ($3, $1); }
997  | completeTypeSpecifier IsType TSEMI 
998    { $$ = fixUnnamedDecl ($1); }
999
1000 structNamedDeclList 
1001  : structNamedDecl NotType                            
1002    { $$ = idDeclList_singleton ($1); }
1003  | structNamedDeclList TCOMMA structNamedDecl NotType
1004    { $$ = idDeclList_add ($1, $3); }
1005
1006 structNamedDecl  /* hack to get around namespace problems */ 
1007  : namedDecl                            { $$ = $1; }
1008  | TCOLON IsType constantExpr           { $$ = idDecl_undefined; }
1009  | namedDecl TCOLON IsType constantExpr { $$ = $1; }
1010    /* Need the IsType in case there is a cast in the constant expression. */
1011
1012 enumSpc
1013  : NotType CENUM TLBRACE enumeratorList TRBRACE IsType 
1014    { $$ = declareUnnamedEnum ($4); }
1015  | NotType CENUM newId TLBRACE { context_pushLoc (); } enumeratorList TRBRACE IsType
1016    { context_popLoc (); $$ = declareEnum ($3, $6); }
1017  | NotType CENUM newId IsType { $$ = handleEnum ($3); }
1018
1019 enumeratorList
1020  : enumerator 
1021    { $$ = enumNameList_single ($1); }
1022  | enumeratorList TCOMMA enumerator 
1023    { $$ = enumNameList_push ($1, $3); }
1024  | enumeratorList TCOMMA
1025
1026 enumerator
1027  : newId 
1028    { uentry ue = uentry_makeEnumConstant ($1, ctype_unknown);
1029      usymtab_supGlobalEntry (ue);
1030      $$ = $1;
1031    }
1032  | newId TASSIGN IsType constantExpr 
1033    { uentry ue = uentry_makeEnumInitializedConstant ($1, ctype_unknown, $4);
1034      usymtab_supGlobalEntry (ue);
1035      $$ = $1; 
1036    }
1037
1038 optNamedDecl
1039  : namedDeclBase
1040  | optAbstractDeclBase   { $$ = idDecl_create (cstring_undefined, qtype_create ($1)); }
1041  | pointers TYPE_NAME    
1042    { 
1043      qtype qt = qtype_unknown ();
1044
1045      qtype_adjustPointers ($1, qt);
1046      $$ = idDecl_create (cstring_copy (LastIdentifier ()), qt);
1047    }
1048  | pointers optNamedDecl 
1049    { $$ = $2; qtype_adjustPointers ($1, idDecl_getTyp ($$)); }
1050
1051 namedDecl
1052  : namedDeclBase
1053  | pointers namedDeclBase 
1054    { $$ = $2; qtype_adjustPointers ($1, idDecl_getTyp ($$)); }
1055
1056 genericParamList
1057  : paramTypeList       { $$ = handleParamTypeList ($1); }
1058  | NotType paramIdList { $$ = handleParamIdList ($2); }  
1059
1060 innerMods
1061  : QCONST    { /* ignored for now */; }
1062  | QVOLATILE { ; }
1063
1064 innerModsList
1065  : innerMods { ; }
1066  | innerModsList innerMods { ; }
1067
1068 pointers
1069  : TMULT { $$ = 1; }
1070  | TMULT innerModsList { $$ = 1; }
1071  | TMULT pointers { $$ = 1 + $2; }
1072  | TMULT innerModsList pointers { $$ = 1 + $3; }
1073
1074 paramIdList
1075  : idList 
1076  | idList TCOMMA CTOK_ELIPSIS { $$ = uentryList_add ($1, uentry_makeElipsisMarker ()); }
1077
1078 idList
1079  : newId { $$ = uentryList_single (uentry_makeVariableLoc ($1, ctype_int)); }
1080  | idList TCOMMA newId { $$ = uentryList_add ($1, uentry_makeVariableLoc ($3, ctype_int)); }
1081
1082 paramTypeList
1083  : CTOK_ELIPSIS { $$ = uentryList_single (uentry_makeElipsisMarker ()); }
1084  | paramList 
1085  | paramList TCOMMA CTOK_ELIPSIS { $$ = uentryList_add ($1, uentry_makeElipsisMarker ()); }
1086
1087 paramList
1088  : { storeLoc (); } paramDecl { $$ = uentryList_single ($2); }
1089  | paramList TCOMMA { storeLoc (); } paramDecl 
1090    { $$ = uentryList_add ($1, $4); }
1091
1092 paramDecl
1093  : IsType completeTypeSpecifier optNamedDecl IsType
1094    { 
1095      if (isFlipOldStyle ()) 
1096        { 
1097          llparseerror (cstring_makeLiteral ("Inconsistent function parameter syntax (mixing old and new style declaration)")); 
1098        }
1099      else 
1100        { 
1101          setNewStyle (); 
1102        }
1103      $$ = makeCurrentParam (idDecl_fixParamBase ($3, $2)); 
1104    }
1105  | newId /* its an old-style declaration */
1106    { 
1107      idDecl tparam = idDecl_create ($1, qtype_unknown ());
1108
1109      if (isNewStyle ()) 
1110        {
1111          llparseerror (message ("Inconsistent function parameter syntax: %q",
1112                                 idDecl_unparse (tparam))); 
1113        }
1114
1115      setFlipOldStyle ();
1116      $$ = makeCurrentParam (tparam);
1117      idDecl_free (tparam);
1118    } 
1119
1120 typeExpression
1121  : completeType
1122  | completeType abstractDecl  { $$ = qtype_newBase ($1, $2); }
1123
1124 abstractDecl
1125  : pointers { $$ = ctype_adjustPointers ($1, ctype_unknown); }
1126  | abstractDeclBase
1127  | pointers abstractDeclBase { $$ = ctype_adjustPointers ($1, $2); }
1128
1129 optAbstractDeclBase
1130  : /* empty */ { $$ = ctype_unknown; }
1131  | abstractDeclBase 
1132
1133 abstractDeclBase
1134  : IsType TLPAREN NotType abstractDecl TRPAREN 
1135    { $$ = ctype_expectFunction ($4); }
1136  | TLSQBR TRSQBR { $$ = ctype_makeArray (ctype_unknown); }
1137  | TLSQBR constantExpr TRSQBR { $$ = ctype_makeArray (ctype_unknown); }
1138  | abstractDeclBase TLSQBR TRSQBR { $$ = ctype_makeArray ($1); }
1139  | abstractDeclBase TLSQBR constantExpr TRSQBR { $$ = ctype_makeArray ($1); }
1140  | IsType TLPAREN TRPAREN 
1141    { $$ = ctype_makeFunction (ctype_unknown, uentryList_makeMissingParams ()); }
1142  | IsType TLPAREN paramTypeList TRPAREN 
1143    { $$ = ctype_makeParamsFunction (ctype_unknown, $3); }
1144  | abstractDeclBase IsType TLPAREN TRPAREN 
1145    { $$ = ctype_makeFunction ($1, uentryList_makeMissingParams ()); }  
1146  | abstractDeclBase IsType TLPAREN paramTypeList TRPAREN 
1147    { $$ = ctype_makeParamsFunction ($1, $4); }  
1148
1149 /* statement */
1150
1151 stmt
1152  : labeledStmt 
1153  | caseStmt 
1154  | defaultStmt
1155  | compoundStmt 
1156  | expressionStmt
1157  | selectionStmt 
1158  | iterationStmt 
1159  | iterStmt
1160  | jumpStmt 
1161
1162 iterBody
1163  : iterDefStmtList { $$ = $1; }
1164
1165 endBody
1166  : iterBody
1167
1168 iterDefStmtList
1169  : iterDefStmt                 
1170  | iterDefStmtList iterDefStmt 
1171    { $$ = exprNode_concat ($1, $2); }
1172
1173 iterDefIterationStmt
1174  : iterWhilePred iterDefStmtList         
1175    { $$ = exprNode_while ($1, $2); }
1176  | doHeader stmtErr WHILE TLPAREN expr TRPAREN TSEMI 
1177    { $$ = exprNode_doWhile ($2, $5); }
1178  | doHeader stmtErr WHILE TLPAREN expr TRPAREN
1179    { $$ = exprNode_doWhile ($2, $5); }
1180  | forPred iterDefStmt
1181    { $$ = exprNode_for ($1, $2); } 
1182
1183 forPred
1184  : CFOR TLPAREN optExpr TSEMI optExpr TSEMI 
1185    { context_setProtectVars (); } optExpr { context_sizeofReleaseVars (); }
1186    TRPAREN 
1187    { $$ = exprNode_forPred ($3, $5, $8); 
1188      context_enterForClause ($5); }
1189
1190 partialIterStmt
1191  : ITER_NAME CreateInnerScope TLPAREN 
1192    { setProcessingIterVars ($1); } 
1193    iterArgList TRPAREN 
1194    { $$ = exprNode_iterStart ($1, $5); }
1195  | ITER_ENDNAME { $$ = exprNode_createId ($1); }
1196
1197 iterDefStmt
1198  : labeledStmt 
1199  | caseStmt 
1200  | defaultStmt
1201  | openScope initializerList { $$ = $2; }
1202  | openScope
1203  | closeScope
1204  | expressionStmt
1205  | iterSelectionStmt 
1206  | iterDefIterationStmt 
1207  | partialIterStmt
1208  | jumpStmt 
1209  | TLPAREN iterDefStmt TRPAREN { $$ = $2; }
1210  | error { $$ = exprNode_makeError (); }
1211
1212 iterSelectionStmt
1213  : ifPred iterDefStmt 
1214    { /* don't: context_exitTrueClause ($1, $2); */
1215      $$ = exprNode_if ($1, $2); 
1216    }
1217
1218 openScope
1219  : CreateInnerScope TLBRACE { $$ = exprNode_createTok ($2); }
1220
1221 closeScope
1222  : DeleteInnerScopeSafe TRBRACE { $$ = exprNode_createTok ($2); }
1223
1224 macroBody
1225  : stmtErr    
1226  | stmtListErr
1227  
1228 stmtErr
1229  : labeledStmt
1230  | caseStmt 
1231  | defaultStmt 
1232  | compoundStmtErr
1233  | expressionStmtErr
1234  | selectionStmt 
1235  | iterStmt
1236  | iterationStmtErr
1237  | TLPAREN stmtErr TRPAREN { $$ = exprNode_addParens ($1, $2); }
1238  | jumpStmt 
1239  | error { $$ = exprNode_makeError (); }
1240
1241 labeledStmt
1242  : newId TCOLON      { $$ = exprNode_labelMarker ($1); }
1243  | QNOTREACHED stmt  { $$ = exprNode_notReached ($2); }
1244
1245 /* Note that we can semantically check that the object to the case is
1246  indeed constant. In this case, we may not want to go through this effort */
1247
1248 caseStmt
1249  : CASE constantExpr { context_enterCaseClause ($2); } 
1250    TCOLON            { $$ = exprNode_caseMarker ($2, FALSE); }
1251  | QFALLTHROUGH CASE constantExpr { context_enterCaseClause ($3); } 
1252    TCOLON            { $$ = exprNode_caseMarker ($3, TRUE); }
1253
1254 defaultStmt
1255  : DEFAULT { context_enterCaseClause (exprNode_undefined); } 
1256    TCOLON { $$ = exprNode_defaultMarker ($1, FALSE); }
1257  | QFALLTHROUGH DEFAULT { context_enterCaseClause (exprNode_undefined); } 
1258    TCOLON { $$ = exprNode_defaultMarker ($2, TRUE); }
1259
1260 compoundStmt
1261  : TLPAREN compoundStmt TRPAREN { $$ = $2; }
1262  | CreateInnerScope compoundStmtAux 
1263    { $$ = $2; context_exitInner ($2); }
1264
1265 compoundStmtErr
1266  : CreateInnerScope compoundStmtAuxErr DeleteInnerScope { $$ = $2; }
1267
1268 CreateInnerScope
1269  : { context_enterInnerContext (); }
1270
1271 DeleteInnerScope
1272  : { context_exitInnerPlain (); }
1273
1274 CreateStructInnerScope
1275  : { context_enterStructInnerContext (); }
1276
1277 DeleteStructInnerScope
1278  : { context_exitStructInnerContext (); }
1279
1280 DeleteInnerScopeSafe
1281  : { context_exitInnerSafe (); }
1282
1283 compoundStmtRest
1284  : TRBRACE { $$ = exprNode_createTok ($1); }
1285  | QNOTREACHED TRBRACE { $$ = exprNode_notReached (exprNode_createTok ($2)); }
1286  | stmtList TRBRACE { $$ = exprNode_updateLocation ($1, lltok_getLoc ($2)); }
1287  | stmtList QNOTREACHED TRBRACE 
1288    { $$ = exprNode_notReached (exprNode_updateLocation ($1, lltok_getLoc ($3))); }
1289  | initializerList TRBRACE { $$ = exprNode_updateLocation ($1, lltok_getLoc ($2)); }
1290  | initializerList QNOTREACHED TRBRACE 
1291    { $$ = exprNode_notReached (exprNode_updateLocation ($1, lltok_getLoc ($3))); }
1292  | initializerList stmtList TRBRACE
1293    { $$ = exprNode_updateLocation (exprNode_concat ($1, $2), lltok_getLoc ($3)); }
1294  | initializerList stmtList QNOTREACHED TRBRACE
1295    { $$ = exprNode_notReached (exprNode_updateLocation (exprNode_concat ($1, $2), 
1296                                                         lltok_getLoc ($3))); 
1297    }
1298
1299
1300 compoundStmtAux
1301  : TLBRACE compoundStmtRest 
1302    { $$ = exprNode_makeBlock ($2); }
1303
1304 compoundStmtAuxErr
1305  : TLBRACE TRBRACE 
1306    { $$ = exprNode_createTok ($2); }
1307  | TLBRACE stmtListErr TRBRACE 
1308    { $$ = exprNode_updateLocation ($2, lltok_getLoc ($3)); }
1309  | TLBRACE initializerList TRBRACE 
1310    { $$ = exprNode_updateLocation ($2, lltok_getLoc ($3)); }
1311  | TLBRACE initializerList stmtList TRBRACE 
1312    { $$ = exprNode_updateLocation (exprNode_concat ($2, $3), lltok_getLoc ($4)); }
1313
1314 stmtListErr
1315  : stmtErr 
1316  | stmtListErr stmtErr { $$ = exprNode_concat ($1, $2); }
1317
1318 initializerList
1319  : initializer { $$ = $1; }
1320  | initializerList initializer { $$ = exprNode_concat ($1, $2); }
1321
1322 stmtList
1323  : stmt { $$ = $1; }
1324  | stmtList stmt { $$ = exprNode_concat ($1, $2); }
1325  
1326 expressionStmt 
1327  : TSEMI { $$ = exprNode_createTok ($1); }
1328  | expr TSEMI { $$ = exprNode_statement ($1); }
1329
1330 expressionStmtErr
1331  : TSEMI { $$ = exprNode_createTok ($1); }
1332  | expr TSEMI { $$ = exprNode_statement ($1); }
1333  | expr { $$ = exprNode_checkExpr ($1); } 
1334
1335 ifPred
1336  : CIF TLPAREN expr TRPAREN 
1337    { $$ = $3; exprNode_produceGuards ($3); context_enterTrueClause ($3); }
1338  /*
1339  ** not ANSI: | CIF TLPAREN compoundStmt TRPAREN 
1340  **             { $$ = $3; context_enterTrueClause (); } 
1341  */
1342
1343 selectionStmt
1344  : ifPred stmt 
1345    { 
1346      context_exitTrueClause ($1, $2);
1347      $$ = exprNode_if ($1, $2); 
1348    }
1349  | ifPred stmt CELSE { context_enterFalseClause ($1); } stmt 
1350    {
1351      context_exitClause ($1, $2, $5);
1352      $$ = exprNode_ifelse ($1, $2, $5); 
1353    }
1354  | SWITCH TLPAREN expr { context_enterSwitch ($3); } 
1355    TRPAREN stmt        { $$ = exprNode_switch ($3, $6); }
1356  
1357 whilePred
1358  : WHILE TLPAREN expr TRPAREN 
1359    { $$ = exprNode_whilePred ($3); context_enterWhileClause ($3); }
1360    /* not ANSI: | WHILE TLPAREN compoundStmt TRPAREN stmt { $$ = exprNode_while ($3, $5); } */
1361
1362 iterWhilePred
1363  : WHILE TLPAREN expr TRPAREN { $$ = exprNode_whilePred($3); }
1364
1365 iterStmt
1366  : ITER_NAME { context_enterIterClause (); } 
1367    CreateInnerScope TLPAREN { setProcessingIterVars ($1); } 
1368    iterArgList TRPAREN 
1369    compoundStmt endIter DeleteInnerScope
1370    { 
1371      $$ = exprNode_iter ($1, $6, $8, $9); 
1372
1373    } 
1374  
1375 iterArgList 
1376  : iterArgExpr { $$ = exprNodeList_singleton ($1); }
1377  | iterArgList { nextIterParam (); } TCOMMA iterArgExpr 
1378    { $$ = exprNodeList_push ($1, $4); }
1379
1380 iterArgExpr
1381   : assignIterExpr  { $$ = exprNode_iterExpr ($1); }
1382   | id              { $$ = exprNode_iterId ($1); }
1383   | TYPE_NAME_OR_ID { uentry ue = coerceIterId ($1);
1384
1385                       if (uentry_isValid (ue)) 
1386                         {
1387                           $$ = exprNode_iterId (ue);
1388                         }
1389                       else
1390                         {
1391                           $$ = exprNode_iterNewId (cstring_copy (LastIdentifier ()));
1392                         }
1393                     }
1394   | NEW_IDENTIFIER  { $$ = exprNode_iterNewId ($1); }
1395
1396 /*
1397 ** everything is the same, EXCEPT it cannot be a NEW_IDENTIFIER 
1398 */
1399
1400 primaryIterExpr
1401  : CCONSTANT 
1402  | TLPAREN expr TRPAREN { $$ = exprNode_addParens ($1, $2); }
1403  
1404 postfixIterExpr
1405  : primaryIterExpr 
1406  | postfixExpr TLSQBR expr TRSQBR { $$ = exprNode_arrayFetch ($1, $3); }
1407  | postfixExpr TLPAREN TRPAREN { $$ = exprNode_functionCall ($1, exprNodeList_new ()); }
1408  | postfixExpr TLPAREN argumentExprList TRPAREN { $$ = exprNode_functionCall ($1, $3); }
1409  | VA_ARG TLPAREN assignExpr TCOMMA typeExpression TRPAREN
1410        { $$ = exprNode_vaArg ($1, $3, $5); }
1411  | postfixExpr NotType TDOT newId IsType { $$ = exprNode_fieldAccess ($1, $4); }
1412  | postfixExpr NotType ARROW_OP newId IsType { $$ = exprNode_arrowAccess ($1, $4); }
1413  | postfixExpr INC_OP { $$ = exprNode_postOp ($1, $2); }
1414  | postfixExpr DEC_OP { $$ = exprNode_postOp ($1, $2); }
1415  
1416 unaryIterExpr
1417  : postfixIterExpr 
1418  | INC_OP unaryExpr    { $$ = exprNode_preOp ($2, $1); }
1419  | DEC_OP unaryExpr    { $$ = exprNode_preOp ($2, $1); }
1420  | TAMPERSAND castExpr { $$ = exprNode_preOp ($2, $1); }
1421  | TMULT castExpr      { $$ = exprNode_preOp ($2, $1); }
1422  | TPLUS castExpr      { $$ = exprNode_preOp ($2, $1); }
1423  | TMINUS castExpr     { $$ = exprNode_preOp ($2, $1); }
1424  | TTILDE castExpr     { $$ = exprNode_preOp ($2, $1); }
1425  | TEXCL castExpr      { $$ = exprNode_preOp ($2, $1); }
1426  | sizeofExpr          { $$ = $1; }
1427
1428 castIterExpr
1429  : unaryIterExpr 
1430  | TLPAREN typeExpression TRPAREN castExpr { $$ = exprNode_cast ($1, $4, $2); } 
1431  
1432 timesIterExpr
1433  : castIterExpr 
1434  | timesExpr TMULT castExpr { $$ = exprNode_op ($1, $3, $2); }
1435  | timesExpr TDIV castExpr { $$ = exprNode_op ($1, $3, $2); }
1436  | timesExpr TPERCENT castExpr { $$ = exprNode_op ($1, $3, $2); }
1437
1438 plusIterExpr
1439  : timesIterExpr 
1440  | plusExpr TPLUS timesExpr { $$ = exprNode_op ($1, $3, $2); }
1441  | plusExpr TMINUS timesExpr { $$ = exprNode_op ($1, $3, $2); }
1442
1443 shiftIterExpr
1444  : plusIterExpr 
1445  | shiftExpr LEFT_OP plusExpr { $$ = exprNode_op ($1, $3, $2); }
1446  | shiftExpr RIGHT_OP plusExpr { $$ = exprNode_op ($1, $3, $2); }
1447
1448 relationalIterExpr
1449  : shiftIterExpr 
1450  | relationalExpr TLT shiftExpr { $$ = exprNode_op ($1, $3, $2); }
1451  | relationalExpr TGT shiftExpr { $$ = exprNode_op ($1, $3, $2); }
1452  | relationalExpr LE_OP shiftExpr { $$ = exprNode_op ($1, $3, $2); }
1453  | relationalExpr GE_OP shiftExpr { $$ = exprNode_op ($1, $3, $2); }
1454  
1455 equalityIterExpr 
1456  : relationalIterExpr 
1457  | equalityExpr EQ_OP relationalExpr { $$ = exprNode_op ($1, $3, $2); }
1458  | equalityExpr NE_OP relationalExpr { $$ = exprNode_op ($1, $3, $2); }
1459
1460 bitandIterExpr
1461  : equalityIterExpr 
1462  | bitandExpr TAMPERSAND equalityExpr { $$ = exprNode_op ($1, $3, $2); }
1463
1464 xorIterExpr
1465  : bitandIterExpr 
1466  | xorExpr TCIRC bitandExpr { $$ = exprNode_op ($1, $3, $2); }
1467
1468
1469 bitorIterExpr
1470  : xorIterExpr 
1471  | bitorExpr TBAR xorExpr { $$ = exprNode_op ($1, $3, $2); }
1472
1473 andIterExpr 
1474  : bitorIterExpr 
1475  | andExpr AND_OP bitorExpr { $$ = exprNode_op ($1, $3, $2); }
1476
1477 orIterExpr
1478  : andIterExpr 
1479  | orExpr OR_OP andExpr { $$ = exprNode_op ($1, $3, $2); }
1480
1481 conditionalIterExpr 
1482  : orIterExpr 
1483  | orExpr TQUEST { context_enterTrueClause ($1); } 
1484    expr TCOLON { context_enterFalseClause ($1); } conditionalExpr
1485    { $$ = exprNode_cond ($1, $4, $7); }
1486
1487 assignIterExpr
1488  : conditionalIterExpr 
1489  | unaryExpr TASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
1490  | unaryExpr MUL_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
1491  | unaryExpr DIV_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
1492  | unaryExpr MOD_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
1493  | unaryExpr ADD_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
1494  | unaryExpr SUB_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
1495  | unaryExpr LEFT_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
1496  | unaryExpr RIGHT_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
1497  | unaryExpr AND_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
1498  | unaryExpr XOR_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
1499  | unaryExpr OR_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
1500
1501 endIter
1502  : ITER_ENDNAME { $$ = $1; }
1503  | /* empty */  { $$ = uentry_undefined; } 
1504
1505 doHeader
1506  : DO { context_enterDoWhileClause (); $$ = $1; }
1507   
1508 iterationStmt 
1509  : whilePred stmt 
1510    { $$ = exprNode_while ($1, $2); context_exitWhileClause ($1, $2); }
1511  | doHeader stmt WHILE TLPAREN expr TRPAREN TSEMI 
1512    { $$ = exprNode_statement (exprNode_doWhile ($2, $5)); }
1513  | forPred stmt 
1514    { $$ = exprNode_for ($1, $2); context_exitForClause ($1, $2); }
1515
1516 iterationStmtErr 
1517  : whilePred stmtErr { $$ = exprNode_while ($1, $2); context_exitWhileClause ($1, $2); }
1518  | doHeader stmtErr WHILE TLPAREN expr TRPAREN TSEMI
1519    { $$ = exprNode_statement (exprNode_doWhile ($2, $5)); }
1520  | doHeader stmtErr WHILE TLPAREN expr TRPAREN 
1521    { $$ = exprNode_doWhile ($2, $5); }
1522  | forPred stmtErr { $$ = exprNode_for ($1, $2); context_exitForClause ($1, $2); }
1523  
1524 jumpStmt
1525  : GOTO newId TSEMI         { $$ = exprNode_goto ($2); }
1526  | CONTINUE TSEMI           { $$ = exprNode_continue ($1, BADTOK); }
1527  | QINNERCONTINUE CONTINUE TSEMI    
1528                             { $$ = exprNode_continue ($1, QINNERCONTINUE); }
1529  | BREAK TSEMI              { $$ = exprNode_break ($1, BADTOK); }
1530  | QSWITCHBREAK BREAK TSEMI { $$ = exprNode_break ($2, QSWITCHBREAK); }
1531  | QLOOPBREAK BREAK TSEMI   { $$ = exprNode_break ($2, QLOOPBREAK); }
1532  | QINNERBREAK BREAK TSEMI  { $$ = exprNode_break ($2, QINNERBREAK); }
1533  | QSAFEBREAK BREAK TSEMI   { $$ = exprNode_break ($2, QSAFEBREAK); }
1534  | RETURN TSEMI             { $$ = exprNode_nullReturn ($1); }
1535  | RETURN expr TSEMI        { $$ = exprNode_return ($2); }
1536  
1537 optSemi
1538  : 
1539  | TSEMI { ; } 
1540
1541 id
1542  : IDENTIFIER 
1543
1544 newId
1545  : NEW_IDENTIFIER 
1546  | ITER_NAME       { $$ = uentry_getName ($1); }
1547  | ITER_ENDNAME    { $$ = uentry_getName ($1); }
1548  | id              { $$ = uentry_getName ($1); }
1549  | TYPE_NAME_OR_ID { $$ = $1; } 
1550
1551 typeName
1552  : TYPE_NAME
1553  | TYPE_NAME_OR_ID { $$ = ctype_unknown; }
1554
1555 %%
1556
1557 /*@-redecl@*/
1558 extern char *yytext;
1559 /*@=redecl@*/
1560
1561 # include "bison.reset"
1562
1563 void yyerror (/*@unused@*/ char *s) 
1564 {
1565   static bool givehint = FALSE;
1566
1567   if (context_inIterDef ())
1568     {
1569       llerror (FLG_SYNTAX, message ("Iter syntax not parseable: %s", 
1570                                     context_inFunctionName ()));
1571     }
1572   else if (context_inIterEnd ())
1573     {
1574       llerror (FLG_SYNTAX, message ("Iter finalizer syntax not parseable: %s", 
1575                                     context_inFunctionName ()));
1576     }
1577   else if (context_inMacro ())
1578     {
1579       llerror (FLG_SYNTAX, message ("Macro syntax not parseable: %s", 
1580                                     context_inFunctionName ()));
1581       
1582       if (context_inMacroUnknown ())
1583         {
1584           if (!givehint)
1585             {
1586               llhint (cstring_makeLiteral 
1587                      ("Precede macro definition with /*@notfunction@*/ "
1588                       "to suppress checking and force expansion"));
1589               givehint = TRUE;
1590             }
1591         }
1592
1593       swallowMacro ();
1594     }
1595   else
1596     {
1597       llparseerror (cstring_undefined);
1598     }
1599 }
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
This page took 0.956931 seconds and 5 git commands to generate.