X-Git-Url: http://andersk.mit.edu/gitweb/splint.git/blobdiff_plain/b87215ab641c38a5509a608751384ebb9f4f8bf9..35b9a1d988c06908076e3a6eeae55b1147879607:/src/cgrammar.y diff --git a/src/cgrammar.y b/src/cgrammar.y index 1b18b8b..e91de36 100644 --- a/src/cgrammar.y +++ b/src/cgrammar.y @@ -1,6 +1,6 @@ /*;-*-C-*-; ** Splint - annotation-assisted static program checker -** Copyright (C) 1994-2002 University of Virginia, +** Copyright (C) 1994-2003 University of Virginia, ** Massachusetts Institute of Technology ** ** This program is free software; you can redistribute it and/or modify it @@ -47,12 +47,12 @@ /*@=allmacros@*/ extern int yylex (); -extern void swallowMacro (void); extern void yyerror (char *); # include "splintMacros.nf" # include "basic.h" # include "cscanner.h" +# include "cscannerHelp.h" # include "cgrammar.h" # include "exprChecks.h" @@ -94,7 +94,7 @@ extern void yyerror (char *); /*@only@*/ modifiesClause modsclause; /*@only@*/ warnClause warnclause; /*@only@*/ stateClause stateclause; - + /*@only@*/ pointers pointers; /*@only@*/ functionConstraint fcnconstraint; /*@only@*/ metaStateConstraint msconstraint; @@ -183,14 +183,14 @@ extern void yyerror (char *); %token QNOTREACHED /* type qualifiers: */ -%token QCONST QVOLATILE QINLINE QEXTENSION QEXTERN QSTATIC QAUTO QREGISTER +%token QCONST QRESTRICT QVOLATILE QINLINE QEXTENSION QEXTERN QSTATIC QAUTO QREGISTER %token QOUT QIN QYIELD QONLY QTEMP QSHARED QREF QUNIQUE %token QCHECKED QUNCHECKED QCHECKEDSTRICT QCHECKMOD %token QKEEP QKEPT QPARTIAL QSPECIAL QOWNED QDEPENDENT %token QRETURNED QEXPOSED QNULL QOBSERVER QISNULL %token QEXITS QMAYEXIT QNEVEREXIT QTRUEEXIT QFALSEEXIT %token QLONG QSIGNED QUNSIGNED QSHORT QUNUSED QSEF QNOTNULL QRELNULL -%token QABSTRACT QCONCRETE QMUTABLE QIMMUTABLE +%token QABSTRACT QNUMABSTRACT QCONCRETE QMUTABLE QIMMUTABLE %token QTRUENULL QFALSENULL QEXTERNAL %token QREFCOUNTED QREFS QNEWREF QTEMPREF QKILLREF QRELDEF %token CGCHAR CBOOL CINT CGFLOAT CDOUBLE CVOID @@ -237,7 +237,7 @@ extern void yyerror (char *); %token METASTATE_NAME %type metaStateName %type enumerator newId /*@-varuse@*/ /* yacc declares yytranslate here */ -%type pointers /*@=varuse@*/ +%type pointers /*@=varuse@*/ %type doHeader stateTag conditionTag startConditionClause %type exitsQualifier checkQualifier stateQualifier @@ -260,7 +260,7 @@ extern void yyerror (char *); %type genericParamList paramTypeList paramList idList paramIdList %type argumentExprList iterArgList -%type initList namedInitializerList namedInitializerListAux +%type initList namedInitializerList namedInitializerListAux namedInitializerTypeList namedInitializerTypeListAux %type structDeclList structDecl %type locModifies modList specClauseList optSpecClauseList %type mExpr modListExpr specClauseListExpr @@ -290,7 +290,7 @@ extern void yyerror (char *); %type sizeofExpr sizeofExprAux offsetofExpr %type openScope closeScope -%type instanceDecl namedInitializer optDeclarators +%type instanceDecl namedInitializer optDeclarators namedInitializerType %type primaryExpr postfixExpr primaryIterExpr postfixIterExpr %type unaryExpr castExpr timesExpr plusExpr %type unaryIterExpr castIterExpr timesIterExpr plusIterExpr @@ -312,8 +312,8 @@ extern void yyerror (char *); %type designator designatorList designation -%type storageSpecifier typeQualifier typeModifier globQual -%type optGlobQuals +%type storageSpecifier typeQualifier typeModifier globQual innerMods +%type optGlobQuals innerModsList %type completeType completeTypeSpecifier optCompleteType %type completeTypeSpecifierAux altType typeExpression @@ -324,10 +324,12 @@ extern void yyerror (char *); file : | externalDefs + ; externalDefs : externalDef { context_checkGlobalScope (); } | externalDefs externalDef { context_checkGlobalScope (); } + ; externalDef : fcnDef optSemi { uentry_clearDecl (); } @@ -336,21 +338,25 @@ externalDef | iterDecl { uentry_clearDecl (); } | macroDef { uentry_clearDecl (); } | initializer { uentry_checkDecl (); exprNode_free ($1); } - | TSEMI { uentry_clearDecl (); /* evans 2002-02-08: okay to have a null statement */ } + | TSEMI { uentry_clearDecl (); lltok_free ($1); /* evans 2002-02-08: okay to have a null statement */ } | error { uentry_clearDecl (); } + ; constantDecl : QCONSTANT completeTypeSpecifier NotType namedDecl NotType optSemi IsType QENDMACRO - { checkConstant ($2, $4); } + { checkConstant ($2, $4); lltok_free2 ($1, $8); } | QCONSTANT completeTypeSpecifier NotType namedDecl NotType TASSIGN IsType init optDeclarators optSemi QENDMACRO - { checkValueConstant ($2, $4, $8) ; } + { checkValueConstant ($2, $4, $8); lltok_free3 ($1, $6, $11); } +; fcnDecl : QFUNCTION { context_enterFunctionHeader (); } plainFcn optSemi QENDMACRO { declareStaticFunction ($3); context_quietExitFunction (); context_exitFunctionHeader (); + lltok_free2 ($1, $5); /*!*/ } +; plainFcn : plainNamedDecl @@ -361,18 +367,20 @@ plainFcn } | completeTypeSpecifier NotType plainNamedDecl { $$ = idDecl_fixBase ($3, $1); } +; plainNamedDecl : plainNamedDeclBase | pointers plainNamedDeclBase { $$ = $2; qtype_adjustPointers ($1, idDecl_getTyp ($$)); } +; namedDeclBase : newId { $$ = idDecl_create ($1, qtype_unknown ()); } | IsType TLPAREN NotType namedDecl IsType TRPAREN - { $$ = idDecl_expectFunction ($4); } + { $$ = idDecl_expectFunction ($4); lltok_free2 ($2, $6); } | namedDeclBase TLSQBR TRSQBR - { $$ = idDecl_replaceCtype ($1, ctype_makeInnerArray (idDecl_getCtype ($1))); } + { $$ = idDecl_replaceCtype ($1, ctype_makeInnerArray (idDecl_getCtype ($1))); lltok_free2 ($2, $3); } | namedDeclBase TLSQBR IsType constantExpr TRSQBR NotType { exprNode_findValue ($4); @@ -387,36 +395,77 @@ namedDeclBase { $$ = idDecl_replaceCtype ($1, ctype_makeInnerArray (idDecl_getCtype ($1))); } + + lltok_free2 ($2, $5); } | namedDeclBase PushType TLPAREN TRPAREN { setCurrentParams (uentryList_missingParams); } functionClauses { /* need to support globals and modifies here! */ + functionClauseList fcl; ctype ct = ctype_makeFunction (idDecl_getCtype ($1), uentryList_makeMissingParams ()); $$ = idDecl_replaceCtype ($1, ct); - idDecl_addClauses ($$, $6); - context_popLoc (); + /*drl 7/25/01 added*/ setImplictfcnConstraints(); + + DPRINTF((message("namedDeclBase PushType TLPAREN TRPAREN...:\n adding implict constraints to functionClause List: %s", + functionClauseList_unparse($6) + ) + )); + + fcl = functionClauseList_setImplictConstraints($6); + + idDecl_addClauses ($$, fcl); + + DPRINTF((message("1 added fuctionClause List: %s to the Id", + functionClauseList_unparse(fcl) + ) + )); + + + context_popLoc (); + lltok_free2 ($3, $4); } | namedDeclBase PushType TLPAREN genericParamList TRPAREN { setCurrentParams ($4); } functionClauses - { setImplictfcnConstraints (); + { + functionClauseList fcl; + setImplictfcnConstraints (); clearCurrentParams (); $$ = idDecl_replaceCtype ($1, ctype_makeFunction (idDecl_getCtype ($1), $4)); - idDecl_addClauses ($$, $7); + + DPRINTF((message("namedDeclBase PushType TLPAREN genericParamList TRPAREN...:\n adding implict constraints to functionClause List: %s", + functionClauseList_unparse($7) + ) + )) ; + + fcl = functionClauseList_setImplictConstraints($7); + + idDecl_addClauses ($$, fcl); + + DPRINTF((message("added fuctionClause List: %s to the Id", + functionClauseList_unparse(fcl) + ) + )); + + context_popLoc (); + lltok_free2 ($3, $5); } +; plainNamedDeclBase : newId { $$ = idDecl_create ($1, qtype_unknown ()); } | IsType TLPAREN NotType plainNamedDecl IsType TRPAREN - { $$ = idDecl_expectFunction ($4); } + { $$ = idDecl_expectFunction ($4); lltok_free2 ($2, $6); } | plainNamedDeclBase TLSQBR TRSQBR - { $$ = idDecl_replaceCtype ($1, ctype_makeInnerArray (idDecl_getCtype ($1))); } + { $$ = idDecl_replaceCtype ($1, ctype_makeInnerArray (idDecl_getCtype ($1))); + lltok_free2 ($2, $3); + } | plainNamedDeclBase TLSQBR IsType constantExpr TRSQBR NotType { int value; @@ -432,6 +481,7 @@ plainNamedDeclBase } $$ = idDecl_replaceCtype ($1, ctype_makeInnerFixedArray (idDecl_getCtype ($1), value)); + lltok_free2 ($2, $5); } | plainNamedDeclBase PushType TLPAREN TRPAREN { setCurrentParams (uentryList_missingParams); } @@ -443,6 +493,7 @@ plainNamedDeclBase $$ = idDecl_replaceCtype ($1, ct); idDecl_addClauses ($$, $6); context_popLoc (); + lltok_free2 ($3, $4); } | plainNamedDeclBase PushType TLPAREN genericParamList TRPAREN { setCurrentParams ($4); } @@ -452,65 +503,86 @@ plainNamedDeclBase $$ = idDecl_replaceCtype ($1, ctype_makeFunction (idDecl_getCtype ($1), $4)); idDecl_addClauses ($$, $7); context_popLoc (); + lltok_free ($3); + /*!! lltok_free2 ($3, $5); */ } +; iterDecl : QITER newId TLPAREN genericParamList TRPAREN { setCurrentParams ($4); } functionClausesPlain { clearCurrentParams (); } optSemi QENDMACRO - { declareCIter ($2, $4); } + { declareCIter ($2, $4); + lltok_free3 ($1, $3, $5); + } +; macroDef - : LLMACRO macroBody TENDMACRO { exprNode_checkMacroBody ($2); } - | LLMACROITER iterBody TENDMACRO { exprNode_checkIterBody ($2); } - | LLMACROEND endBody TENDMACRO { exprNode_checkIterEnd ($2); } - | LLMACRO TENDMACRO /* no stmt */ { exprChecks_checkEmptyMacroBody (); } + : LLMACRO macroBody TENDMACRO { exprNode_checkMacroBody ($2); lltok_free2 ($1, $3); } + | LLMACROITER iterBody TENDMACRO { exprNode_checkIterBody ($2); lltok_free2 ($1, $3); } + | LLMACROEND endBody TENDMACRO { exprNode_checkIterEnd ($2); lltok_free2 ($1, $3);} + | LLMACRO TENDMACRO /* no stmt */ { exprChecks_checkEmptyMacroBody (); lltok_free2 ($1, $2); } +; fcnDefHdr : fcnDefHdrAux { clabstract_declareFunction ($1); } +; metaStateConstraint : metaStateSpecifier TASSIGN metaStateExpression - { $$ = metaStateConstraint_create ($1, $3); } + { $$ = metaStateConstraint_create ($1, $3); lltok_free ($2); } +; metaStateSpecifier - : BufConstraintSrefExpr { cscanner_expectingMetaStateName (); } TCOLON metaStateName - { cscanner_clearExpectingMetaStateName (); - $$ = metaStateSpecifier_create ($1, $4); } - | CTOK_ELIPSIS { cscanner_expectingMetaStateName (); } TCOLON metaStateName - { cscanner_clearExpectingMetaStateName (); - $$ = metaStateSpecifier_createElipsis ($4); } + : BufConstraintSrefExpr { cscannerHelp_expectingMetaStateName (); } TCOLON metaStateName + { cscannerHelp_clearExpectingMetaStateName (); + $$ = metaStateSpecifier_create ($1, $4); + lltok_free ($3); + } + | CTOK_ELIPSIS { cscannerHelp_expectingMetaStateName (); } TCOLON metaStateName + { cscannerHelp_clearExpectingMetaStateName (); + $$ = metaStateSpecifier_createElipsis ($4); + lltok_free2 ($1, $3); + } +; metaStateExpression : metaStateSpecifier { $$ = metaStateExpression_create ($1); } -| metaStateSpecifier TBAR metaStateExpression { $$ = metaStateExpression_createMerge ($1, $3); } +| metaStateSpecifier TBAR metaStateExpression { $$ = metaStateExpression_createMerge ($1, $3); lltok_free ($2); } +; metaStateName : METASTATE_NAME +; /*drl*/ constraintSeperator : TCAND | AND_OP +; BufConstraintList : BufConstraint constraintSeperator BufConstraintList { $$ = constraintList_add ($3, $1); } | BufConstraint { $$ = constraintList_single ($1); } +; BufConstraint : BufConstraintExpr relationalOp BufConstraintExpr { $$ = makeConstraintParse3 ($1, $2, $3); DPRINTF(("Done BufConstraint1\n")); } +; bufferModifier : QMAXSET | QMAXREAD +; relationalOp : GE_OP | LE_OP | EQ_OP +; BufConstraintExpr : BufConstraintTerm @@ -518,10 +590,12 @@ BufConstraintExpr | TLPAREN BufConstraintExpr BufBinaryOp BufConstraintExpr TRPAREN { DPRINTF( ("Got BufConstraintExpr BINary Op ") ); $$ = constraintExpr_parseMakeBinaryOp ($2, $3, $4); } +; BufConstraintTerm : BufConstraintSrefExpr { $$ = constraintExpr_makeTermsRef ($1);} | CCONSTANT { $$ = constraintExpr_makeIntLiteral (exprNode_getLongValue ($1)); } +; BufConstraintSrefExpr : id @@ -555,6 +629,7 @@ BufConstraintSrefExpr | specClauseListExpr TDOT newId { cstring_markOwned ($3); $$ = sRef_buildField ($1, $3); } */ +; /*BufConstraintExpr : BufConstraintTerm @@ -576,6 +651,7 @@ functionClauses : { $$ = functionClauseList_new (); } | functionClause functionClauses { $$ = functionClauseList_prepend ($2, $1); } +; /* ** Inside macro definitions, there are no end macros. @@ -586,6 +662,7 @@ functionClausesPlain { $$ = functionClauseList_new (); } | functionClausePlain functionClausesPlain { $$ = functionClauseList_prepend ($2, $1); } +; functionClause : globalsClause { $$ = functionClause_createGlobals ($1); } @@ -594,6 +671,7 @@ functionClause | stateClause { $$ = functionClause_createState ($1); } | conditionClause { $$ = $1; } | warnClause { $$ = functionClause_createWarn ($1); } +; functionClausePlain : globalsClausePlain { $$ = functionClause_createGlobals ($1); } @@ -602,9 +680,11 @@ functionClausePlain | stateClausePlain { $$ = functionClause_createState ($1); } | conditionClausePlain { $$ = $1; } | warnClausePlain { $$ = functionClause_createWarn ($1); } +; globalsClause : globalsClausePlain QENDMACRO { $$ = $1; } +; globalsClausePlain : QGLOBALS { setProcessingGlobalsList (); } @@ -613,12 +693,15 @@ globalsClausePlain unsetProcessingGlobals (); $$ = globalsClause_create ($1, $3); } +; nomodsClause : QNOMODS { $$ = modifiesClause_createNoMods ($1); } +; modifiesClause : modifiesClausePlain QENDMACRO { $$ = $1; } +; modifiesClausePlain : QMODIFIES @@ -633,22 +716,27 @@ modifiesClausePlain context_releaseVars (); $$ = modifiesClause_create ($1, $3); } +; flagSpec : flagId { $$ = flagSpec_createPlain ($1); } | flagId TBAR flagSpec { $$ = flagSpec_createOr ($1, $3); } +; flagId : NEW_IDENTIFIER +; optWarnClause : warnClause | /* empty */ { $$ = warnClause_undefined; } +; warnClause : warnClausePlain QENDMACRO { $$ = $1; } +; warnClausePlain : QWARN flagSpec cconstantExpr @@ -659,22 +747,27 @@ warnClausePlain } | QWARN flagSpec { $$ = warnClause_create ($1, $2, cstring_undefined); } +; globIdList : globIdListExpr { $$ = globSet_single ($1); } | globIdList TCOMMA globIdListExpr { $$ = globSet_insert ($1, $3); } +; globIdListExpr : optGlobQuals globId { $$ = clabstract_createGlobal ($2, $1); } +; optGlobQuals : /* empty */ { $$ = qualList_undefined; } | globQual optGlobQuals { $$ = qualList_add ($2, $1); } +; globId : id { $$ = uentry_getSref ($1); } | NEW_IDENTIFIER { $$ = clabstract_unrecognizedGlobal ($1); } | initializer { $$ = clabstract_checkGlobal ($1); } +; globQual : QUNDEF { $$ = qual_createUndef (); } @@ -682,6 +775,7 @@ globQual | QOUT { $$ = qual_createOut (); } | QIN { $$ = qual_createIn (); } | QPARTIAL { $$ = qual_createPartial (); } +; stateTag : QDEFINES @@ -689,10 +783,12 @@ stateTag | QALLOCATES | QSETS | QRELEASES +; conditionTag : QPRECLAUSE | QPOSTCLAUSE +; fcnDefHdrAux : namedDecl @@ -704,6 +800,7 @@ fcnDefHdrAux } | completeTypeSpecifier NotType namedDecl { $$ = idDecl_fixBase ($3, $1); } +; fcnBody : TLBRACE { checkDoneParams (); context_enterInnerContext (); } @@ -720,6 +817,7 @@ fcnBody $$ = $4; /* oldstyle */ context_exitInner ($4); } +; fcnDef : fcnDefHdr fcnBody @@ -730,30 +828,35 @@ fcnDef context_exitFunction (); } +; locModifies : modList optSemi { $$ = $1; } | optSemi { $$ = sRefSet_new (); } +; modListExpr : id { $$ = uentry_getSref ($1); checkModifiesId ($1); } | NEW_IDENTIFIER { $$ = fixModifiesId ($1); } + | TYPE_NAME_OR_ID { $$ = fixModifiesId ($1); } | modListExpr TLSQBR TRSQBR { $$ = modListArrayFetch ($1, sRef_undefined); } | modListExpr TLSQBR mExpr TRSQBR { $$ = modListArrayFetch ($1, $3); } | TMULT modListExpr { $$ = modListPointer ($2); } | TLPAREN modListExpr TRPAREN { $$ = $2; } | modListExpr TDOT newId { $$ = modListFieldAccess ($1, $3); } | modListExpr ARROW_OP newId { $$ = modListArrowAccess ($1, $3); } - +; mExpr : modListExpr { $$ = $1; } | cconstantExpr { $$ = sRef_makeUnknown (); /* sRef_makeConstant ($1); ? */ } /* arithmetic? */ +; modList : modListExpr { $$ = sRefSet_single ($1); } | modList TCOMMA modListExpr { $$ = sRefSet_insert ($1, $3); } +; specClauseListExpr : id @@ -768,15 +871,19 @@ specClauseListExpr $$ = sRef_buildField ($1, $3); } | specClauseListExpr ARROW_OP newId { cstring_markOwned ($3); $$ = sRef_makeArrow ($1, $3); } +; optSpecClauseList - : /* empty */ { $$ = sRefSet_undefined } + : /* empty */ { DPRINTF ((message("Empty optSpecClauseList") )); $$ = sRefSet_undefined } | specClauseList + ; specClauseList : specClauseListExpr { if (sRef_isValid ($1)) { $$ = sRefSet_single ($1); } - else { $$ = sRefSet_undefined; } + else { + DPRINTF((message("returning sRefSEt_undefined ") )); + $$ = sRefSet_undefined; } } | specClauseList TCOMMA specClauseListExpr { if (sRef_isValid ($3)) @@ -788,17 +895,19 @@ specClauseList $$ = $1; } } +; primaryExpr : id { $$ = exprNode_fromIdentifier ($1); } | NEW_IDENTIFIER { $$ = exprNode_fromUIO ($1); } | cconstantExpr | TLPAREN expr TRPAREN { $$ = exprNode_addParens ($1, $2); } - | TYPE_NAME_OR_ID { $$ = exprNode_fromIdentifier (coerceId ($1)); } + | TYPE_NAME_OR_ID { $$ = exprNode_fromIdentifier (cscannerHelp_coerceId ($1)); } | QEXTENSION { $$ = exprNode_makeError (); } | TLPAREN { exprChecks_inCompoundStatementExpression (); } compoundStmt TRPAREN { exprChecks_leaveCompoundStatementExpression (); $$ = exprNode_compoundStatementExpression ($1, $3); } +; postfixExpr : primaryExpr @@ -812,10 +921,12 @@ postfixExpr | postfixExpr DEC_OP { $$ = exprNode_postOp ($1, $2); } | TLPAREN typeExpression TRPAREN TLBRACE typeInitializerList optComma TRBRACE { /* added for C99 */ $$ = exprNode_undefined; /*@i87 no checking */ } +; argumentExprList : assignExpr { $$ = exprNodeList_singleton ($1); } | argumentExprList TCOMMA assignExpr { $$ = exprNodeList_push ($1, $3); } +; unaryExpr : postfixExpr @@ -827,47 +938,67 @@ unaryExpr | TMINUS castExpr { $$ = exprNode_preOp ($2, $1); } | TTILDE castExpr { $$ = exprNode_preOp ($2, $1); } | TEXCL castExpr { $$ = exprNode_preOp ($2, $1); } - | sizeofExpr { $$ = $1; } + | processSizeof sizeofExpr endprocessSizeof { $$ = $2; } | offsetofExpr { $$ = $1; } +; fieldDesignator - : fieldDesignator TDOT newId { $$ = cstringList_add ($1, $3); } - | newId { $$ = cstringList_single ($1); } + : fieldDesignator TDOT newId { $$ = cstringList_add ($1, $3); lltok_free ($2); } + | fieldDesignator TLSQBR expr TRSQBR { $$ = $1; lltok_free2 ($2, $4); } + /* evans 2002-07-02: offsetof designators can use array indexes */ + | newId { $$ = cstringList_single ($1); } +; offsetofExpr : COFFSETOF IsType TLPAREN typeExpression NotType TCOMMA fieldDesignator TRPAREN IsType - { $$ = exprNode_offsetof ($4, $7); } + { $$ = exprNode_offsetof ($4, $7); + lltok_free3 ($1, $3, $6); lltok_free ($8); } +; sizeofExpr : IsType { context_setProtectVars (); } sizeofExprAux { context_sizeofReleaseVars (); $$ = $3; } +; + +processSizeof: {context_enterSizeof()}; + + +endprocessSizeof: {context_leaveSizeof()}; + sizeofExprAux - : CSIZEOF TLPAREN typeExpression TRPAREN { $$ = exprNode_sizeofType ($3); } - | CSIZEOF unaryExpr { $$ = exprNode_sizeofExpr ($2); } - | CALIGNOF TLPAREN typeExpression TRPAREN { $$ = exprNode_alignofType ($3); } - | CALIGNOF unaryExpr { $$ = exprNode_alignofExpr ($2); } - + : CSIZEOF TLPAREN typeExpression TRPAREN { $$ = exprNode_sizeofType ($3); lltok_free3 ($1, $2, $4); } + | CSIZEOF unaryExpr { $$ = exprNode_sizeofExpr ($2); lltok_free ($1); } + | CALIGNOF TLPAREN typeExpression TRPAREN { $$ = exprNode_alignofType ($3); lltok_free3 ($1, $2, $4); } + | CALIGNOF unaryExpr { $$ = exprNode_alignofExpr ($2); lltok_free ($1); } +; + + + castExpr : unaryExpr | TLPAREN typeExpression TRPAREN castExpr - { $$ = exprNode_cast ($1, $4, $2); } + { $$ = exprNode_cast ($1, $4, $2); lltok_free ($3); } +; timesExpr : castExpr | timesExpr TMULT castExpr { $$ = exprNode_op ($1, $3, $2); } | timesExpr TDIV castExpr { $$ = exprNode_op ($1, $3, $2); } | timesExpr TPERCENT castExpr { $$ = exprNode_op ($1, $3, $2); } +; plusExpr : timesExpr | plusExpr TPLUS timesExpr { $$ = exprNode_op ($1, $3, $2); } | plusExpr TMINUS timesExpr { $$ = exprNode_op ($1, $3, $2); } +; shiftExpr : plusExpr | shiftExpr LEFT_OP plusExpr { $$ = exprNode_op ($1, $3, $2); } | shiftExpr RIGHT_OP plusExpr { $$ = exprNode_op ($1, $3, $2); } +; relationalExpr : shiftExpr @@ -875,15 +1006,18 @@ relationalExpr | relationalExpr TGT shiftExpr { $$ = exprNode_op ($1, $3, $2); } | relationalExpr LE_OP shiftExpr { $$ = exprNode_op ($1, $3, $2); } | relationalExpr GE_OP shiftExpr { $$ = exprNode_op ($1, $3, $2); } +; equalityExpr : relationalExpr | equalityExpr EQ_OP relationalExpr { $$ = exprNode_op ($1, $3, $2); } | equalityExpr NE_OP relationalExpr { $$ = exprNode_op ($1, $3, $2); } +; bitandExpr : equalityExpr | bitandExpr TAMPERSAND equalityExpr { $$ = exprNode_op ($1, $3, $2); } +; xorExpr : bitandExpr @@ -893,6 +1027,7 @@ xorExpr bitorExpr : xorExpr | bitorExpr TBAR xorExpr { $$ = exprNode_op ($1, $3, $2); } +; andExpr : bitorExpr @@ -905,6 +1040,7 @@ andExpr $$ = exprNode_op ($1, $4, $2); context_exitAndClause ($$, $4); } +; orExpr : andExpr @@ -918,12 +1054,14 @@ orExpr $$ = exprNode_op ($1, $4, $2); context_exitOrClause ($$, $4); } +; conditionalExpr : orExpr | orExpr TQUEST { exprNode_produceGuards ($1); context_enterTrueClause ($1); } expr TCOLON { context_enterFalseClause ($1); } conditionalExpr { $$ = exprNode_cond ($1, $4, $7); context_exitClause ($1, $4, $7); } +; assignExpr : conditionalExpr @@ -938,17 +1076,21 @@ assignExpr | unaryExpr AND_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } | unaryExpr XOR_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } | unaryExpr OR_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } +; expr : assignExpr | expr TCOMMA assignExpr { $$ = exprNode_comma ($1, $3); } +; optExpr : /* empty */ { $$ = exprNode_undefined; } | expr + ; constantExpr : conditionalExpr +; /* instance_orTypeDecl_and_possible_initialization */ @@ -956,11 +1098,12 @@ initializer : instanceDecl { $$ = $1; } | VA_DCL { doVaDcl (); $$ = exprNode_makeError (); } | typeDecl { $$ = exprNode_makeError (); } +; instanceDecl : completeTypeSpecifier IsType TSEMI - { $$ = exprNode_makeError (); } - /* + { $$ = exprNode_makeError (); } + /* ** This causes r/r conflicts with function definitions. ** Instead we need to snarf one first. (gack) ** @@ -989,6 +1132,12 @@ instanceDecl { $$ = exprNode_concat ($9, exprNode_makeInitialization ($3, $8)); unsetProcessingVars (); } +; + +namedInitializerType + : namedInitializer { $$ = $1; } + | TYPE_NAME { $$ = exprNode_fromIdentifier (usymtab_getTypeEntry (ctype_typeId ($1))); } +; namedInitializer : namedDecl NotType @@ -998,36 +1147,53 @@ namedInitializer } | namedDecl NotType TASSIGN { processNamedDecl ($1); } IsType init { $$ = exprNode_makeInitialization ($1, $6); } +; typeDecl : CTYPEDEF completeTypeSpecifier { setProcessingTypedef ($2); } - NotType namedInitializerList IsType optWarnClause TSEMI + NotType namedInitializerTypeList IsType optWarnClause TSEMI { clabstract_declareType ($5, $7); } | CTYPEDEF completeTypeSpecifier IsType TSEMI { /* in the ANSI grammar, semantics unclear */ } | CTYPEDEF namedInitializerList IsType TSEMI { /* in the ANSI grammar, semantics unclear */ } +; IsType - : { g_expectingTypeName = TRUE; } + : { cscannerHelp_setExpectingTypeName (); } +; PushType - : { g_expectingTypeName = TRUE; context_pushLoc (); } + : { cscannerHelp_setExpectingTypeName (); context_pushLoc (); } +; namedInitializerList : namedInitializerListAux IsType { $$ = $1; } +; namedInitializerListAux : namedInitializer { $$ = exprNodeList_singleton ($1); } | namedInitializerList TCOMMA NotType namedInitializer { $$ = exprNodeList_push ($1, $4); } +; + +namedInitializerTypeList + : namedInitializerTypeListAux IsType { $$ = $1; } +; + +namedInitializerTypeListAux + : namedInitializerType { $$ = exprNodeList_singleton ($1); } + | namedInitializerTypeList TCOMMA NotType namedInitializerType { $$ = exprNodeList_push ($1, $4); } +; optDeclarators : /* empty */ { $$ = exprNode_makeError (); } | optDeclarators TCOMMA NotType namedInitializer { $$ = exprNode_concat ($1, $4); } +; init : assignExpr - | TLBRACE initList TRBRACE { $$ = exprNode_makeInitBlock ($1, $2); } - | TLBRACE initList TCOMMA TRBRACE { $$ = exprNode_makeInitBlock ($1, $2); } + | TLBRACE initList TRBRACE { $$ = exprNode_makeInitBlock ($1, $2); lltok_free ($3); } + | TLBRACE initList TCOMMA TRBRACE { $$ = exprNode_makeInitBlock ($1, $2); lltok_free2 ($3, $4); } | designation init { $$ = exprNode_undefined; } +; /* ** Splint parses these (added in ISO C99), but no checking yet... @@ -1037,20 +1203,24 @@ designation : designatorList TASSIGN { $$ = $1; } | newId TCOLON { $$ = exprNode_undefined; /* gcc extension, obsolete since 2.5 */ } +; designatorList : designator { $$ = exprNode_undefined; } | designatorList designator { $$ = exprNode_undefined; } +; designator : TLSQBR constantExpr TRSQBR { $$ = exprNode_undefined; } | TDOT newId { $$ = exprNode_undefined; } +; initList : init { $$ = exprNodeList_singleton ($1); } | initList TCOMMA init { $$ = exprNodeList_push ($1, $3); } +; /* ** need to do the storage class global hack so tags are @@ -1063,9 +1233,11 @@ storageSpecifier | QSTATIC { setStorageClass (SCSTATIC); $$ = qual_createStatic (); } | QAUTO { $$ = qual_createAuto (); } | QREGISTER { $$ = qual_createRegister (); } +; stateClause : stateClausePlain QENDMACRO { $$ = $1; } +; stateClausePlain : stateTag NotType @@ -1081,12 +1253,15 @@ stateClausePlain context_releaseVars (); $$ = stateClause_createPlain ($1, $4); } +; conditionClause : conditionClausePlain QENDMACRO { $$ = $1; } +; startConditionClause : conditionTag NotType { $$ = $1; context_enterFunctionHeader (); } +; conditionClausePlain : startConditionClause stateQualifier @@ -1132,10 +1307,12 @@ conditionClausePlain DPRINTF (("FunctionclauseS: %s", functionClause_unparse ($$))); } +; functionConstraint : BufConstraintList { $$ = functionConstraint_createBufferConstraint ($1); } | metaStateConstraint { $$ = functionConstraint_createMetaStateConstraint ($1); DPRINTF (("Made constraint: %s", functionConstraint_unparse ($$))); } +; exitsQualifier : QEXITS { $$ = qual_createExits (); } @@ -1143,12 +1320,14 @@ exitsQualifier | QTRUEEXIT { $$ = qual_createTrueExit (); } | QFALSEEXIT { $$ = qual_createFalseExit (); } | QNEVEREXIT { $$ = qual_createNeverExit (); } +; checkQualifier : QCHECKED { $$ = qual_createChecked (); } | QCHECKMOD { $$ = qual_createCheckMod (); } | QUNCHECKED { $$ = qual_createUnchecked (); } | QCHECKEDSTRICT { $$ = qual_createCheckedStrict (); } +; stateQualifier : QOWNED { $$ = qual_createOwned (); } @@ -1168,25 +1347,30 @@ stateQualifier | QOBSERVER { $$ = qual_createObserver (); } | QNULLTERMINATED { $$ = qual_createNullTerminated (); } | CANNOTATION { $$ = qual_createMetaState ($1); } - +; paramQualifier : QRETURNED { $$ = qual_createReturned (); } | QSEF { $$ = qual_createSef (); } +; visibilityQualifier : QUNUSED { $$ = qual_createUnused (); } | QEXTERNAL { $$ = qual_createExternal (); } +; returnQualifier : QTRUENULL { $$ = qual_createTrueNull (); } | QFALSENULL { $$ = qual_createFalseNull (); } +; typedefQualifier : QABSTRACT { $$ = qual_createAbstract (); } + | QNUMABSTRACT { $$ = qual_createNumAbstract (); } | QCONCRETE { $$ = qual_createConcrete (); } | QMUTABLE { $$ = qual_createMutable (); } | QIMMUTABLE { $$ = qual_createImmutable (); } +; refcountQualifier : QREFCOUNTED { $$ = qual_createRefCounted (); } @@ -1195,22 +1379,26 @@ refcountQualifier | QRELDEF { $$ = qual_createRelDef (); } | QNEWREF { $$ = qual_createNewRef (); } | QTEMPREF { $$ = qual_createTempRef (); } +; typeModifier : QSHORT { $$ = qual_createShort (); } | QLONG { $$ = qual_createLong (); } | QSIGNED { $$ = qual_createSigned (); } | QUNSIGNED { $$ = qual_createUnsigned (); } +; definedQualifier : QOUT { $$ = qual_createOut (); } | QIN { $$ = qual_createIn (); } | QPARTIAL { $$ = qual_createPartial (); } | QSPECIAL { $$ = qual_createSpecial (); } +; typeQualifier : QCONST IsType { $$ = qual_createConst (); } | QVOLATILE IsType { $$ = qual_createVolatile (); } + | QRESTRICT IsType { $$ = qual_createRestrict (); } | definedQualifier IsType { $$ = $1; } | stateQualifier IsType { $$ = $1; } | exitsQualifier IsType { $$ = $1; } @@ -1220,6 +1408,7 @@ typeQualifier | visibilityQualifier IsType { $$ = $1; } | typedefQualifier IsType { $$ = $1; } | refcountQualifier IsType { $$ = $1; } +; /* ** This is copied into the mtgrammar! @@ -1232,7 +1421,7 @@ typeSpecifier | CGFLOAT NotType | CDOUBLE NotType | CVOID NotType - | QANYTYPE NotType { $$ = ctype_anytype; DPRINTF (("anytype: %s", ctype_unparse ($$))); } + | QANYTYPE NotType { $$ = ctype_makeAnytype (); } | QINTEGRALTYPE NotType { $$ = ctype_anyintegral; } | QUNSIGNEDINTEGRALTYPE NotType { $$ = ctype_unsignedintegral; } | QSIGNEDINTEGRALTYPE NotType { $$ = ctype_signedintegral; } @@ -1240,37 +1429,42 @@ typeSpecifier | suSpc NotType | enumSpc NotType | typeModifier NotType { $$ = ctype_fromQual ($1); } +; completeType : IsType completeTypeSpecifier IsType { $$ = qtype_resolve ($2); } +; completeTypeSpecifier : completeTypeSpecifierAux { $$ = $1; } | completeTypeSpecifierAux QALT altType QENDMACRO { $$ = qtype_mergeAlt ($1, $3); } +; altType : typeExpression | typeExpression TCOMMA altType { $$ = qtype_mergeAlt ($1, $3); } +; completeTypeSpecifierAux : storageSpecifier optCompleteType { $$ = qtype_addQual ($2, $1); } | typeQualifier optCompleteType { $$ = qtype_addQual ($2, $1); } | typeSpecifier optCompleteType { $$ = qtype_combine ($2, $1); } +; optCompleteType : /* empty */ { $$ = qtype_unknown (); } | completeTypeSpecifier { $$ = $1; } - +; optStructInvariant : /* empty */ { $$ = constraintList_undefined; } -/* don't want to have support for structure invariant until we're - sure it's stable +/* drl commenting before a CVS commit | QINVARIANT BufConstraintList QENDMACRO { $$ = $2 } */ +; suSpc : NotType CSTRUCT newId IsType TLBRACE { sRef_setGlobalScopeSafe (); } @@ -1278,7 +1472,7 @@ suSpc structDeclList DeleteStructInnerScope { sRef_clearGlobalScopeSafe (); } TRBRACE optStructInvariant - { ctype ct; ct = declareStruct ($3, $8); /* setGlobalStructInfo(ct, $12);*/ $$ = ct; } + { ctype ct; ct = declareStruct ($3, $8); context_setGlobalStructInfo(ct, $12); $$ = ct; } | NotType CUNION newId IsType TLBRACE { sRef_setGlobalScopeSafe (); } CreateStructInnerScope structDeclList DeleteStructInnerScope { sRef_clearGlobalScopeSafe (); } @@ -1304,32 +1498,38 @@ suSpc { $$ = ctype_createUnnamedUnion (uentryList_new ()); } | NotType CSTRUCT newId NotType { $$ = handleStruct ($3); } | NotType CUNION newId NotType { $$ = handleUnion ($3); } +; NotType - : { g_expectingTypeName = FALSE; } +: { cscannerHelp_clearExpectingTypeName (); } +; structDeclList : structDecl | macroDef { $$ = uentryList_undefined; /* bogus! */ } | structDeclList structDecl { $$ = uentryList_mergeFields ($1, $2); } +; structDecl : completeTypeSpecifier NotType structNamedDeclList IsType TSEMI { $$ = fixUentryList ($3, $1); } | completeTypeSpecifier IsType TSEMI { $$ = fixUnnamedDecl ($1); } +; structNamedDeclList : structNamedDecl NotType { $$ = idDeclList_singleton ($1); } | structNamedDeclList TCOMMA structNamedDecl NotType { $$ = idDeclList_add ($1, $3); } +; structNamedDecl /* hack to get around namespace problems */ : namedDecl { $$ = $1; } | TCOLON IsType constantExpr { $$ = idDecl_undefined; } | namedDecl TCOLON IsType constantExpr { $$ = $1; } /* Need the IsType in case there is a cast in the constant expression. */ +; enumSpc : NotType CENUM TLBRACE enumeratorList TRBRACE IsType @@ -1337,6 +1537,7 @@ enumSpc | NotType CENUM newId TLBRACE { context_pushLoc (); } enumeratorList TRBRACE IsType { context_popLoc (); $$ = declareEnum ($3, $6); } | NotType CENUM newId IsType { $$ = handleEnum ($3); } +; enumeratorList : enumerator @@ -1344,6 +1545,7 @@ enumeratorList | enumeratorList TCOMMA enumerator { $$ = enumNameList_push ($1, $3); } | enumeratorList TCOMMA + ; enumerator : newId @@ -1356,6 +1558,7 @@ enumerator usymtab_supGlobalEntry (ue); $$ = $1; } +; optNamedDecl : namedDeclBase @@ -1363,53 +1566,63 @@ optNamedDecl | pointers TYPE_NAME { qtype qt = qtype_unknown (); - qtype_adjustPointers ($1, qt); - $$ = idDecl_create (cstring_copy (LastIdentifier ()), qt); + $$ = idDecl_create (cstring_copy (cscannerHelp_observeLastIdentifier ()), qt); } | pointers optNamedDecl { $$ = $2; qtype_adjustPointers ($1, idDecl_getTyp ($$)); } +; namedDecl : namedDeclBase | pointers namedDeclBase { $$ = $2; qtype_adjustPointers ($1, idDecl_getTyp ($$)); } +; genericParamList : paramTypeList { $$ = handleParamTypeList ($1); } | NotType paramIdList { $$ = handleParamIdList ($2); } +; innerMods - : QCONST { /* ignored for now */; } - | QVOLATILE { ; } + : QCONST { $$ = qual_createConst (); } + | QRESTRICT { $$ = qual_createRestrict (); } + | QVOLATILE { $$ = qual_createVolatile (); } +; innerModsList - : innerMods { ; } - | innerModsList innerMods { ; } + : innerMods { $$ = qualList_single ($1); } + | innerModsList innerMods { $$ = qualList_add ($1, $2); } +; pointers - : TMULT { $$ = 1; } - | TMULT innerModsList { $$ = 1; } - | TMULT pointers { $$ = 1 + $2; } - | TMULT innerModsList pointers { $$ = 1 + $3; } + : TMULT { $$ = pointers_create ($1); } + | TMULT innerModsList { $$ = pointers_createMods ($1, $2); } + | TMULT pointers { $$ = pointers_extend (pointers_create ($1), $2); } + | TMULT innerModsList pointers { $$ = pointers_extend (pointers_createMods ($1, $2), $3); } +; paramIdList : idList | idList TCOMMA CTOK_ELIPSIS { $$ = uentryList_add ($1, uentry_makeElipsisMarker ()); } +; idList : newId { $$ = uentryList_single (uentry_makeVariableLoc ($1, ctype_int)); } | idList TCOMMA newId { $$ = uentryList_add ($1, uentry_makeVariableLoc ($3, ctype_int)); } +; paramTypeList : CTOK_ELIPSIS { $$ = uentryList_single (uentry_makeElipsisMarker ()); } | paramList | paramList TCOMMA CTOK_ELIPSIS { $$ = uentryList_add ($1, uentry_makeElipsisMarker ()); } +; paramList : { storeLoc (); } paramDecl { $$ = uentryList_single ($2); } | paramList TCOMMA { storeLoc (); } paramDecl { $$ = uentryList_add ($1, $4); } +; paramDecl : IsType completeTypeSpecifier optNamedDecl IsType @@ -1438,19 +1651,23 @@ paramDecl $$ = makeCurrentParam (tparam); idDecl_free (tparam); } +; typeExpression : completeType | completeType abstractDecl { $$ = qtype_newBase ($1, $2); } +; abstractDecl : pointers { $$ = ctype_adjustPointers ($1, ctype_unknown); } | abstractDeclBase | pointers abstractDeclBase { $$ = ctype_adjustPointers ($1, $2); } +; optAbstractDeclBase : /* empty */ { $$ = ctype_unknown; } | abstractDeclBase + ; abstractDeclBase : IsType TLPAREN NotType abstractDecl TRPAREN @@ -1469,6 +1686,7 @@ abstractDeclBase { $$ = ctype_makeFunction ($1, uentryList_makeMissingParams ()); } | abstractDeclBase IsType TLPAREN paramTypeList TRPAREN { $$ = ctype_makeParamsFunction ($1, $4); } +; /* statement */ @@ -1482,18 +1700,22 @@ stmt | iterationStmt | iterStmt | jumpStmt +; iterBody : iterDefStmtList { $$ = $1; } +; endBody : iterBody +; iterDefStmtList : iterDefStmt | iterDefStmtList iterDefStmt { $$ = exprNode_concat ($1, $2); } +; iterDefIterationStmt : iterWhilePred iterDefStmtList @@ -1504,6 +1726,7 @@ iterDefIterationStmt { $$ = exprNode_doWhile ($2, $5); } | forPred iterDefStmt { $$ = exprNode_for ($1, $2); } +; forPred : CFOR TLPAREN optExpr TSEMI optExpr TSEMI @@ -1511,6 +1734,7 @@ forPred TRPAREN { $$ = exprNode_forPred ($3, $5, $8); context_enterForClause ($5); } +; partialIterStmt : ITER_NAME CreateInnerScope TLPAREN @@ -1518,6 +1742,7 @@ partialIterStmt iterArgList TRPAREN { $$ = exprNode_iterStart ($1, $5); } | ITER_ENDNAME { $$ = exprNode_createId ($1); } +; iterDefStmt : labeledStmt @@ -1533,22 +1758,27 @@ iterDefStmt | jumpStmt | TLPAREN iterDefStmt TRPAREN { $$ = $2; } | error { $$ = exprNode_makeError (); } +; iterSelectionStmt : ifPred { exprNode_checkIfPred ($1); } iterDefStmt { /* don't: context_exitTrueClause ($1, $2); */ $$ = exprNode_if ($1, $3); } +; openScope : CreateInnerScope TLBRACE { $$ = exprNode_createTok ($2); } +; closeScope : DeleteInnerScopeSafe TRBRACE { $$ = exprNode_createTok ($2); } +; macroBody : stmtErr | stmtListErr +; stmtErr : labeledStmt @@ -1562,10 +1792,12 @@ stmtErr | TLPAREN stmtErr TRPAREN { $$ = exprNode_addParens ($1, $2); } | jumpStmt | error { $$ = exprNode_makeError (); } +; labeledStmt : newId TCOLON { $$ = exprNode_labelMarker ($1); } | QNOTREACHED stmt { $$ = exprNode_notReached ($2); } +; /* ** We allow more than one QFALLTHROUGH token to support mixed lint/splint markers. @@ -1574,6 +1806,7 @@ labeledStmt optExtraFallThroughs : /* empty */ { ; } | QFALLTHROUGH optExtraFallThroughs { ; } +; /* Note that we can semantically check that the object to the case is indeed constant. In this case, we may not want to go through this effort */ @@ -1583,35 +1816,44 @@ caseStmt TCOLON { $$ = exprNode_caseMarker ($2, FALSE); } | QFALLTHROUGH optExtraFallThroughs CASE constantExpr { context_enterCaseClause ($4); } TCOLON { $$ = exprNode_caseMarker ($4, TRUE); } +; defaultStmt : DEFAULT { context_enterCaseClause (exprNode_undefined); } TCOLON { $$ = exprNode_defaultMarker ($1, FALSE); } | QFALLTHROUGH optExtraFallThroughs DEFAULT { context_enterCaseClause (exprNode_undefined); } TCOLON { $$ = exprNode_defaultMarker ($3, TRUE); } +; compoundStmt : TLPAREN compoundStmt TRPAREN { $$ = $2; } | CreateInnerScope compoundStmtAux { $$ = $2; context_exitInner ($2); } +; compoundStmtErr : CreateInnerScope compoundStmtAuxErr DeleteInnerScope { $$ = $2; } +; CreateInnerScope : { context_enterInnerContext (); } +; DeleteInnerScope : { context_exitInnerPlain (); } +; CreateStructInnerScope : { context_enterStructInnerContext (); } +; DeleteStructInnerScope : { context_exitStructInnerContext (); } +; DeleteInnerScopeSafe : { context_exitInnerSafe (); } +; compoundStmtRest : TRBRACE { $$ = exprNode_createTok ($1); } @@ -1628,10 +1870,12 @@ compoundStmtRest { $$ = exprNode_notReached (exprNode_updateLocation (exprNode_concat ($1, $2), lltok_getLoc ($3))); } +; compoundStmtAux : TLBRACE compoundStmtRest { $$ = exprNode_makeBlock ($2); } +; compoundStmtAuxErr : TLBRACE TRBRACE @@ -1642,35 +1886,43 @@ compoundStmtAuxErr { $$ = exprNode_updateLocation ($2, lltok_getLoc ($3)); } | TLBRACE initializerList stmtList TRBRACE { $$ = exprNode_updateLocation (exprNode_concat ($2, $3), lltok_getLoc ($4)); } +; stmtListErr : stmtErr | stmtListErr stmtErr { $$ = exprNode_concat ($1, $2); } +; initializerList : initializer { $$ = $1; } | initializerList initializer { $$ = exprNode_concat ($1, $2); } +; typeInitializerList : typeInitializer { $$ = $1; } | typeInitializerList TCOMMA typeInitializer { $$ = exprNode_concat ($1, $3); } +; typeInitializer : assignExpr { $$ = $1; } | TLBRACE typeInitializerList optComma TRBRACE { $$ = $2; } +; stmtList : stmt { $$ = $1; } | stmtList stmt { $$ = exprNode_concat ($1, $2); } - +; + expressionStmt : TSEMI { $$ = exprNode_createTok ($1); } | expr TSEMI { $$ = exprNode_statement ($1, $2); } +; expressionStmtErr : TSEMI { $$ = exprNode_createTok ($1); } | expr TSEMI { $$ = exprNode_statement ($1, $2); } | expr { $$ = exprNode_checkExpr ($1); } +; ifPred : CIF TLPAREN expr TRPAREN @@ -1684,6 +1936,7 @@ ifPred ** not ANSI: | CIF TLPAREN compoundStmt TRPAREN ** { $$ = $3; context_enterTrueClause (); } */ +; selectionStmt : ifPred stmt @@ -1698,14 +1951,17 @@ selectionStmt } | SWITCH TLPAREN expr { context_enterSwitch ($3); } TRPAREN stmt { $$ = exprNode_switch ($3, $6); } +; whilePred : WHILE TLPAREN expr TRPAREN { $$ = exprNode_whilePred ($3); context_enterWhileClause ($3); } /* not ANSI: | WHILE TLPAREN compoundStmt TRPAREN stmt { $$ = exprNode_while ($3, $5); } */ +; iterWhilePred : WHILE TLPAREN expr TRPAREN { $$ = exprNode_whilePred($3); } +; iterStmt : ITER_NAME { context_enterIterClause (); } @@ -1716,16 +1972,18 @@ iterStmt $$ = exprNode_iter ($1, $6, $8, $9); } +; iterArgList : iterArgExpr { $$ = exprNodeList_singleton ($1); } | iterArgList { nextIterParam (); } TCOMMA iterArgExpr { $$ = exprNodeList_push ($1, $4); } +; iterArgExpr : assignIterExpr { $$ = exprNode_iterExpr ($1); } | id { $$ = exprNode_iterId ($1); } - | TYPE_NAME_OR_ID { uentry ue = coerceIterId ($1); + | TYPE_NAME_OR_ID { uentry ue = cscannerHelp_coerceIterId ($1); if (uentry_isValid (ue)) { @@ -1733,10 +1991,11 @@ iterArgExpr } else { - $$ = exprNode_iterNewId (cstring_copy (LastIdentifier ())); + $$ = exprNode_iterNewId (cstring_copy (cscannerHelp_observeLastIdentifier ())); } } | NEW_IDENTIFIER { $$ = exprNode_iterNewId ($1); } +; /* ** everything is the same, EXCEPT it cannot be a NEW_IDENTIFIER @@ -1745,10 +2004,12 @@ iterArgExpr cconstantExpr : CCONSTANT | cconstantExpr CCONSTANT { $$ = exprNode_combineLiterals ($1, $2); } +; primaryIterExpr : cconstantExpr | TLPAREN expr TRPAREN { $$ = exprNode_addParens ($1, $2); } +; postfixIterExpr : primaryIterExpr @@ -1761,6 +2022,7 @@ postfixIterExpr | postfixExpr NotType ARROW_OP newId IsType { $$ = exprNode_arrowAccess ($1, $3, $4); } | postfixExpr INC_OP { $$ = exprNode_postOp ($1, $2); } | postfixExpr DEC_OP { $$ = exprNode_postOp ($1, $2); } +; unaryIterExpr : postfixIterExpr @@ -1773,26 +2035,31 @@ unaryIterExpr | TTILDE castExpr { $$ = exprNode_preOp ($2, $1); } | TEXCL castExpr { $$ = exprNode_preOp ($2, $1); } | sizeofExpr { $$ = $1; } +; castIterExpr : unaryIterExpr | TLPAREN typeExpression TRPAREN castExpr { $$ = exprNode_cast ($1, $4, $2); } +; timesIterExpr : castIterExpr | timesExpr TMULT castExpr { $$ = exprNode_op ($1, $3, $2); } | timesExpr TDIV castExpr { $$ = exprNode_op ($1, $3, $2); } | timesExpr TPERCENT castExpr { $$ = exprNode_op ($1, $3, $2); } +; plusIterExpr : timesIterExpr | plusExpr TPLUS timesExpr { $$ = exprNode_op ($1, $3, $2); } | plusExpr TMINUS timesExpr { $$ = exprNode_op ($1, $3, $2); } +; shiftIterExpr : plusIterExpr | shiftExpr LEFT_OP plusExpr { $$ = exprNode_op ($1, $3, $2); } | shiftExpr RIGHT_OP plusExpr { $$ = exprNode_op ($1, $3, $2); } +; relationalIterExpr : shiftIterExpr @@ -1800,15 +2067,18 @@ relationalIterExpr | relationalExpr TGT shiftExpr { $$ = exprNode_op ($1, $3, $2); } | relationalExpr LE_OP shiftExpr { $$ = exprNode_op ($1, $3, $2); } | relationalExpr GE_OP shiftExpr { $$ = exprNode_op ($1, $3, $2); } +; equalityIterExpr : relationalIterExpr | equalityExpr EQ_OP relationalExpr { $$ = exprNode_op ($1, $3, $2); } | equalityExpr NE_OP relationalExpr { $$ = exprNode_op ($1, $3, $2); } +; bitandIterExpr : equalityIterExpr | bitandExpr TAMPERSAND equalityExpr { $$ = exprNode_op ($1, $3, $2); } +; xorIterExpr : bitandIterExpr @@ -1818,20 +2088,24 @@ xorIterExpr bitorIterExpr : xorIterExpr | bitorExpr TBAR xorExpr { $$ = exprNode_op ($1, $3, $2); } +; andIterExpr : bitorIterExpr | andExpr AND_OP bitorExpr { $$ = exprNode_op ($1, $3, $2); } +; orIterExpr : andIterExpr | orExpr OR_OP andExpr { $$ = exprNode_op ($1, $3, $2); } +; conditionalIterExpr : orIterExpr | orExpr TQUEST { context_enterTrueClause ($1); } expr TCOLON { context_enterFalseClause ($1); } conditionalExpr { $$ = exprNode_cond ($1, $4, $7); } +; assignIterExpr : conditionalIterExpr @@ -1846,13 +2120,16 @@ assignIterExpr | unaryExpr AND_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } | unaryExpr XOR_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } | unaryExpr OR_ASSIGN assignExpr { $$ = exprNode_assign ($1, $3, $2); } +; endIter : ITER_ENDNAME { $$ = $1; } | /* empty */ { $$ = uentry_undefined; } +; doHeader : DO { context_enterDoWhileClause (); $$ = $1; } +; iterationStmt : whilePred stmt @@ -1861,6 +2138,7 @@ iterationStmt { $$ = exprNode_statement (exprNode_doWhile ($2, $5), $7); } | forPred stmt { $$ = exprNode_for ($1, $2); context_exitForClause ($1, $2); } +; iterationStmtErr : whilePred stmtErr { $$ = exprNode_while ($1, $2); context_exitWhileClause ($1, $2); } @@ -1869,6 +2147,7 @@ iterationStmtErr | doHeader stmtErr WHILE TLPAREN expr TRPAREN { $$ = exprNode_doWhile ($2, $5); } | forPred stmtErr { $$ = exprNode_for ($1, $2); context_exitForClause ($1, $2); } +; jumpStmt : GOTO newId TSEMI { $$ = exprNode_goto ($2); } @@ -1882,17 +2161,21 @@ jumpStmt | QSAFEBREAK BREAK TSEMI { $$ = exprNode_break ($2, QSAFEBREAK); } | RETURN TSEMI { $$ = exprNode_nullReturn ($1); } | RETURN expr TSEMI { $$ = exprNode_return ($2); } +; optSemi : | TSEMI { ; } +; optComma : | TCOMMA { ; } +; id : IDENTIFIER +; newId : NEW_IDENTIFIER @@ -1900,12 +2183,14 @@ newId | ITER_ENDNAME { $$ = uentry_getName ($1); } | id { $$ = uentry_getName ($1); } | TYPE_NAME_OR_ID { $$ = $1; } +; typeName : TYPE_NAME | TYPE_NAME_OR_ID { $$ = ctype_unknown; } | CTYPEOF TLPAREN expr TRPAREN { $$ = exprNode_getType ($3); exprNode_free ($3); } | CTYPEOF TLPAREN typeExpression TRPAREN { $$ = qtype_getType ($3); } +; %% @@ -1945,7 +2230,7 @@ void yyerror (/*@unused@*/ char *s) } } - swallowMacro (); + cscannerHelp_swallowMacro (); context_exitAllClausesQuiet (); } else