]> andersk Git - splint.git/blob - src/cgrammar.y
Changed checking of complete descruction so +strictdestroy is no
[splint.git] / src / cgrammar.y
1 /*;-*-C-*-;
2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2001 University of Virginia,
4 **         Massachusetts Institute of Technology
5 **
6 ** This program is free software; you can redistribute it and/or modify it
7 ** under the terms of the GNU General Public License as published by the
8 ** Free Software Foundation; either version 2 of the License, or (at your
9 ** option) any later version.
10 ** 
11 ** This program is distributed in the hope that it will be useful, but
12 ** WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 ** General Public License for more details.
15 ** 
16 ** The GNU General Public License is available from http://www.gnu.org/ or
17 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 ** MA 02111-1307, USA.
19 **
20 ** For information on lclint: lclint-request@cs.virginia.edu
21 ** To report a bug: lclint-bug@cs.virginia.edu
22 ** For more information: http://www.splint.org
23 */
24 %{
25 /*
26 **
27 ** cgrammar.y
28 **
29 ** Yacc/Bison grammar for extended ANSI C used by LCLint.
30 **
31 ** original grammar by Nate Osgood ---
32 **    hacrat@catfish.lcs.mit.edu Mon Jun 14 13:06:32 1993
33 **
34 ** changes for LCLint --- handle typedef names correctly
35 ** fix struct/union parsing bug (empty struct is accepted)
36 ** add productions to handle macros --- require
37 ** error correction --- main source of conflicts in grammar.
38 ** need to process initializations sequentially, L->R
39 **
40 ** production names are cryptic, so more productions fit on one line
41 **
42 ** conflicts:  87 shift/reduce, 18 reduce/reduce
43 ** most of these are due to handling macros
44 ** a few are due to handling type expressions
45 */
46
47 /*@=allmacros@*/
48
49 extern int yylex ();
50 extern void swallowMacro (void);
51 extern void yyerror (char *);
52
53 # include "lclintMacros.nf"
54 # include "basic.h"
55 # include "cscanner.h"
56 # include "cgrammar.h"
57 # include "exprChecks.h"
58
59 /*@-allmacros@*/
60 /*@-matchfields@*/
61
62 # define SHOWCSYM FALSE
63
64 /*
65 ** This is necessary, or else when the bison-generated code #include's malloc.h,
66 ** there will be a parse error.
67 **
68 ** Unfortunately, it means the error checking on malloc, etc. is lost for allocations
69 ** in bison-generated files under Win32.
70 */
71
72 # ifdef WIN32
73 # undef malloc
74 # undef calloc
75 # undef realloc
76 # endif
77
78 %}
79
80 %union
81 {
82   lltok tok;
83   int count;
84   qual typequal;
85   qualList tquallist;
86   ctype ctyp;
87   /*@dependent@*/ sRef sr;
88   /*@only@*/ sRef osr;
89
90   /*@only@*/ functionClauseList funcclauselist;
91   /*@only@*/ functionClause funcclause;  
92   /*@only@*/ flagSpec flagspec;
93   /*@only@*/ globalsClause globsclause;
94   /*@only@*/ modifiesClause modsclause;
95   /*@only@*/ warnClause warnclause;
96   /*@only@*/ stateClause stateclause;
97
98   /*@only@*/ functionConstraint fcnconstraint; 
99
100   /*@only@*/ metaStateConstraint msconstraint;
101   /*@only@*/ metaStateSpecifier msspec;
102   /*@only@*/ metaStateExpression msexpr;
103   /*@observer@*/ metaStateInfo msinfo;
104
105   /*@only@*/ sRefList srlist;
106   /*@only@*/ globSet globset;
107   /*@only@*/ qtype qtyp;
108   /*@only@*/ cstring cname;
109   /*@observer@*/ annotationInfo annotation;
110   /*@only@*/ idDecl ntyp;
111   /*@only@*/ idDeclList ntyplist;
112   /*@only@*/ uentryList flist;
113   /*@owned@*/ uentryList entrylist;
114   /*@observer@*/ /*@dependent@*/ uentry entry;
115   /*@only@*/ uentry oentry;
116   /*@only@*/ exprNode expr;
117   /*@only@*/ enumNameList enumnamelist;
118   /*@only@*/ exprNodeList exprlist;
119   /*@only@*/ sRefSet srset; 
120   /*@only@*/ cstringList cstringlist;
121
122   /*drl
123     added 1/19/2001
124   */
125   constraint con;
126   constraintList conL;
127   constraintExpr conE;
128   /* drl */  
129 }
130
131 /* standard C tokens */
132
133 %token <tok> BADTOK SKIPTOK
134 %token <tok> CTOK_ELIPSIS CASE DEFAULT CIF CELSE SWITCH WHILE DO CFOR
135 %token <tok> GOTO CONTINUE BREAK RETURN
136 %token <tok> TSEMI TLBRACE TRBRACE TCOMMA TCOLON TASSIGN TLPAREN 
137 %token <tok> TRPAREN TLSQBR TRSQBR TDOT TAMPERSAND TEXCL TTILDE
138 %token <tok> TMINUS TPLUS TMULT TDIV TPERCENT TLT TGT TCIRC TBAR TQUEST
139 %token <tok> CSIZEOF CALIGNOF ARROW_OP CTYPEDEF COFFSETOF
140 %token <tok> INC_OP DEC_OP LEFT_OP RIGHT_OP
141 %token <tok> LE_OP GE_OP EQ_OP NE_OP AND_OP OR_OP
142 %token <tok> MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN SUB_ASSIGN
143 %token <tok> LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN
144 %token <tok> CSTRUCT CUNION CENUM
145 %token <tok> VA_ARG VA_DCL
146 %token <tok> QWARN
147 %token <tok> QGLOBALS
148 %token <tok> QMODIFIES 
149 %token <tok> QNOMODS
150 %token <tok> QCONSTANT
151 %token <tok> QFUNCTION
152 %token <tok> QITER
153 %token <tok> QDEFINES 
154 %token <tok> QUSES
155 %token <tok> QALLOCATES
156 %token <tok> QSETS
157 %token <tok> QRELEASES 
158 %token <tok> QPRECLAUSE 
159 %token <tok> QPOSTCLAUSE 
160 %token <tok> QALT 
161 %token <tok> QUNDEF QKILLED
162 %token <tok> QENDMACRO
163
164 /* additional tokens introduced by lclint pre-processor. */
165 %token <tok> LLMACRO LLMACROITER LLMACROEND TENDMACRO
166
167 /* break comments: */
168 %token <tok> QSWITCHBREAK QLOOPBREAK QINNERBREAK QSAFEBREAK
169 %token <tok> QINNERCONTINUE
170
171 /* case fall-through marker: */
172 %token <tok> QFALLTHROUGH
173
174 /* used in scanner only */
175 %token <tok> QLINTNOTREACHED
176 %token <tok> QLINTFALLTHROUGH
177 %token <tok> QLINTFALLTHRU
178 %token <tok> QARGSUSED
179 %token <tok> QPRINTFLIKE QLINTPRINTFLIKE QSCANFLIKE QMESSAGELIKE
180
181 /* not-reached marker: (used like a label) */
182 %token <tok> QNOTREACHED
183
184 /* type qualifiers: */
185 %token <tok> QCONST QVOLATILE QINLINE QEXTENSION QEXTERN QSTATIC QAUTO QREGISTER
186 %token <tok> QOUT QIN QYIELD QONLY QTEMP QSHARED QREF QUNIQUE
187 %token <tok> QCHECKED QUNCHECKED QCHECKEDSTRICT QCHECKMOD
188 %token <tok> QKEEP QKEPT QPARTIAL QSPECIAL QOWNED QDEPENDENT
189 %token <tok> QRETURNED QEXPOSED QNULL QOBSERVER QISNULL 
190 %token <tok> QEXITS QMAYEXIT QNEVEREXIT QTRUEEXIT QFALSEEXIT
191 %token <tok> QLONG QSIGNED QUNSIGNED QSHORT QUNUSED QSEF QNOTNULL QRELNULL
192 %token <tok> QABSTRACT QCONCRETE QMUTABLE QIMMUTABLE
193 %token <tok> QTRUENULL QFALSENULL QEXTERNAL
194 %token <tok> QREFCOUNTED QREFS QNEWREF QTEMPREF QKILLREF QRELDEF
195 %token <ctyp> CGCHAR CBOOL CINT CGFLOAT CDOUBLE CVOID 
196 %token <tok> QANYTYPE QINTEGRALTYPE QUNSIGNEDINTEGRALTYPE QSIGNEDINTEGRALTYPE
197
198 %type <typequal> nullterminatedQualifier
199 %token <tok> QNULLTERMINATED
200 %token <tok> QSETBUFFERSIZE
201 %token <tok> QSETSTRINGLENGTH
202 %token <tok> QMAXSET
203 %token <tok> QMAXREAD
204 %token <tok> QTESTINRANGE
205
206 %token <tok> TCAND
207
208
209 /* identifiers, literals */
210 %token <entry> IDENTIFIER
211 %token <cname> NEW_IDENTIFIER TYPE_NAME_OR_ID 
212 %token <annotation> CANNOTATION
213 %token <expr> CCONSTANT
214 %type <cname> flagId
215 %type <flagspec> flagSpec
216 %type <expr> cconstantExpr
217 %token <entry> ITER_NAME ITER_ENDNAME 
218 %type <entry> endIter 
219
220 %type <funcclauselist> functionClauses functionClausesPlain
221 %type <funcclause> functionClause functionClause functionClausePlain
222
223 %type <globsclause> globalsClause globalsClausePlain
224 %type <modsclause> modifiesClause modifiesClausePlain nomodsClause
225 %type <warnclause> warnClause warnClausePlain optWarnClause
226 %type <funcclause> conditionClause conditionClausePlain
227 %type <stateclause> stateClause stateClausePlain
228 %type <msconstraint> metaStateConstraint 
229 %type <fcnconstraint> functionConstraint
230 %type <msspec> metaStateSpecifier
231 %type <msexpr> metaStateExpression
232
233 %type <sr> globId globIdListExpr
234 %type <globset> globIdList
235
236 %token <ctyp>  TYPE_NAME 
237 %token <msinfo> METASTATE_NAME 
238 %type <msinfo> metaStateName
239 %type <cname> enumerator newId  /*@-varuse@*/ /* yacc declares yytranslate here */
240 %type <count> pointers /*@=varuse@*/
241
242 %type <tok> doHeader stateTag conditionTag startConditionClause
243 %type <typequal> exitsQualifier checkQualifier stateQualifier 
244                  paramQualifier returnQualifier visibilityQualifier
245                  typedefQualifier refcountQualifier definedQualifier
246
247 /* type construction */
248 %type <ctyp> abstractDecl abstractDeclBase optAbstractDeclBase
249 %type <ctyp> suSpc enumSpc typeName typeSpecifier
250
251 %type <ntyp> namedDecl namedDeclBase optNamedDecl
252 %type <ntyp> plainNamedDecl plainNamedDeclBase
253 %type <ntyp> structNamedDecl
254 %type <ntyp> fcnDefHdrAux plainFcn
255
256 %type <oentry> paramDecl 
257 %type <entry> id 
258
259 %type <ntyplist> structNamedDeclList
260
261 %type <entrylist> genericParamList paramTypeList paramList idList paramIdList
262 %type <exprlist> argumentExprList iterArgList
263 %type <exprlist> initList namedInitializerList namedInitializerListAux
264 %type <flist> structDeclList structDecl
265 %type <srset> locModifies modList specClauseList optSpecClauseList
266 %type <sr>    mExpr modListExpr specClauseListExpr
267
268 /*drl*/
269 %type <con> BufConstraint
270 %type <tok> relationalOp
271 %type <tok> BufBinaryOp
272 %type <tok> bufferModifier
273
274 %type <conE> BufConstraintExpr
275
276 %type <conE> BufConstraintTerm
277 %type <sr> BufConstraintSrefExpr
278
279 %type <conL> BufConstraintList
280
281 %type <tok>  BufUnaryOp
282
283 %type <enumnamelist> enumeratorList 
284 %type <cstringlist> fieldDesignator
285
286 %type <expr> sizeofExpr sizeofExprAux offsetofExpr
287 %type <expr> openScope closeScope 
288 %type <expr> instanceDecl namedInitializer optDeclarators
289 %type <expr> primaryExpr postfixExpr primaryIterExpr postfixIterExpr
290 %type <expr> unaryExpr castExpr timesExpr plusExpr
291 %type <expr> unaryIterExpr castIterExpr timesIterExpr plusIterExpr
292 %type <expr> shiftExpr relationalExpr equalityExpr bitandExpr
293 %type <expr> xorExpr bitorExpr andExpr
294 %type <expr> orExpr conditionalExpr assignExpr 
295 %type <expr> shiftIterExpr relationalIterExpr equalityIterExpr bitandIterExpr
296 %type <expr> xorIterExpr bitorIterExpr andIterExpr
297 %type <expr> orIterExpr conditionalIterExpr assignIterExpr iterArgExpr
298 %type <expr> expr optExpr constantExpr
299 %type <expr> init macroBody iterBody endBody partialIterStmt iterSelectionStmt
300 %type <expr> stmt stmtList fcnBody iterStmt iterDefStmt iterDefStmtList
301 %type <expr> labeledStmt caseStmt defaultStmt 
302 %type <expr> compoundStmt compoundStmtAux compoundStmtRest compoundStmtAuxErr
303 %type <expr> expressionStmt selectionStmt iterationStmt jumpStmt iterDefIterationStmt 
304 %type <expr> stmtErr stmtListErr compoundStmtErr expressionStmtErr 
305 %type <expr> iterationStmtErr initializerList initializer ifPred whilePred forPred iterWhilePred
306
307 %type <typequal> storageSpecifier typeQualifier typeModifier globQual
308 %type <tquallist> optGlobQuals
309 %type <qtyp> completeType completeTypeSpecifier optCompleteType
310 %type <qtyp> completeTypeSpecifierAux altType typeExpression 
311 /*%type <expr> lclintassertion*/
312
313 %start file
314
315 %%
316
317 file
318  :              
319  | externalDefs
320
321 externalDefs
322  : externalDef { context_checkGlobalScope (); }
323  | externalDefs externalDef { context_checkGlobalScope (); }
324
325 externalDef
326  : fcnDef optSemi { uentry_clearDecl (); } 
327  | constantDecl   { uentry_clearDecl (); } 
328  | fcnDecl        { uentry_clearDecl (); }
329  | iterDecl       { uentry_clearDecl (); } 
330  | macroDef       { uentry_clearDecl (); } 
331  | initializer    { uentry_checkDecl (); exprNode_free ($1); }
332  | error          { uentry_clearDecl (); } 
333
334 constantDecl
335  : QCONSTANT completeTypeSpecifier NotType namedDecl NotType optSemi IsType QENDMACRO
336    { checkConstant ($2, $4); }
337  | QCONSTANT completeTypeSpecifier NotType namedDecl NotType TASSIGN IsType init optDeclarators optSemi QENDMACRO
338    { checkValueConstant ($2, $4, $8) ; }
339
340 fcnDecl
341  : QFUNCTION { context_enterFunctionHeader (); } plainFcn optSemi QENDMACRO 
342    { 
343      declareStaticFunction ($3); context_quietExitFunction (); 
344      context_exitFunctionHeader (); 
345    }
346
347 plainFcn
348  : plainNamedDecl
349    { 
350      qtype qint = qtype_create (ctype_int);
351      $$ = idDecl_fixBase ($1, qint);
352      qtype_free (qint);
353    }
354  | completeTypeSpecifier NotType plainNamedDecl
355    { $$ = idDecl_fixBase ($3, $1); }
356
357 plainNamedDecl
358  : plainNamedDeclBase
359  | pointers plainNamedDeclBase 
360    { $$ = $2; qtype_adjustPointers ($1, idDecl_getTyp ($$)); }
361
362 namedDeclBase
363  : newId { $$ = idDecl_create ($1, qtype_unknown ()); }
364  | IsType TLPAREN NotType namedDecl IsType TRPAREN
365    { $$ = idDecl_expectFunction ($4); }
366  | namedDeclBase TLSQBR TRSQBR 
367    { $$ = idDecl_replaceCtype ($1, ctype_makeArray (idDecl_getCtype ($1))); }
368  | namedDeclBase TLSQBR IsType constantExpr TRSQBR NotType
369    {
370      exprNode_findValue($4);
371      if (exprNode_hasValue ($4)) 
372        {
373          $$ = idDecl_replaceCtype ($1, ctype_makeFixedArray (idDecl_getCtype ($1), exprNode_getLongValue ($4)));
374        } 
375      else
376        {
377          $$ = idDecl_replaceCtype ($1, ctype_makeArray (idDecl_getCtype ($1))); 
378        }
379    }
380  | namedDeclBase PushType TLPAREN TRPAREN 
381    { setCurrentParams (uentryList_missingParams); }
382    functionClauses
383    { /* need to support globals and modifies here! */
384      ctype ct = ctype_makeFunction (idDecl_getCtype ($1), 
385                                     uentryList_makeMissingParams ());
386      
387      $$ = idDecl_replaceCtype ($1, ct);
388      idDecl_addClauses ($$, $6);
389      context_popLoc ();
390      /*drl 7/25/01 added*/
391      setImplictfcnConstraints();
392    }
393  | namedDeclBase PushType TLPAREN genericParamList TRPAREN 
394    { setCurrentParams ($4); } 
395    functionClauses
396    { setImplictfcnConstraints ();
397      clearCurrentParams ();
398      $$ = idDecl_replaceCtype ($1, ctype_makeFunction (idDecl_getCtype ($1), $4));
399      idDecl_addClauses ($$, $7);
400      context_popLoc (); 
401    }
402
403 plainNamedDeclBase
404  : newId { $$ = idDecl_create ($1, qtype_unknown ()); }
405  | IsType TLPAREN NotType plainNamedDecl IsType TRPAREN
406    { $$ = idDecl_expectFunction ($4); }
407  | plainNamedDeclBase TLSQBR TRSQBR 
408    { $$ = idDecl_replaceCtype ($1, ctype_makeArray (idDecl_getCtype ($1))); }
409  | plainNamedDeclBase TLSQBR IsType constantExpr TRSQBR NotType
410    { 
411      int value;
412
413      if (exprNode_hasValue ($4) 
414          && multiVal_isInt (exprNode_getValue ($4)))
415        {
416          value = (int) multiVal_forceInt (exprNode_getValue ($4));
417        }
418      else
419        {
420          value = 0;
421        }
422
423      $$ = idDecl_replaceCtype ($1, ctype_makeFixedArray (idDecl_getCtype ($1), value));
424    }
425  | plainNamedDeclBase PushType TLPAREN TRPAREN 
426    { setCurrentParams (uentryList_missingParams); }
427    functionClausesPlain
428    {
429      ctype ct = ctype_makeFunction (idDecl_getCtype ($1), 
430                                     uentryList_makeMissingParams ());
431      
432      $$ = idDecl_replaceCtype ($1, ct);
433      idDecl_addClauses ($$, $6);
434      context_popLoc (); 
435    }
436  | plainNamedDeclBase PushType TLPAREN genericParamList TRPAREN 
437    { setCurrentParams ($4); } 
438    functionClausesPlain
439    { 
440      clearCurrentParams ();
441      $$ = idDecl_replaceCtype ($1, ctype_makeFunction (idDecl_getCtype ($1), $4));
442      idDecl_addClauses ($$, $7);
443      context_popLoc (); 
444    }
445
446 iterDecl
447  : QITER newId TLPAREN genericParamList TRPAREN 
448    { setCurrentParams ($4); } functionClausesPlain
449    { clearCurrentParams (); } optSemi QENDMACRO
450    { declareCIter ($2, $4); }
451
452 macroDef
453  : LLMACRO macroBody TENDMACRO     { exprNode_checkMacroBody ($2); }
454  | LLMACROITER iterBody TENDMACRO  { exprNode_checkIterBody ($2); }
455  | LLMACROEND endBody TENDMACRO    { exprNode_checkIterEnd ($2); }
456  | LLMACRO TENDMACRO /* no stmt */ { exprChecks_checkEmptyMacroBody (); } 
457
458 fcnDefHdr
459  : fcnDefHdrAux { clabstract_declareFunction ($1); }
460
461 metaStateConstraint
462  : metaStateSpecifier TASSIGN metaStateExpression 
463    { $$ = metaStateConstraint_create ($1, $3); }
464
465 metaStateSpecifier
466   : BufConstraintSrefExpr { cscanner_expectingMetaStateName (); } TCOLON metaStateName
467     { cscanner_clearExpectingMetaStateName ();
468       $$ = metaStateSpecifier_create ($1, $4); }
469   | CTOK_ELIPSIS { cscanner_expectingMetaStateName (); } TCOLON metaStateName
470     { cscanner_clearExpectingMetaStateName ();
471       $$ = metaStateSpecifier_createElipsis ($4); }
472
473 metaStateExpression
474 : metaStateSpecifier { $$ = metaStateExpression_create ($1); }
475 | metaStateSpecifier TBAR metaStateExpression { $$ = metaStateExpression_createMerge ($1, $3); }
476
477 metaStateName
478 : METASTATE_NAME
479
480 /*drl*/
481
482 BufConstraintList
483 : BufConstraint TCAND BufConstraintList { $$ = constraintList_add ($3, $1); }
484 | BufConstraint { $$ = constraintList_single ($1); } 
485
486 BufConstraint
487 :  BufConstraintExpr relationalOp BufConstraintExpr {
488  $$ = makeConstraintParse3 ($1, $2, $3);
489  DPRINTF(("Done BufConstraint1\n")); }
490
491 bufferModifier
492  : QMAXSET
493  | QMAXREAD
494
495 relationalOp
496  : GE_OP
497  | LE_OP
498  | EQ_OP
499
500 BufConstraintExpr
501  : BufConstraintTerm 
502  | BufUnaryOp TLPAREN BufConstraintExpr TRPAREN {$$ = constraintExpr_parseMakeUnaryOp ($1, $3);  DPRINTF( ("Got BufConstraintExpr UNary Op ") ); }
503  | TLPAREN BufConstraintExpr BufBinaryOp BufConstraintExpr TRPAREN {
504    DPRINTF( ("Got BufConstraintExpr BINary Op ") );
505    $$ = constraintExpr_parseMakeBinaryOp ($2, $3, $4); }
506
507 BufConstraintTerm
508  : BufConstraintSrefExpr { $$ =  constraintExpr_makeTermsRef ($1);} 
509  | CCONSTANT { $$ = constraintExpr_makeIntLiteral (exprNode_getLongValue ($1)); }
510
511 BufConstraintSrefExpr
512 : id            
513   { /*@-onlytrans@*/ $$ = checkbufferConstraintClausesId ($1); /*@=onlytrans@*/ /*@i523@*/ }
514 | NEW_IDENTIFIER                   
515   { $$ = fixStateClausesId ($1); }
516 | BufConstraintSrefExpr TLSQBR TRSQBR       
517   { $$ = sRef_makeAnyArrayFetch ($1); }
518 | BufConstraintSrefExpr  TLSQBR CCONSTANT TRSQBR 
519   {
520     /*
521     char *t; int c; 
522     t =  cstring_toCharsSafe (exprNode_unparse($3)); 
523     c = atoi( t );
524     */
525     $$ = sRef_makeArrayFetchKnown ($1, exprNode_getLongValue ($3));
526   }
527 | TMULT  BufConstraintSrefExpr               
528   { $$ = sRef_constructPointer ($2); }
529 | TLPAREN BufConstraintSrefExpr TRPAREN     
530   { $$ = $2; }  
531 | BufConstraintSrefExpr TDOT newId          
532   { cstring_markOwned ($3); $$ = sRef_buildField ($1, $3); }
533 | BufConstraintSrefExpr ARROW_OP newId      
534   { cstring_markOwned ($3); $$ = sRef_makeArrow ($1, $3); }
535
536 /*
537 | BufConstraintTerm TLSQBR TRSQBR       { $$ = sRef_makeAnyArrayFetch ($1); }
538  | specClauseListExpr TLSQBR mExpr TRSQBR { $$ = sRef_makeAnyArrayFetch ($1); }
539  | TLPAREN specClauseListExpr TRPAREN     { $$ = $2; }  
540  | specClauseListExpr TDOT newId          { cstring_markOwned ($3);
541                                             $$ = sRef_buildField ($1, $3); }
542 */
543
544 /*BufConstraintExpr
545 : BufConstraintTerm 
546 */
547
548 BufUnaryOp
549 : bufferModifier 
550 ;
551
552 BufBinaryOp
553  : TPLUS
554 | TMINUS
555 ;
556 /*
557 ** Function clauses can appear in any order.
558 */
559
560 functionClauses
561  : { $$ = functionClauseList_new (); }
562  | functionClause functionClauses
563    { $$ = functionClauseList_prepend ($2, $1); }
564
565 /*
566 ** Inside macro definitions, there are no end macros.
567 */
568
569 functionClausesPlain
570  : 
571    { $$ = functionClauseList_new (); }
572  | functionClausePlain functionClausesPlain
573    { $$ = functionClauseList_prepend ($2, $1); }
574
575 functionClause
576  : globalsClause   { $$ = functionClause_createGlobals ($1); }
577  | modifiesClause  { $$ = functionClause_createModifies ($1); }
578  | nomodsClause    { $$ = functionClause_createModifies ($1); }
579  | stateClause     { $$ = functionClause_createState ($1); }  
580  | conditionClause { $$ = $1; }
581  | warnClause      { $$ = functionClause_createWarn ($1); }
582
583 functionClausePlain
584  : globalsClausePlain   { $$ = functionClause_createGlobals ($1); }
585  | modifiesClausePlain  { $$ = functionClause_createModifies ($1); }
586  | nomodsClause         { $$ = functionClause_createModifies ($1); }
587  | stateClausePlain     { $$ = functionClause_createState ($1); }  
588  | conditionClausePlain { $$ = $1; }
589  | warnClausePlain      { $$ = functionClause_createWarn ($1); }
590
591 globalsClause
592  : globalsClausePlain QENDMACRO { $$ = $1; }
593
594 globalsClausePlain
595  : QGLOBALS { setProcessingGlobalsList (); } 
596    globIdList optSemi  
597    { 
598      unsetProcessingGlobals (); 
599      $$ = globalsClause_create ($1, $3); 
600    }
601
602 nomodsClause
603  : QNOMODS { $$ = modifiesClause_createNoMods ($1); }
604
605 modifiesClause
606  : modifiesClausePlain QENDMACRO { $$ = $1; }
607
608 modifiesClausePlain
609  : QMODIFIES 
610    {
611      context_setProtectVars (); enterParamsTemp (); 
612      sRef_setGlobalScopeSafe (); 
613    }
614    locModifies
615    { 
616      exitParamsTemp ();
617      sRef_clearGlobalScopeSafe (); 
618      context_releaseVars ();
619      $$ = modifiesClause_create ($1, $3);
620    }
621
622 flagSpec
623  : flagId 
624    { $$ = flagSpec_createPlain ($1); }
625  | flagId TBAR flagSpec
626    { $$ = flagSpec_createOr ($1, $3); }
627
628 flagId
629  : NEW_IDENTIFIER
630
631 optWarnClause
632  : warnClause
633  | /* empty */ { $$ = warnClause_undefined; }
634
635 warnClause
636  : warnClausePlain QENDMACRO { $$ = $1; }
637
638 warnClausePlain
639  : QWARN flagSpec cconstantExpr
640    {      
641      llassert (exprNode_knownStringValue ($3));
642      $$ = warnClause_create ($1, $2, cstring_copy (multiVal_forceString (exprNode_getValue ($3)))); 
643      exprNode_free ($3);
644    }
645  | QWARN flagSpec
646    { $$ = warnClause_create ($1, $2, cstring_undefined); }
647
648 globIdList
649  : globIdListExpr                     { $$ = globSet_single ($1); }
650  | globIdList TCOMMA globIdListExpr   { $$ = globSet_insert ($1, $3); }
651  
652 globIdListExpr 
653  : optGlobQuals globId { $$ = clabstract_createGlobal ($2, $1); }
654
655 optGlobQuals
656  : /* empty */           { $$ = qualList_undefined; }
657  | globQual optGlobQuals { $$ = qualList_add ($2, $1); }
658
659 globId
660  : id             { $$ = uentry_getSref ($1); }
661  | NEW_IDENTIFIER { $$ = clabstract_unrecognizedGlobal ($1); }
662  | initializer    { $$ = clabstract_checkGlobal ($1); }
663
664 globQual
665  : QUNDEF   { $$ = qual_createUndef (); }
666  | QKILLED  { $$ = qual_createKilled (); }
667  | QOUT     { $$ = qual_createOut (); }
668  | QIN      { $$ = qual_createIn (); }
669  | QPARTIAL { $$ = qual_createPartial (); }
670
671 stateTag
672  : QDEFINES
673  | QUSES
674  | QALLOCATES
675  | QSETS
676  | QRELEASES
677
678 conditionTag
679  : QPRECLAUSE
680  | QPOSTCLAUSE
681
682 fcnDefHdrAux
683  : namedDecl                               
684    { 
685      qtype qint = qtype_create (ctype_int);
686      $$ = idDecl_fixBase ($1, qint);
687      qtype_free (qint);
688    }
689  | completeTypeSpecifier NotType namedDecl 
690    { $$ = idDecl_fixBase ($3, $1); }
691  
692 fcnBody
693  : TLBRACE { checkDoneParams (); context_enterInnerContext (); } 
694    compoundStmtRest 
695    {  
696      exprNode_checkFunctionBody ($3); $$ = $3; 
697      context_exitInner ($3); 
698    }
699  | { context_enterOldStyleScope (); } initializerList 
700    { oldStyleDoneParams (); context_enterInnerContext (); } 
701    compoundStmt 
702    {
703      exprNode_checkFunctionBody ($4); 
704      $$ = $4; /* oldstyle */ 
705      context_exitInner ($4);
706    } 
707  
708 fcnDef
709  : fcnDefHdr fcnBody 
710    { 
711      context_setFunctionDefined (exprNode_loc ($2)); 
712      exprNode_checkFunction (context_getHeader (),  $2); 
713      /* DRL 8 8 2000 */
714      
715      context_exitFunction ();
716    }
717
718 locModifies
719  : modList optSemi           { $$ = $1; }
720  | optSemi                   { $$ = sRefSet_new (); }
721  
722 modListExpr
723  : id                              { $$ = uentry_getSref ($1); checkModifiesId ($1); }
724  | NEW_IDENTIFIER                  { $$ = fixModifiesId ($1); }
725  | modListExpr TLSQBR TRSQBR       { $$ = modListArrayFetch ($1, sRef_undefined); }
726  | modListExpr TLSQBR mExpr TRSQBR { $$ = modListArrayFetch ($1, $3); }
727  | TMULT modListExpr               { $$ = modListPointer ($2); }
728  | TLPAREN modListExpr TRPAREN     { $$ = $2; }  
729  | modListExpr TDOT newId          { $$ = modListFieldAccess ($1, $3); }
730  | modListExpr ARROW_OP newId      { $$ = modListArrowAccess ($1, $3); }
731
732
733 mExpr
734   : modListExpr     { $$ = $1; }
735   | cconstantExpr   { $$ = sRef_makeUnknown (); /* sRef_makeConstant ($1); ? */ }
736     /* arithmetic? */
737
738 modList
739   : modListExpr                { $$ = sRefSet_single ($1); }
740   | modList TCOMMA modListExpr { $$ = sRefSet_insert ($1, $3); }
741
742 specClauseListExpr
743  : id                                     
744    { $$ = checkStateClausesId ($1); }
745  | NEW_IDENTIFIER                         
746    { $$ = fixStateClausesId ($1); }
747  | specClauseListExpr TLSQBR TRSQBR       { $$ = sRef_makeAnyArrayFetch ($1); }
748  | specClauseListExpr TLSQBR mExpr TRSQBR { $$ = sRef_makeAnyArrayFetch ($1); }
749  | TMULT specClauseListExpr               { $$ = sRef_constructPointer ($2); }
750  | TLPAREN specClauseListExpr TRPAREN     { $$ = $2; }  
751  | specClauseListExpr TDOT newId          { cstring_markOwned ($3);
752                                             $$ = sRef_buildField ($1, $3); }
753  | specClauseListExpr ARROW_OP newId      { cstring_markOwned ($3);
754                                             $$ = sRef_makeArrow ($1, $3); }
755
756 optSpecClauseList
757  : /* empty */ { $$ = sRefSet_undefined }
758  | specClauseList
759
760 specClauseList
761   : specClauseListExpr                       
762     { if (sRef_isValid ($1)) { $$ = sRefSet_single ($1); } 
763       else { $$ = sRefSet_undefined; } 
764     }
765   | specClauseList TCOMMA specClauseListExpr 
766     { if (sRef_isValid ($3))
767         {
768           $$ = sRefSet_insert ($1, $3); 
769         }
770       else
771         {
772           $$ = $1;
773         }
774     }
775
776 primaryExpr
777  : id { $$ = exprNode_fromIdentifier ($1); }
778  | NEW_IDENTIFIER { $$ = exprNode_fromUIO ($1); } 
779  | cconstantExpr
780  | TLPAREN expr TRPAREN { $$ = exprNode_addParens ($1, $2); }
781  | TYPE_NAME_OR_ID { $$ = exprNode_fromIdentifier (coerceId ($1)); } 
782  | QEXTENSION { $$ = exprNode_makeError (); }
783  
784 postfixExpr
785  : primaryExpr 
786  | postfixExpr TLSQBR expr TRSQBR { $$ = exprNode_arrayFetch ($1, $3); }
787  | postfixExpr TLPAREN TRPAREN { $$ = exprNode_functionCall ($1, exprNodeList_new ()); }
788  | postfixExpr TLPAREN argumentExprList TRPAREN { $$ = exprNode_functionCall ($1, $3); }
789  | VA_ARG TLPAREN assignExpr TCOMMA typeExpression TRPAREN { $$ = exprNode_vaArg ($1, $3, $5); }
790  | postfixExpr NotType TDOT newId IsType { $$ = exprNode_fieldAccess ($1, $3, $4); }
791  | postfixExpr NotType ARROW_OP newId IsType { $$ = exprNode_arrowAccess ($1, $3, $4); }
792  | postfixExpr INC_OP { $$ = exprNode_postOp ($1, $2); }
793  | postfixExpr DEC_OP { $$ = exprNode_postOp ($1, $2); }
794  
795 argumentExprList
796  : assignExpr { $$ = exprNodeList_singleton ($1); }
797  | argumentExprList TCOMMA assignExpr { $$ = exprNodeList_push ($1, $3); }
798  
799 unaryExpr
800  : postfixExpr 
801  | INC_OP unaryExpr { $$ = exprNode_preOp ($2, $1); }
802  | DEC_OP unaryExpr { $$ = exprNode_preOp ($2, $1); }
803  | TAMPERSAND castExpr { $$ = exprNode_preOp ($2, $1); }
804  | TMULT castExpr  { $$ = exprNode_preOp ($2, $1); }
805  | TPLUS castExpr  { $$ = exprNode_preOp ($2, $1); }
806  | TMINUS castExpr { $$ = exprNode_preOp ($2, $1); }
807  | TTILDE castExpr { $$ = exprNode_preOp ($2, $1); }
808  | TEXCL castExpr  { $$ = exprNode_preOp ($2, $1); }
809  | sizeofExpr      { $$ = $1; }
810  | offsetofExpr    { $$ = $1; }
811
812 fieldDesignator
813  : fieldDesignator TDOT newId { $$ = cstringList_add ($1, $3); }
814  | newId                      { $$ = cstringList_single ($1); }
815
816 offsetofExpr
817  : COFFSETOF IsType TLPAREN typeExpression NotType TCOMMA fieldDesignator TRPAREN IsType
818    { $$ = exprNode_offsetof ($4, $7); }
819
820 sizeofExpr
821  : IsType { context_setProtectVars (); } 
822    sizeofExprAux { context_sizeofReleaseVars (); $$ = $3; }
823
824 sizeofExprAux 
825  : CSIZEOF TLPAREN typeExpression TRPAREN { $$ = exprNode_sizeofType ($3); } 
826  | CSIZEOF unaryExpr                      { $$ = exprNode_sizeofExpr ($2); }
827  | CALIGNOF TLPAREN typeExpression TRPAREN { $$ = exprNode_alignofType ($3); } 
828  | CALIGNOF unaryExpr                      { $$ = exprNode_alignofExpr ($2); }
829  
830 castExpr
831  : unaryExpr 
832  | TLPAREN typeExpression TRPAREN castExpr 
833    { $$ = exprNode_cast ($1, $4, $2); } 
834  
835 timesExpr
836  : castExpr 
837  | timesExpr TMULT castExpr { $$ = exprNode_op ($1, $3, $2); }
838  | timesExpr TDIV castExpr { $$ = exprNode_op ($1, $3, $2); }
839  | timesExpr TPERCENT castExpr { $$ = exprNode_op ($1, $3, $2); }
840
841 plusExpr
842  : timesExpr 
843  | plusExpr TPLUS timesExpr { $$ = exprNode_op ($1, $3, $2); }
844  | plusExpr TMINUS timesExpr { $$ = exprNode_op ($1, $3, $2); }
845
846 shiftExpr
847  : plusExpr 
848  | shiftExpr LEFT_OP plusExpr { $$ = exprNode_op ($1, $3, $2); }
849  | shiftExpr RIGHT_OP plusExpr { $$ = exprNode_op ($1, $3, $2); }
850
851 relationalExpr
852  : shiftExpr 
853  | relationalExpr TLT shiftExpr { $$ = exprNode_op ($1, $3, $2); }
854  | relationalExpr TGT shiftExpr { $$ = exprNode_op ($1, $3, $2); }
855  | relationalExpr LE_OP shiftExpr { $$ = exprNode_op ($1, $3, $2); }
856  | relationalExpr GE_OP shiftExpr { $$ = exprNode_op ($1, $3, $2); }
857  
858 equalityExpr 
859  : relationalExpr 
860  | equalityExpr EQ_OP relationalExpr { $$ = exprNode_op ($1, $3, $2); }
861  | equalityExpr NE_OP relationalExpr { $$ = exprNode_op ($1, $3, $2); }
862
863 bitandExpr
864  : equalityExpr 
865  | bitandExpr TAMPERSAND equalityExpr { $$ = exprNode_op ($1, $3, $2); }
866
867 xorExpr
868  : bitandExpr 
869  | xorExpr TCIRC bitandExpr { $$ = exprNode_op ($1, $3, $2); }
870
871
872 bitorExpr
873  : xorExpr 
874  | bitorExpr TBAR xorExpr { $$ = exprNode_op ($1, $3, $2); }
875
876 andExpr 
877  : bitorExpr 
878  | andExpr AND_OP 
879    { exprNode_produceGuards ($1); 
880      context_enterAndClause ($1); 
881    } 
882    bitorExpr 
883    { 
884      $$ = exprNode_op ($1, $4, $2); 
885      context_exitAndClause ($$, $4);
886    }
887
888 orExpr
889  : andExpr 
890  | orExpr OR_OP 
891    { 
892      exprNode_produceGuards ($1);
893      context_enterOrClause ($1); 
894    } 
895    andExpr 
896    { 
897      $$ = exprNode_op ($1, $4, $2); 
898      context_exitOrClause ($$, $4);
899    }
900
901 conditionalExpr 
902  : orExpr 
903  | orExpr TQUEST { exprNode_produceGuards ($1); context_enterTrueClause ($1); } expr TCOLON 
904    { context_enterFalseClause ($1); } conditionalExpr
905    { $$ = exprNode_cond ($1, $4, $7); context_exitClause ($1, $4, $7); }
906
907 assignExpr
908  : conditionalExpr 
909  | unaryExpr TASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
910  | unaryExpr MUL_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
911  | unaryExpr DIV_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
912  | unaryExpr MOD_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
913  | unaryExpr ADD_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
914  | unaryExpr SUB_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
915  | unaryExpr LEFT_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
916  | unaryExpr RIGHT_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
917  | unaryExpr AND_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
918  | unaryExpr XOR_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
919  | unaryExpr OR_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
920
921 expr
922  : assignExpr 
923  | expr TCOMMA assignExpr { $$ = exprNode_comma ($1, $3); } 
924
925 optExpr
926  : /* empty */ { $$ = exprNode_undefined; }
927  | expr 
928
929 constantExpr
930  : conditionalExpr 
931
932 /* instance_orTypeDecl_and_possible_initialization */
933
934 initializer
935  : instanceDecl { $$ = $1; }
936  | VA_DCL       { doVaDcl (); $$ = exprNode_makeError (); } 
937  | typeDecl     { $$ = exprNode_makeError (); }
938
939 instanceDecl
940  : completeTypeSpecifier IsType TSEMI 
941    { $$ = exprNode_makeError (); }
942     /*
943      ** This causes r/r conflicts with function definitions.
944      ** Instead we need to snarf one first. (gack)
945      **
946      ** | completeTypeSpecifier { setProcessingVars ($1); } 
947      ** NotType 
948      ** namedInitializerList IsType TSEMI 
949      ** { unsetProcessingVars (); }
950      **;
951      **
952      ** the solution is pretty ugly:
953      */
954  | completeTypeSpecifier NotType namedDecl NotType 
955    {
956      setProcessingVars ($1); 
957      processNamedDecl ($3); 
958    }
959    IsType optDeclarators TSEMI IsType 
960    { 
961      unsetProcessingVars (); 
962      $$ = exprNode_makeEmptyInitialization ($3); 
963      DPRINTF (("Empty initialization: %s", exprNode_unparse ($$)));
964    }
965  | completeTypeSpecifier NotType namedDecl NotType TASSIGN 
966    { setProcessingVars ($1); processNamedDecl ($3); }
967    IsType init optDeclarators TSEMI IsType 
968    { $$ = exprNode_concat ($9, exprNode_makeInitialization ($3, $8)); 
969      unsetProcessingVars ();
970    }
971
972 namedInitializer
973  : namedDecl NotType 
974    { 
975      processNamedDecl ($1); 
976      $$ = exprNode_makeEmptyInitialization ($1);
977    }
978  | namedDecl NotType TASSIGN { processNamedDecl ($1); } IsType init
979    { $$ = exprNode_makeInitialization ($1, $6); }
980
981 typeDecl
982  : CTYPEDEF completeTypeSpecifier { setProcessingTypedef ($2); } 
983    NotType namedInitializerList IsType optWarnClause TSEMI 
984    { clabstract_declareType ($5, $7); }
985  | CTYPEDEF completeTypeSpecifier IsType TSEMI { /* in the ANSI grammar, semantics unclear */ }
986  | CTYPEDEF namedInitializerList IsType TSEMI { /* in the ANSI grammar, semantics unclear */ } 
987
988 IsType
989  : { g_expectingTypeName = TRUE; }
990
991 PushType
992  : { g_expectingTypeName = TRUE; context_pushLoc (); }
993
994 namedInitializerList
995  :  namedInitializerListAux IsType { $$ = $1; }
996
997 namedInitializerListAux
998  : namedInitializer { $$ = exprNodeList_singleton ($1); }
999  | namedInitializerList TCOMMA NotType namedInitializer { $$ = exprNodeList_push ($1, $4); }
1000
1001 optDeclarators
1002  : /* empty */      { $$ = exprNode_makeError (); }
1003  | optDeclarators TCOMMA NotType namedInitializer { $$ = exprNode_concat ($1, $4); }
1004
1005 init
1006  : assignExpr                      
1007  | TLBRACE initList TRBRACE        { $$ = exprNode_makeInitBlock ($1, $2); }
1008  | TLBRACE initList TCOMMA TRBRACE { $$ = exprNode_makeInitBlock ($1, $2); }
1009
1010
1011 initList
1012  : init 
1013    { $$ = exprNodeList_singleton ($1); }
1014  | initList TCOMMA init 
1015    { $$ = exprNodeList_push ($1, $3); }
1016
1017 /*
1018 ** need to do the storage class global hack so tags are
1019 ** declared with the right storage class.
1020 */
1021
1022 storageSpecifier
1023  : QEXTERN   { setStorageClass (SCEXTERN); $$ = qual_createExtern (); }
1024  | QINLINE   { $$ = qual_createInline (); }
1025  | QSTATIC   { setStorageClass (SCSTATIC); $$ = qual_createStatic (); }
1026  | QAUTO     { $$ = qual_createAuto (); }
1027  | QREGISTER { $$ = qual_createRegister (); }
1028
1029 nullterminatedQualifier:
1030  QNULLTERMINATED IsType { $$ = qual_createNullTerminated (); }
1031
1032 stateClause
1033  : stateClausePlain QENDMACRO { $$ = $1; }
1034
1035 stateClausePlain
1036  : stateTag NotType
1037    {
1038      context_setProtectVars (); 
1039      enterParamsTemp (); 
1040      sRef_setGlobalScopeSafe (); 
1041    }
1042    specClauseList optSemi IsType
1043    { 
1044      exitParamsTemp ();
1045      sRef_clearGlobalScopeSafe (); 
1046      context_releaseVars ();
1047      $$ = stateClause_createPlain ($1, $4);
1048    }
1049
1050 conditionClause
1051  : conditionClausePlain QENDMACRO { $$ = $1; }
1052
1053 startConditionClause
1054 : conditionTag NotType { $$ = $1; context_enterFunctionHeader (); } 
1055
1056 conditionClausePlain
1057  : startConditionClause stateQualifier
1058    {
1059      context_exitFunctionHeader ();
1060      context_setProtectVars (); 
1061      enterParamsTemp (); 
1062      sRef_setGlobalScopeSafe (); 
1063    }
1064    optSpecClauseList optSemi IsType
1065    { 
1066      exitParamsTemp ();
1067      sRef_clearGlobalScopeSafe (); 
1068      context_releaseVars ();
1069      $$ = functionClause_createState (stateClause_create ($1, $2, $4));
1070    }
1071  | startConditionClause
1072    {
1073      context_setProtectVars (); 
1074      enterParamsTemp (); 
1075      sRef_setGlobalScopeSafe (); 
1076    } 
1077    functionConstraint optSemi IsType
1078    {
1079      context_exitFunctionHeader ();
1080      exitParamsTemp ();
1081      sRef_clearGlobalScopeSafe (); 
1082      context_releaseVars ();
1083      DPRINTF (("done optGlobBufConstraintsAux\n"));
1084
1085      if (lltok_isEnsures ($1)) 
1086        {
1087          $$ = functionClause_createEnsures ($3);
1088        }
1089      else if (lltok_isRequires ($1))
1090        {
1091          $$ = functionClause_createRequires ($3);
1092        }
1093      else
1094        {
1095          BADBRANCH;
1096        }
1097
1098      DPRINTF (("FunctionclauseS: %s", functionClause_unparse ($$)));
1099    }
1100
1101 functionConstraint
1102  : BufConstraintList   { $$ = functionConstraint_createBufferConstraint ($1); }
1103  | metaStateConstraint { $$ = functionConstraint_createMetaStateConstraint ($1); DPRINTF (("Made constraint: %s", functionConstraint_unparse ($$))); } 
1104  
1105 exitsQualifier
1106  : QEXITS        { $$ = qual_createExits (); }
1107  | QMAYEXIT      { $$ = qual_createMayExit (); }
1108  | QTRUEEXIT     { $$ = qual_createTrueExit (); }
1109  | QFALSEEXIT    { $$ = qual_createFalseExit (); }
1110  | QNEVEREXIT    { $$ = qual_createNeverExit (); }
1111
1112 checkQualifier
1113  : QCHECKED        { $$ = qual_createChecked (); }
1114  | QCHECKMOD       { $$ = qual_createCheckMod (); }
1115  | QUNCHECKED      { $$ = qual_createUnchecked (); }
1116  | QCHECKEDSTRICT  { $$ = qual_createCheckedStrict (); }
1117
1118 stateQualifier
1119  : QOWNED        { $$ = qual_createOwned (); }
1120  | QDEPENDENT    { $$ = qual_createDependent (); }
1121  | QYIELD        { $$ = qual_createYield (); }
1122  | QTEMP         { $$ = qual_createTemp (); }
1123  | QONLY         { $$ = qual_createOnly (); }
1124  | QKEEP         { $$ = qual_createKeep (); }
1125  | QKEPT         { $$ = qual_createKept (); }
1126  | QSHARED       { $$ = qual_createShared (); }
1127  | QUNIQUE       { $$ = qual_createUnique (); }
1128  | QNULL         { $$ = qual_createNull (); }
1129  | QISNULL       { $$ = qual_createIsNull (); }
1130  | QRELNULL      { $$ = qual_createRelNull (); }
1131  | QNOTNULL      { $$ = qual_createNotNull (); }
1132  | QEXPOSED      { $$ = qual_createExposed (); }
1133  | QOBSERVER     { $$ = qual_createObserver (); }
1134  | QNULLTERMINATED { $$ = qual_createNullTerminated (); } 
1135  | CANNOTATION   { $$ = qual_createMetaState ($1); }
1136
1137
1138 paramQualifier
1139  : QRETURNED     { $$ = qual_createReturned (); }
1140  | QSEF          { $$ = qual_createSef (); }
1141
1142 visibilityQualifier
1143  : QUNUSED       { $$ = qual_createUnused (); }
1144  | QEXTERNAL     { $$ = qual_createExternal (); }
1145
1146 returnQualifier
1147  : QTRUENULL     { $$ = qual_createTrueNull (); }
1148  | QFALSENULL    { $$ = qual_createFalseNull (); }
1149
1150 typedefQualifier
1151  : QABSTRACT     { $$ = qual_createAbstract (); }
1152  | QCONCRETE     { $$ = qual_createConcrete (); }
1153  | QMUTABLE      { $$ = qual_createMutable (); }
1154  | QIMMUTABLE    { $$ = qual_createImmutable (); }
1155
1156 refcountQualifier
1157  : QREFCOUNTED   { $$ = qual_createRefCounted (); }
1158  | QREFS         { $$ = qual_createRefs (); }
1159  | QKILLREF      { $$ = qual_createKillRef (); }
1160  | QRELDEF       { $$ = qual_createRelDef (); }
1161  | QNEWREF       { $$ = qual_createNewRef (); }
1162  | QTEMPREF      { $$ = qual_createTempRef (); }
1163
1164 typeModifier
1165  : QSHORT            { $$ = qual_createShort (); }
1166  | QLONG             { $$ = qual_createLong (); }
1167  | QSIGNED           { $$ = qual_createSigned (); }
1168  | QUNSIGNED         { $$ = qual_createUnsigned (); }
1169
1170 definedQualifier
1171  : QOUT              { $$ = qual_createOut (); }
1172  | QIN               { $$ = qual_createIn (); }
1173  | QPARTIAL          { $$ = qual_createPartial (); }
1174  | QSPECIAL          { $$ = qual_createSpecial (); }
1175
1176 typeQualifier
1177  : QCONST IsType       { $$ = qual_createConst (); }
1178  | QVOLATILE IsType    { $$ = qual_createVolatile (); }
1179  | definedQualifier IsType { $$ = $1; } 
1180  | stateQualifier IsType { $$ = $1; } 
1181  | exitsQualifier IsType { $$ = $1; }
1182  | paramQualifier IsType { $$ = $1; }
1183  | checkQualifier IsType { $$ = $1; }
1184  | returnQualifier IsType { $$ = $1; }
1185  | visibilityQualifier IsType { $$ = $1; }
1186  | typedefQualifier IsType { $$ = $1; }
1187  | refcountQualifier IsType { $$ = $1; }
1188
1189 /*
1190 ** This is copied into the mtgrammar!
1191 */
1192
1193 typeSpecifier
1194  : CGCHAR NotType 
1195  | CINT NotType 
1196  | CBOOL NotType
1197  | CGFLOAT NotType
1198  | CDOUBLE NotType
1199  | CVOID NotType 
1200  | QANYTYPE NotType              { $$ = ctype_unknown; }
1201  | QINTEGRALTYPE NotType         { $$ = ctype_anyintegral; }
1202  | QUNSIGNEDINTEGRALTYPE NotType { $$ = ctype_unsignedintegral; }
1203  | QSIGNEDINTEGRALTYPE NotType   { $$ = ctype_signedintegral; }
1204  | typeName NotType     
1205  | suSpc NotType 
1206  | enumSpc NotType
1207  | typeModifier NotType { $$ = ctype_fromQual ($1); }
1208
1209 completeType
1210  : IsType completeTypeSpecifier IsType
1211    { $$ = qtype_resolve ($2); }
1212
1213 completeTypeSpecifier
1214  : completeTypeSpecifierAux { $$ = $1; }
1215  | completeTypeSpecifierAux QALT altType QENDMACRO  
1216    { $$ = qtype_mergeAlt ($1, $3); }
1217
1218 altType
1219  : typeExpression
1220  | typeExpression TCOMMA altType
1221    { $$ = qtype_mergeAlt ($1, $3); } 
1222
1223 completeTypeSpecifierAux
1224  : storageSpecifier optCompleteType        { $$ = qtype_addQual ($2, $1); }
1225  | typeQualifier optCompleteType           { $$ = qtype_addQual ($2, $1); } 
1226  | typeSpecifier optCompleteType           { $$ = qtype_combine ($2, $1); }
1227
1228 optCompleteType
1229  : /* empty */                             { $$ = qtype_unknown (); }
1230  | completeTypeSpecifier                   { $$ = $1; }
1231
1232 suSpc
1233  : NotType CSTRUCT newId IsType TLBRACE { sRef_setGlobalScopeSafe (); } 
1234    CreateStructInnerScope 
1235    structDeclList DeleteStructInnerScope { sRef_clearGlobalScopeSafe (); }
1236    TRBRACE 
1237    { $$ = declareStruct ($3, $8); }
1238  | NotType CUNION  newId IsType TLBRACE { sRef_setGlobalScopeSafe (); } 
1239    CreateStructInnerScope 
1240    structDeclList DeleteStructInnerScope { sRef_clearGlobalScopeSafe (); } 
1241    TRBRACE
1242    { $$ = declareUnion ($3, $8); } 
1243  | NotType CSTRUCT newId IsType TLBRACE TRBRACE 
1244    { $$ = declareStruct ($3, uentryList_new ()); }
1245  | NotType CUNION  newId IsType TLBRACE TRBRACE 
1246    { $$ = declareUnion ($3, uentryList_new ()); }
1247  | NotType CSTRUCT IsType TLBRACE { sRef_setGlobalScopeSafe (); } 
1248    CreateStructInnerScope 
1249    structDeclList DeleteStructInnerScope { sRef_clearGlobalScopeSafe (); }
1250    TRBRACE 
1251    { $$ = declareUnnamedStruct ($7); }
1252  | NotType CUNION IsType TLBRACE { sRef_setGlobalScopeSafe (); } 
1253    CreateStructInnerScope structDeclList DeleteStructInnerScope 
1254    { sRef_clearGlobalScopeSafe (); }
1255    TRBRACE 
1256    { $$ = declareUnnamedUnion ($7); } 
1257  | NotType CSTRUCT IsType TLBRACE TRBRACE
1258    { $$ = ctype_createUnnamedStruct (uentryList_new ()); }
1259  | NotType CUNION  IsType TLBRACE TRBRACE 
1260    { $$ = ctype_createUnnamedUnion (uentryList_new ()); } 
1261  | NotType CSTRUCT newId NotType { $$ = handleStruct ($3); } 
1262  | NotType CUNION  newId NotType { $$ = handleUnion ($3); }
1263
1264 NotType
1265  : { g_expectingTypeName = FALSE; }
1266
1267 structDeclList
1268  : structDecl 
1269  | macroDef { $$ = uentryList_undefined; /* bogus! */ }
1270  | structDeclList structDecl { $$ = uentryList_mergeFields ($1, $2); }
1271
1272 structDecl
1273  : completeTypeSpecifier NotType structNamedDeclList IsType TSEMI 
1274    { $$ = fixUentryList ($3, $1); }
1275  | completeTypeSpecifier IsType TSEMI 
1276    { $$ = fixUnnamedDecl ($1); }
1277
1278 structNamedDeclList 
1279  : structNamedDecl NotType                            
1280    { $$ = idDeclList_singleton ($1); }
1281  | structNamedDeclList TCOMMA structNamedDecl NotType
1282    { $$ = idDeclList_add ($1, $3); }
1283
1284 structNamedDecl  /* hack to get around namespace problems */ 
1285  : namedDecl                            { $$ = $1; }
1286  | TCOLON IsType constantExpr           { $$ = idDecl_undefined; }
1287  | namedDecl TCOLON IsType constantExpr { $$ = $1; }
1288    /* Need the IsType in case there is a cast in the constant expression. */
1289
1290 enumSpc
1291  : NotType CENUM TLBRACE enumeratorList TRBRACE IsType 
1292    { $$ = declareUnnamedEnum ($4); }
1293  | NotType CENUM newId TLBRACE { context_pushLoc (); } enumeratorList TRBRACE IsType
1294    { context_popLoc (); $$ = declareEnum ($3, $6); }
1295  | NotType CENUM newId IsType { $$ = handleEnum ($3); }
1296
1297 enumeratorList
1298  : enumerator 
1299    { $$ = enumNameList_single ($1); }
1300  | enumeratorList TCOMMA enumerator 
1301    { $$ = enumNameList_push ($1, $3); }
1302  | enumeratorList TCOMMA
1303
1304 enumerator
1305  : newId 
1306    { uentry ue = uentry_makeEnumConstant ($1, ctype_unknown);
1307      usymtab_supGlobalEntry (ue);
1308      $$ = $1;
1309    }
1310  | newId TASSIGN IsType constantExpr 
1311    { uentry ue = uentry_makeEnumInitializedConstant ($1, ctype_unknown, $4);
1312      usymtab_supGlobalEntry (ue);
1313      $$ = $1; 
1314    }
1315
1316 optNamedDecl
1317  : namedDeclBase
1318  | optAbstractDeclBase   { $$ = idDecl_create (cstring_undefined, qtype_create ($1)); }
1319  | pointers TYPE_NAME    
1320    { 
1321      qtype qt = qtype_unknown ();
1322
1323      qtype_adjustPointers ($1, qt);
1324      $$ = idDecl_create (cstring_copy (LastIdentifier ()), qt);
1325    }
1326  | pointers optNamedDecl 
1327    { $$ = $2; qtype_adjustPointers ($1, idDecl_getTyp ($$)); }
1328
1329 namedDecl
1330  : namedDeclBase
1331  | pointers namedDeclBase 
1332    { $$ = $2; qtype_adjustPointers ($1, idDecl_getTyp ($$)); }
1333
1334 genericParamList
1335  : paramTypeList       { $$ = handleParamTypeList ($1); }
1336  | NotType paramIdList { $$ = handleParamIdList ($2); }  
1337
1338 innerMods
1339  : QCONST    { /* ignored for now */; }
1340  | QVOLATILE { ; }
1341
1342 innerModsList
1343  : innerMods { ; }
1344  | innerModsList innerMods { ; }
1345
1346 pointers
1347  : TMULT { $$ = 1; }
1348  | TMULT innerModsList { $$ = 1; }
1349  | TMULT pointers { $$ = 1 + $2; }
1350  | TMULT innerModsList pointers { $$ = 1 + $3; }
1351
1352 paramIdList
1353  : idList 
1354  | idList TCOMMA CTOK_ELIPSIS { $$ = uentryList_add ($1, uentry_makeElipsisMarker ()); }
1355
1356 idList
1357  : newId { $$ = uentryList_single (uentry_makeVariableLoc ($1, ctype_int)); }
1358  | idList TCOMMA newId { $$ = uentryList_add ($1, uentry_makeVariableLoc ($3, ctype_int)); }
1359
1360 paramTypeList
1361  : CTOK_ELIPSIS { $$ = uentryList_single (uentry_makeElipsisMarker ()); }
1362  | paramList 
1363  | paramList TCOMMA CTOK_ELIPSIS { $$ = uentryList_add ($1, uentry_makeElipsisMarker ()); }
1364
1365 paramList
1366  : { storeLoc (); } paramDecl { $$ = uentryList_single ($2); }
1367  | paramList TCOMMA { storeLoc (); } paramDecl 
1368    { $$ = uentryList_add ($1, $4); }
1369
1370 paramDecl
1371  : IsType completeTypeSpecifier optNamedDecl IsType
1372    { 
1373      if (isFlipOldStyle ()) 
1374        { 
1375          llparseerror (cstring_makeLiteral ("Inconsistent function parameter syntax (mixing old and new style declaration)")); 
1376        }
1377      else 
1378        { 
1379          setNewStyle (); 
1380        }
1381      $$ = makeCurrentParam (idDecl_fixParamBase ($3, $2)); 
1382    }
1383  | newId /* its an old-style declaration */
1384    { 
1385      idDecl tparam = idDecl_create ($1, qtype_unknown ());
1386
1387      if (isNewStyle ()) 
1388        {
1389          llparseerror (message ("Inconsistent function parameter syntax: %q",
1390                                 idDecl_unparse (tparam))); 
1391        }
1392
1393      setFlipOldStyle ();
1394      $$ = makeCurrentParam (tparam);
1395      idDecl_free (tparam);
1396    } 
1397
1398 typeExpression
1399  : completeType
1400  | completeType abstractDecl  { $$ = qtype_newBase ($1, $2); }
1401
1402 abstractDecl
1403  : pointers { $$ = ctype_adjustPointers ($1, ctype_unknown); }
1404  | abstractDeclBase
1405  | pointers abstractDeclBase { $$ = ctype_adjustPointers ($1, $2); }
1406
1407 optAbstractDeclBase
1408  : /* empty */ { $$ = ctype_unknown; }
1409  | abstractDeclBase 
1410
1411 abstractDeclBase
1412  : IsType TLPAREN NotType abstractDecl TRPAREN 
1413    { $$ = ctype_expectFunction ($4); }
1414  | TLSQBR TRSQBR { $$ = ctype_makeArray (ctype_unknown); }
1415  | TLSQBR constantExpr TRSQBR 
1416    { $$ = ctype_makeFixedArray (ctype_unknown, exprNode_getLongValue ($2)); }
1417  | abstractDeclBase TLSQBR TRSQBR { $$ = ctype_makeArray ($1); }
1418  | abstractDeclBase TLSQBR constantExpr TRSQBR 
1419    { $$ = ctype_makeFixedArray ($1, exprNode_getLongValue ($3)); }
1420  | IsType TLPAREN TRPAREN 
1421    { $$ = ctype_makeFunction (ctype_unknown, uentryList_makeMissingParams ()); }
1422  | IsType TLPAREN paramTypeList TRPAREN 
1423    { $$ = ctype_makeParamsFunction (ctype_unknown, $3); }
1424  | abstractDeclBase IsType TLPAREN TRPAREN 
1425    { $$ = ctype_makeFunction ($1, uentryList_makeMissingParams ()); }  
1426  | abstractDeclBase IsType TLPAREN paramTypeList TRPAREN 
1427    { $$ = ctype_makeParamsFunction ($1, $4); }  
1428
1429 /* statement */
1430
1431 stmt
1432  : labeledStmt 
1433  | caseStmt 
1434  | defaultStmt
1435  | compoundStmt 
1436  | expressionStmt
1437  | selectionStmt 
1438  | iterationStmt 
1439  | iterStmt
1440  | jumpStmt 
1441 /* | lclintassertion {$$ = $1; printf ("Doing stmt lclintassertion\n"); }*/
1442
1443 /*
1444 lclintassertion
1445  : QSETBUFFERSIZE id CCONSTANT QENDMACRO { printf(" QSETBUFFERSIZE id CCONSTANT HEllo World\n");  uentry_setBufferSize($2, $3); $$ = exprNode_createTok ($4);
1446   }
1447  | QSETSTRINGLENGTH id CCONSTANT QENDMACRO { printf(" QSETSTRINGLENGTH id CCONSTANT HEllo World\n");  uentry_setStringLength($2, $3); $$ = exprNode_createTok ($4);
1448   }
1449  | QTESTINRANGE id CCONSTANT QENDMACRO {printf(" QTESTINRANGE\n");  uentry_testInRange($2, $3); $$ = exprNode_createTok ($4);
1450   }
1451
1452 /* | QSETBUFFERSIZE id id  {$$ = $2; printf(" QSETBUFFERSIZE id id HEllo World\n");} */
1453
1454 iterBody
1455  : iterDefStmtList { $$ = $1; }
1456
1457 endBody
1458  : iterBody
1459
1460 iterDefStmtList
1461  : iterDefStmt                 
1462  | iterDefStmtList iterDefStmt 
1463    { $$ = exprNode_concat ($1, $2); }
1464
1465 iterDefIterationStmt
1466  : iterWhilePred iterDefStmtList         
1467    { $$ = exprNode_while ($1, $2); }
1468  | doHeader stmtErr WHILE TLPAREN expr TRPAREN TSEMI 
1469    { $$ = exprNode_doWhile ($2, $5); }
1470  | doHeader stmtErr WHILE TLPAREN expr TRPAREN
1471    { $$ = exprNode_doWhile ($2, $5); }
1472  | forPred iterDefStmt
1473    { $$ = exprNode_for ($1, $2); } 
1474
1475 forPred
1476  : CFOR TLPAREN optExpr TSEMI optExpr TSEMI 
1477    { context_setProtectVars (); } optExpr { context_sizeofReleaseVars (); }
1478    TRPAREN 
1479    { $$ = exprNode_forPred ($3, $5, $8); 
1480      context_enterForClause ($5); }
1481
1482 partialIterStmt
1483  : ITER_NAME CreateInnerScope TLPAREN 
1484    { setProcessingIterVars ($1); } 
1485    iterArgList TRPAREN 
1486    { $$ = exprNode_iterStart ($1, $5); }
1487  | ITER_ENDNAME { $$ = exprNode_createId ($1); }
1488
1489 iterDefStmt
1490  : labeledStmt 
1491  | caseStmt 
1492  | defaultStmt
1493  | openScope initializerList { $$ = $1; DPRINTF (("def stmt: %s", exprNode_unparse ($$))); }
1494  | openScope
1495  | closeScope
1496  | expressionStmt
1497  | iterSelectionStmt 
1498  | iterDefIterationStmt 
1499  | partialIterStmt
1500  | jumpStmt 
1501  | TLPAREN iterDefStmt TRPAREN { $$ = $2; }
1502  | error { $$ = exprNode_makeError (); }
1503
1504 iterSelectionStmt
1505  : ifPred { exprNode_checkIfPred ($1); } iterDefStmt 
1506    { /* don't: context_exitTrueClause ($1, $2); */
1507      $$ = exprNode_if ($1, $3); 
1508    }
1509
1510 openScope
1511  : CreateInnerScope TLBRACE { $$ = exprNode_createTok ($2); }
1512
1513 closeScope
1514  : DeleteInnerScopeSafe TRBRACE { $$ = exprNode_createTok ($2); }
1515
1516 macroBody
1517  : stmtErr    
1518  | stmtListErr
1519  
1520 stmtErr
1521  : labeledStmt
1522  | caseStmt 
1523  | defaultStmt 
1524  | compoundStmtErr
1525  | expressionStmtErr
1526  | selectionStmt 
1527  | iterStmt
1528  | iterationStmtErr
1529  | TLPAREN stmtErr TRPAREN { $$ = exprNode_addParens ($1, $2); }
1530  | jumpStmt 
1531  | error { $$ = exprNode_makeError (); }
1532
1533 labeledStmt
1534  : newId TCOLON      { $$ = exprNode_labelMarker ($1); }
1535  | QNOTREACHED stmt  { $$ = exprNode_notReached ($2); }
1536
1537 /*
1538 ** We allow more than one QFALLTHROUGH token to support mixed lint/splint markers.
1539 */
1540
1541 optExtraFallThroughs
1542  : /* empty */ { ; }
1543  | QFALLTHROUGH optExtraFallThroughs { ; }
1544
1545 /* Note that we can semantically check that the object to the case is
1546  indeed constant. In this case, we may not want to go through this effort */
1547
1548 caseStmt
1549  : CASE constantExpr { context_enterCaseClause ($2); } 
1550    TCOLON            { $$ = exprNode_caseMarker ($2, FALSE); }
1551  | QFALLTHROUGH optExtraFallThroughs CASE constantExpr { context_enterCaseClause ($4); } 
1552    TCOLON            { $$ = exprNode_caseMarker ($4, TRUE); }
1553
1554 defaultStmt
1555  : DEFAULT { context_enterCaseClause (exprNode_undefined); } 
1556    TCOLON { $$ = exprNode_defaultMarker ($1, FALSE); }
1557  | QFALLTHROUGH optExtraFallThroughs DEFAULT { context_enterCaseClause (exprNode_undefined); } 
1558    TCOLON { $$ = exprNode_defaultMarker ($3, TRUE); }
1559
1560 compoundStmt
1561  : TLPAREN compoundStmt TRPAREN { $$ = $2; }
1562  | CreateInnerScope compoundStmtAux 
1563    { $$ = $2; context_exitInner ($2); }
1564
1565 compoundStmtErr
1566  : CreateInnerScope compoundStmtAuxErr DeleteInnerScope { $$ = $2; }
1567
1568 CreateInnerScope
1569  : { context_enterInnerContext (); }
1570
1571 DeleteInnerScope
1572  : { context_exitInnerPlain (); }
1573
1574 CreateStructInnerScope
1575  : { context_enterStructInnerContext (); }
1576
1577 DeleteStructInnerScope
1578  : { context_exitStructInnerContext (); }
1579
1580 DeleteInnerScopeSafe
1581  : { context_exitInnerSafe (); }
1582
1583 compoundStmtRest
1584  : TRBRACE { $$ = exprNode_createTok ($1); }
1585  | QNOTREACHED TRBRACE { $$ = exprNode_notReached (exprNode_createTok ($2)); }
1586  | stmtList TRBRACE { $$ = exprNode_updateLocation ($1, lltok_getLoc ($2)); }
1587  | stmtList QNOTREACHED TRBRACE 
1588    { $$ = exprNode_notReached (exprNode_updateLocation ($1, lltok_getLoc ($3))); }
1589  | initializerList TRBRACE { $$ = exprNode_updateLocation ($1, lltok_getLoc ($2)); }
1590  | initializerList QNOTREACHED TRBRACE 
1591    { $$ = exprNode_notReached (exprNode_updateLocation ($1, lltok_getLoc ($3))); }
1592  | initializerList stmtList TRBRACE
1593    { $$ = exprNode_updateLocation (exprNode_concat ($1, $2), lltok_getLoc ($3)); }
1594  | initializerList stmtList QNOTREACHED TRBRACE
1595    { $$ = exprNode_notReached (exprNode_updateLocation (exprNode_concat ($1, $2), 
1596                                                         lltok_getLoc ($3))); 
1597    }
1598
1599 compoundStmtAux
1600  : TLBRACE compoundStmtRest 
1601    { $$ = exprNode_makeBlock ($2); }
1602
1603 compoundStmtAuxErr
1604  : TLBRACE TRBRACE 
1605    { $$ = exprNode_createTok ($2); }
1606  | TLBRACE stmtListErr TRBRACE 
1607    { $$ = exprNode_updateLocation ($2, lltok_getLoc ($3)); }
1608  | TLBRACE initializerList TRBRACE 
1609    { $$ = exprNode_updateLocation ($2, lltok_getLoc ($3)); }
1610  | TLBRACE initializerList stmtList TRBRACE 
1611    { $$ = exprNode_updateLocation (exprNode_concat ($2, $3), lltok_getLoc ($4)); }
1612
1613 stmtListErr
1614  : stmtErr 
1615  | stmtListErr stmtErr { $$ = exprNode_concat ($1, $2); }
1616
1617 initializerList
1618  : initializer { $$ = $1; }
1619  | initializerList initializer { $$ = exprNode_concat ($1, $2); }
1620
1621 stmtList
1622  : stmt { $$ = $1; }
1623  | stmtList stmt { $$ = exprNode_concat ($1, $2); }
1624  
1625 expressionStmt 
1626  : TSEMI { $$ = exprNode_createTok ($1); }
1627  | expr TSEMI { $$ = exprNode_statement ($1, $2); }
1628
1629 expressionStmtErr
1630  : TSEMI { $$ = exprNode_createTok ($1); }
1631  | expr TSEMI { $$ = exprNode_statement ($1, $2); }
1632  | expr { $$ = exprNode_checkExpr ($1); } 
1633
1634 ifPred
1635  : CIF TLPAREN expr TRPAREN 
1636    { 
1637      exprNode_produceGuards ($3); context_enterTrueClause ($3); 
1638      exprNode_checkIfPred ($3);
1639      $$ = $3;
1640    }
1641
1642  /*
1643  ** not ANSI: | CIF TLPAREN compoundStmt TRPAREN 
1644  **             { $$ = $3; context_enterTrueClause (); } 
1645  */
1646
1647 selectionStmt
1648  : ifPred stmt 
1649    { 
1650      context_exitTrueClause ($1, $2);
1651      $$ = exprNode_if ($1, $2); 
1652    }
1653  | ifPred stmt CELSE  { context_enterFalseClause ($1); } stmt 
1654    {
1655      context_exitClause ($1, $2, $5);
1656      $$ = exprNode_ifelse ($1, $2, $5); 
1657    }
1658  | SWITCH TLPAREN expr { context_enterSwitch ($3); } 
1659    TRPAREN stmt        { $$ = exprNode_switch ($3, $6); }
1660  
1661 whilePred
1662  : WHILE TLPAREN expr TRPAREN 
1663    { $$ = exprNode_whilePred ($3); context_enterWhileClause ($3); }
1664    /* not ANSI: | WHILE TLPAREN compoundStmt TRPAREN stmt { $$ = exprNode_while ($3, $5); } */
1665
1666 iterWhilePred
1667  : WHILE TLPAREN expr TRPAREN { $$ = exprNode_whilePred($3); }
1668
1669 iterStmt
1670  : ITER_NAME { context_enterIterClause (); } 
1671    CreateInnerScope TLPAREN { setProcessingIterVars ($1); } 
1672    iterArgList TRPAREN 
1673    compoundStmt endIter DeleteInnerScope
1674    { 
1675      $$ = exprNode_iter ($1, $6, $8, $9); 
1676
1677    } 
1678  
1679 iterArgList 
1680  : iterArgExpr { $$ = exprNodeList_singleton ($1); }
1681  | iterArgList { nextIterParam (); } TCOMMA iterArgExpr 
1682    { $$ = exprNodeList_push ($1, $4); }
1683
1684 iterArgExpr
1685   : assignIterExpr  { $$ = exprNode_iterExpr ($1); }
1686   | id              { $$ = exprNode_iterId ($1); }
1687   | TYPE_NAME_OR_ID { uentry ue = coerceIterId ($1);
1688
1689                       if (uentry_isValid (ue)) 
1690                         {
1691                           $$ = exprNode_iterId (ue);
1692                         }
1693                       else
1694                         {
1695                           $$ = exprNode_iterNewId (cstring_copy (LastIdentifier ()));
1696                         }
1697                     }
1698   | NEW_IDENTIFIER  { $$ = exprNode_iterNewId ($1); }
1699
1700 /*
1701 ** everything is the same, EXCEPT it cannot be a NEW_IDENTIFIER 
1702 */
1703
1704 cconstantExpr
1705  : CCONSTANT
1706  | cconstantExpr CCONSTANT { $$ = exprNode_combineLiterals ($1, $2); }  
1707
1708 primaryIterExpr
1709  : cconstantExpr 
1710  | TLPAREN expr TRPAREN { $$ = exprNode_addParens ($1, $2); }
1711  
1712 postfixIterExpr
1713  : primaryIterExpr 
1714  | postfixExpr TLSQBR expr TRSQBR { $$ = exprNode_arrayFetch ($1, $3); }
1715  | postfixExpr TLPAREN TRPAREN { $$ = exprNode_functionCall ($1, exprNodeList_new ()); }
1716  | postfixExpr TLPAREN argumentExprList TRPAREN { $$ = exprNode_functionCall ($1, $3); }
1717  | VA_ARG TLPAREN assignExpr TCOMMA typeExpression TRPAREN
1718        { $$ = exprNode_vaArg ($1, $3, $5); }
1719  | postfixExpr NotType TDOT newId IsType { $$ = exprNode_fieldAccess ($1, $3, $4); }
1720  | postfixExpr NotType ARROW_OP newId IsType { $$ = exprNode_arrowAccess ($1, $3, $4); }
1721  | postfixExpr INC_OP { $$ = exprNode_postOp ($1, $2); }
1722  | postfixExpr DEC_OP { $$ = exprNode_postOp ($1, $2); }
1723  
1724 unaryIterExpr
1725  : postfixIterExpr 
1726  | INC_OP unaryExpr    { $$ = exprNode_preOp ($2, $1); }
1727  | DEC_OP unaryExpr    { $$ = exprNode_preOp ($2, $1); }
1728  | TAMPERSAND castExpr { $$ = exprNode_preOp ($2, $1); }
1729  | TMULT castExpr      { $$ = exprNode_preOp ($2, $1); }
1730  | TPLUS castExpr      { $$ = exprNode_preOp ($2, $1); }
1731  | TMINUS castExpr     { $$ = exprNode_preOp ($2, $1); }
1732  | TTILDE castExpr     { $$ = exprNode_preOp ($2, $1); }
1733  | TEXCL castExpr      { $$ = exprNode_preOp ($2, $1); }
1734  | sizeofExpr          { $$ = $1; }
1735
1736 castIterExpr
1737  : unaryIterExpr 
1738  | TLPAREN typeExpression TRPAREN castExpr { $$ = exprNode_cast ($1, $4, $2); } 
1739  
1740 timesIterExpr
1741  : castIterExpr 
1742  | timesExpr TMULT castExpr { $$ = exprNode_op ($1, $3, $2); }
1743  | timesExpr TDIV castExpr { $$ = exprNode_op ($1, $3, $2); }
1744  | timesExpr TPERCENT castExpr { $$ = exprNode_op ($1, $3, $2); }
1745
1746 plusIterExpr
1747  : timesIterExpr 
1748  | plusExpr TPLUS timesExpr { $$ = exprNode_op ($1, $3, $2); }
1749  | plusExpr TMINUS timesExpr { $$ = exprNode_op ($1, $3, $2); }
1750
1751 shiftIterExpr
1752  : plusIterExpr 
1753  | shiftExpr LEFT_OP plusExpr { $$ = exprNode_op ($1, $3, $2); }
1754  | shiftExpr RIGHT_OP plusExpr { $$ = exprNode_op ($1, $3, $2); }
1755
1756 relationalIterExpr
1757  : shiftIterExpr 
1758  | relationalExpr TLT shiftExpr { $$ = exprNode_op ($1, $3, $2); }
1759  | relationalExpr TGT shiftExpr { $$ = exprNode_op ($1, $3, $2); }
1760  | relationalExpr LE_OP shiftExpr { $$ = exprNode_op ($1, $3, $2); }
1761  | relationalExpr GE_OP shiftExpr { $$ = exprNode_op ($1, $3, $2); }
1762  
1763 equalityIterExpr 
1764  : relationalIterExpr 
1765  | equalityExpr EQ_OP relationalExpr { $$ = exprNode_op ($1, $3, $2); }
1766  | equalityExpr NE_OP relationalExpr { $$ = exprNode_op ($1, $3, $2); }
1767
1768 bitandIterExpr
1769  : equalityIterExpr 
1770  | bitandExpr TAMPERSAND equalityExpr { $$ = exprNode_op ($1, $3, $2); }
1771
1772 xorIterExpr
1773  : bitandIterExpr 
1774  | xorExpr TCIRC bitandExpr { $$ = exprNode_op ($1, $3, $2); }
1775
1776
1777 bitorIterExpr
1778  : xorIterExpr 
1779  | bitorExpr TBAR xorExpr { $$ = exprNode_op ($1, $3, $2); }
1780
1781 andIterExpr 
1782  : bitorIterExpr 
1783  | andExpr AND_OP bitorExpr { $$ = exprNode_op ($1, $3, $2); }
1784
1785 orIterExpr
1786  : andIterExpr 
1787  | orExpr OR_OP andExpr { $$ = exprNode_op ($1, $3, $2); }
1788
1789 conditionalIterExpr 
1790  : orIterExpr 
1791  | orExpr TQUEST { context_enterTrueClause ($1); } 
1792    expr TCOLON { context_enterFalseClause ($1); } conditionalExpr
1793    { $$ = exprNode_cond ($1, $4, $7); }
1794
1795 assignIterExpr
1796  : conditionalIterExpr 
1797  | unaryExpr TASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
1798  | unaryExpr MUL_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
1799  | unaryExpr DIV_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
1800  | unaryExpr MOD_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
1801  | unaryExpr ADD_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
1802  | unaryExpr SUB_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
1803  | unaryExpr LEFT_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
1804  | unaryExpr RIGHT_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
1805  | unaryExpr AND_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
1806  | unaryExpr XOR_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
1807  | unaryExpr OR_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } 
1808
1809 endIter
1810  : ITER_ENDNAME { $$ = $1; }
1811  | /* empty */  { $$ = uentry_undefined; } 
1812
1813 doHeader
1814  : DO { context_enterDoWhileClause (); $$ = $1; }
1815   
1816 iterationStmt 
1817  : whilePred stmt 
1818    { $$ = exprNode_while ($1, $2); context_exitWhileClause ($1, $2); }
1819  | doHeader stmt WHILE TLPAREN expr TRPAREN TSEMI 
1820    { $$ = exprNode_statement (exprNode_doWhile ($2, $5), $7); }
1821  | forPred stmt 
1822    { $$ = exprNode_for ($1, $2); context_exitForClause ($1, $2); }
1823
1824 iterationStmtErr 
1825  : whilePred stmtErr { $$ = exprNode_while ($1, $2); context_exitWhileClause ($1, $2); }
1826  | doHeader stmtErr WHILE TLPAREN expr TRPAREN TSEMI
1827    { $$ = exprNode_statement (exprNode_doWhile ($2, $5), $7); }
1828  | doHeader stmtErr WHILE TLPAREN expr TRPAREN 
1829    { $$ = exprNode_doWhile ($2, $5); }
1830  | forPred stmtErr { $$ = exprNode_for ($1, $2); context_exitForClause ($1, $2); }
1831  
1832 jumpStmt
1833  : GOTO newId TSEMI         { $$ = exprNode_goto ($2); }
1834  | CONTINUE TSEMI           { $$ = exprNode_continue ($1, BADTOK); }
1835  | QINNERCONTINUE CONTINUE TSEMI    
1836                             { $$ = exprNode_continue ($1, QINNERCONTINUE); }
1837  | BREAK TSEMI              { $$ = exprNode_break ($1, BADTOK); }
1838  | QSWITCHBREAK BREAK TSEMI { $$ = exprNode_break ($2, QSWITCHBREAK); }
1839  | QLOOPBREAK BREAK TSEMI   { $$ = exprNode_break ($2, QLOOPBREAK); }
1840  | QINNERBREAK BREAK TSEMI  { $$ = exprNode_break ($2, QINNERBREAK); }
1841  | QSAFEBREAK BREAK TSEMI   { $$ = exprNode_break ($2, QSAFEBREAK); }
1842  | RETURN TSEMI             { $$ = exprNode_nullReturn ($1); }
1843  | RETURN expr TSEMI        { $$ = exprNode_return ($2); }
1844  
1845 optSemi
1846  : 
1847  | TSEMI { ; } 
1848
1849 id
1850  : IDENTIFIER 
1851
1852 newId
1853  : NEW_IDENTIFIER 
1854  | ITER_NAME       { $$ = uentry_getName ($1); }
1855  | ITER_ENDNAME    { $$ = uentry_getName ($1); }
1856  | id              { $$ = uentry_getName ($1); }
1857  | TYPE_NAME_OR_ID { $$ = $1; } 
1858
1859 typeName
1860  : TYPE_NAME
1861  | TYPE_NAME_OR_ID { $$ = ctype_unknown; }
1862
1863 %%
1864
1865 /*@-redecl@*/ /*@-namechecks@*/
1866 extern char *yytext;
1867 /*@=redecl@*/ /*@=namechecks@*/
1868
1869 # include "bison.reset"
1870
1871 void yyerror (/*@unused@*/ char *s) 
1872 {
1873   static bool givehint = FALSE;
1874
1875   if (context_inIterDef ())
1876     {
1877       llerror (FLG_SYNTAX, message ("Iter syntax not parseable: %s", 
1878                                     context_inFunctionName ()));
1879     }
1880   else if (context_inIterEnd ())
1881     {
1882       llerror (FLG_SYNTAX, message ("Iter finalizer syntax not parseable: %s", 
1883                                     context_inFunctionName ()));
1884     }
1885   else if (context_inMacro ())
1886     {
1887       llerror (FLG_SYNTAX, message ("Macro syntax not parseable: %s", 
1888                                     context_inFunctionName ()));
1889       
1890       if (context_inUnknownMacro ())
1891         {
1892           if (!givehint)
1893             {
1894               llhint (cstring_makeLiteral 
1895                      ("Precede macro definition with /*@notfunction@*/ "
1896                       "to suppress checking and force expansion"));
1897               givehint = TRUE;
1898             }
1899         }
1900
1901       swallowMacro ();
1902       context_exitAllClausesQuiet ();
1903     }
1904   else
1905     {
1906       llparseerror (cstring_undefined);
1907     }
1908 }
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
This page took 1.526796 seconds and 5 git commands to generate.