/***************************************************************************** ** Microsoft LAN Manager ** Copyright(c) Microsoft Corp., 1987-1999 *****************************************************************************/ /***************************************************************************** File : acfgram.y Title : the acf grammar file Description : contains the syntactic and semantic handling of the : acf file History : 26-Dec-1990 VibhasC Started rewrite of acf *****************************************************************************/ %{ /**************************************************************************** *** local defines ***************************************************************************/ #define pascal #define FARDATA #define NEARDATA #define FARCODE #define NEARCODE #define NEARSWAP #define YYFARDATA #define PASCAL pascal #define CDECL #define VOID void #define CONST const #define GLOBAL #define YYSTYPE lextype_t #define YYNEAR NEARCODE #define YYPASCAL PASCAL #define YYPRINT printf #define YYSTATIC static #define YYCONST static const #define YYLEX yylex #define YYPARSER yyparse #define yyval yyacfval // enable compilation under /W4 #pragma warning ( disable : 4514 4710 4244 4706 ) #include "nulldefs.h" extern "C" { #include #include #include #include #define yyparse yyacfparse int yyacfparse(); } #include "allnodes.hxx" #include "lexutils.hxx" #include "gramutil.hxx" #include "filehndl.hxx" #include "control.hxx" #include "cmdana.hxx" extern "C" { #include "lex.h" } /**************************************************************************** *** local defines contd.. ***************************************************************************/ #define PUSH_SYMBOL_TABLE(pName, Tag, pSymTbl) \ { \ pSymTbl = pBaseSymTbl; \ SymKey SKey( pName, Tag ); \ pSymTbl->EnterScope(SKey, &pSymTbl);\ } #define POP_SYMBOL_TABLE( pSymTbl ) \ pSymTbl->ExitScope(&pSymTbl) /**************************************************************************** *** local data ***************************************************************************/ node_proc * pAcfProc; int iParam; int cParams; node_interface * pCurInterfaceNode; /**************************************************************************** *** extern procs ***************************************************************************/ extern void yyunlex( token_t ); extern char * GenTempName(); extern STATUS_T GetBaseTypeNode(node_skl**,short,short,short, short); extern short CheckValidAllocate( char * ); extern void SyntaxError( STATUS_T, short ); extern short PossibleMissingToken( short, short ); extern CMD_ARG * pCommand; /**************************************************************************** *** local data ***************************************************************************/ /**************************************************************************** *** extern data ***************************************************************************/ extern SymTable * pBaseSymTbl; extern NFA_INFO * pImportCntrl; extern PASS_2 * pPass2; %} %start AcfFile %token KWINTERFACE %token KWIMPORT %token KWIMPORTODLBASE %token KWCPPQUOTE %token KWCPRAGMA %token KWCPRAGMAPACK %token KWMPRAGMAIMPORT %token KWMPRAGMAECHO %token KWMPRAGMAIMPORTCLNTAUX %token KWMPRAGMAIMPORTSRVRAUX %token KWMIDLPRAGMA %token TYPENAME %token LIBNAME %token KWVOID %token KWUNSIGNED %token KWSIGNED %token KWFLOAT %token KWDOUBLE %token KWINT %token KWBYTE %token KWCHAR %token KWSMALL %token KWLONG %token KWSHORT %token KWHYPER %token KWINT32 %token KWINT3264 %token KWINT64 %token KWINT128 %token KWFLOAT80 %token KWFLOAT128 %token KWSTRUCT %token KWUNION %token KWENUM %token KWSHORTENUM %token KWLONGENUM %token KWCONST %token KWVOLATILE %token KW_C_INLINE %token KWTYPEDEF %token KWDECLGUID %token KWEXTERN %token KWSTATIC %token KWAUTO %token KWREGISTER %token KWERRORSTATUST %token KWBOOLEAN %token KWISOLATIN1 %token KWPRIVATECHAR8 %token KWISOMULTILINGUAL %token KWPRIVATECHAR16 %token KWISOUCS %token KWPIPE %token KWSWITCH %token KWCASE %token KWDEFAULT %token KWUUID %token KWASYNCUUID %token KWVERSION %token KWSTRING %token KWBSTRING %token KWIN %token KWOUT %token KWPARTIALIGNORE %token KWIIDIS %token KWFIRSTIS %token KWLASTIS %token KWMAXIS %token KWMINIS %token KWLENGTHIS %token KWSIZEIS %token KWRANGE /* start of ODL key words */ %token KWID %token KWHC /* helpcontext attribute */ %token KWHSC /* helpstring context attribute */ %token KWLCID %token KWDLLNAME %token KWHELPSTR %token KWHELPFILE %token KWHELPSTRINGDLL %token KWENTRY %token KWPROPGET %token KWPROPPUT %token KWPROPPUTREF %token KWOPTIONAL %token KWVARARG %token KWAPPOBJECT %token KWRESTRICTED %token KWPUBLIC %token KWREADONLY %token KWODL %token KWSOURCE %token KWBINDABLE %token KWREQUESTEDIT %token KWDISPLAYBIND %token KWDEFAULTBIND %token KWLICENSED %token KWPREDECLID %token KWHIDDEN %token KWRETVAL %token KWCONTROL %token KWDUAL %token KWPROXY %token KWNONEXTENSIBLE %token KWNONCREATABLE %token KWOLEAUTOMATION %token KWLIBRARY %token KWMODULE %token KWDISPINTERFACE %token KWCOCLASS %token KWMETHODS %token KWPROPERTIES %token KWIMPORTLIB %token KWFUNCDESCATTR %token KWIDLDESCATTR %token KWTYPEDESCATTR %token KWVARDESCATTR %token KWSAFEARRAY %token KWAGGREGATABLE %token KWUIDEFAULT %token KWNONBROWSABLE %token KWDEFAULTCOLLELEM %token KWDEFAULTVALUE %token KWCUSTOM %token KWDEFAULTVTABLE %token KWIMMEDIATEBIND %token KWUSESGETLASTERROR %token KWREPLACEABLE /* end of ODL key words */ %token KWHANDLET /* Formerly RPCHNDL */ %token KWHANDLE /* Formerly GEN_HNDL */ %token KWCONTEXTHANDLE /* Aka LRPC_CTXT_HNDL */ %token KWMSUNION %token KWMS_CONF_STRUCT %token KWENDPOINT %token KWDEFAULTPOINTER %token KWLOCAL %token KWSWITCHTYPE %token KWSWITCHIS %token KWTRANSMITAS %token KWWIREMARSHAL %token KWIGNORE %token KWREF %token KWUNIQUE %token KWPTR %token KWV1ARRAY %token KWV1STRUCT %token KWV1ENUM %token KWV1STRING %token KWIDEMPOTENT %token KWBROADCAST %token KWMAYBE %token KWASYNC %token KWINPUTSYNC %token KWCALLBACK %token KWALIGN %token KWUNALIGNED %token KWOPTIMIZE %token KWMESSAGE %token STRING %token WIDECHARACTERSTRING %token FLOATCONSTANT %token DOUBLECONSTANT %token KWTOKENNULL %token NUMERICCONSTANT %token NUMERICUCONSTANT %token NUMERICLONGCONSTANT %token NUMERICULONGCONSTANT %token HEXCONSTANT %token HEXUCONSTANT %token HEXLONGCONSTANT %token HEXULONGCONSTANT %token OCTALCONSTANT %token OCTALUCONSTANT %token OCTALLONGCONSTANT %token OCTALULONGCONSTANT %token CHARACTERCONSTANT %token WIDECHARACTERCONSTANT %token IDENTIFIER %token KWSIZEOF %token KWALIGNOF %token TOKENTRUE %token TOKENFALSE /* These are Microsoft C abominations */ %token KWMSCDECLSPEC %token MSCEXPORT %token MSCFORTRAN %token MSCCDECL %token MSCSTDCALL %token MSCLOADDS %token MSCSAVEREGS %token MSCFASTCALL %token MSCSEGMENT %token MSCINTERRUPT %token MSCSELF %token MSCNEAR %token MSCFAR %token MSCUNALIGNED %token MSCHUGE %token MSCPTR32 %token MSCPTR64 %token MSCPASCAL %token MSCEMIT %token MSCASM %token MSCW64 /* Microsoft proposed extentions to MIDL */ %token KWNOCODE /* Allowed in .IDL in addition to .ACF */ /* These are residual C tokens I'm not sure we should even allow */ %token POINTSTO %token INCOP %token DECOP %token MULASSIGN %token DIVASSIGN %token MODASSIGN %token ADDASSIGN %token SUBASSIGN %token LEFTASSIGN %token RIGHTASSIGN %token ANDASSIGN %token XORASSIGN %token ORASSIGN %token DOTDOT %token LTEQ %token GTEQ %token NOTEQ %token LSHIFT %token RSHIFT %token ANDAND %token EQUALS %token OROR /* used by lex internally to signify "get another token" */ %token NOTOKEN /* garbage token - should cause parse errors */ %token GARBAGETOKEN /* OLE extensions */ %token KWOBJECT /* Note that we're assuming that we get constants back and can check bounds (e.g. "are we integer") in the semantic actoins. */ /* ACF - Specific Tokens */ %token KWSHAPE %token KWBYTECOUNT %token KWIMPLICITHANDLE %token KWAUTOHANDLE %token KWEXPLICITHANDLE %token KWREPRESENTAS %token KWCALLAS %token KWCODE %token KWINLINE %token KWOUTOFLINE %token KWINTERPRET %token KWNOINTERPRET %token KWCOMMSTATUS %token KWFAULTSTATUS %token KWHEAP %token KWINCLUDE %token KWPOINTERSIZE %token KWOFFLINE %token KWALLOCATE %token KWENABLEALLOCATE %token KWMANUAL %token KWNOTIFY %token KWNOTIFYFLAG %token KWUSERMARSHAL %token KWENCODE %token KWDECODE %token KWSTRICTCONTEXTHANDLE %token KWNOSERIALIZE %token KWSERIALIZE %token KWCSCHAR %token KWCSDRTAG %token KWCSRTAG %token KWCSSTAG %token KWCSTAGRTN %token KWFORCEALLOCATE /* Currently Unsupported Tokens */ %token KWBITSET %token UUIDTOKEN %token VERSIONTOKEN %token EOI %token LASTTOKEN /*************************************************************************** * acf specific parse stack data types ***************************************************************************/ %type AcfAllocationUnitList %type AcfAllocationUnit %type AcfBodyElement %type AcfEnumSizeAttr %type AcfHandleAttr %type AcfHandleTypeSpec %type AcfImplicitHandleSpec %type AcfInclude %type AcfIncludeList %type AcfIncludeName %type AcfAttr %type AcfAttrList %type AcfAttrs %type AcfInterfaceName %type AcfOpAttr %type AcfOptimizationAttr %type AcfOptionalAttrList %type AcfParamAttr %type AcfRepresentType %type AcfUserMarshalType %type AcfCallType %type AcfType %type AcfTypeAttr %type AcfTypeNameList %type AcfUnimplementedAttr %type FuncModifier %type FuncModifiers %type OptFuncModifiers %type MscDeclSpec %type KWMSCDECLSPEC %type IDENTIFIER %type ImplicitHandleIDName %type NUMERICCONSTANT %type STRING %type TYPENAME %% AcfFile: AcfInterfaceList EOI ; AcfInterfaceList: AcfInterfaceList AcfInterface { if( !pCommand->IsSwitchDefined( SWITCH_MS_EXT ) ) { ParseError( MULTIPLE_INTF_NON_OSF, NULL ); } } | AcfInterface ; AcfInterface: AcfInterfaceHeader '{' AcfOptionalInterfaceBody '}' | AcfInterfaceHeader ';' | AcfBodyElement ; AcfInterfaceHeader: AcfOptionalAttrList KWINTERFACE AcfInterfaceName { named_node * pNode; // the user MUST have defined the type. SymKey SKey( $3, NAME_DEF ); //Search for an interface_reference node in the symbol table. pNode = pBaseSymTbl->SymSearch( SKey ); if ( pNode ) pNode = ( (node_interface_reference *)pNode )->GetRealInterface(); //If the acf switch is specified and there is only one interface //in the IDL file, then tolerate mismatches in the interface name. if ( (!pNode) && pCommand->IsSwitchDefined( SWITCH_ACF ) ) { node_file *pFileNode = pPass2->GetFileNode(); node_interface *pFirst; pFirst = (node_interface *) pFileNode->GetFirstMember(); if(pFirst && pFirst->GetSibling()) pNode = 0; else pNode = pFirst; } if ( (!pNode) || ( !pNode->IsInterfaceOrObject() ) ) { ParseError( ACF_INTERFACE_MISMATCH, $3 ); returnflag = 1; return; } pCurInterfaceNode = (node_interface *)pNode; if( $1.NonNull() ) { pCurInterfaceNode->AddAttributes( $1 ); if ( pCurInterfaceNode->FInSummary( ATTR_ENCODE ) || pCurInterfaceNode->FInSummary( ATTR_DECODE ) ) { pCurInterfaceNode->SetPickleInterface(); } } } ; AcfOptionalAttrList: AcfAttrList | /* Empty */ { $$.MakeAttrList(); } ; AcfAttrList: '[' AcfAttrs ']' { $$ = $2; } ; AcfAttrs: AcfAttrs ',' AcfAttr { ($$ = $1).SetPeer( $3 ); } | AcfAttr { $$.MakeAttrList( $1 ); } ; /*** Interface attributes ***/ AcfAttr: AcfHandleAttr { $$ = $1; } | AcfTypeAttr { $$ = $1; } | AcfEnumSizeAttr { $$ = $1; } | AcfParamAttr { $$ = $1; } | AcfOpAttr { $$ = $1; } | AcfUnimplementedAttr { ParseError(IGNORE_UNIMPLEMENTED_ATTRIBUTE, ((node_base_attr *)$1)->GetNodeNameString()); $$ = $1; } | AcfOptimizationAttr { $$ = $1; } ; AcfEnumSizeAttr: KWSHORTENUM { ParseError( IGNORE_UNIMPLEMENTED_ATTRIBUTE, "[short_enum]" ); $$ = NULL; } | KWLONGENUM { ParseError( IGNORE_UNIMPLEMENTED_ATTRIBUTE, "[long_enum]" ); $$ = NULL; } ; AcfOptimizationAttr: KWOPTIMIZE '(' STRING ')' { unsigned short OptFlags = OPTIMIZE_NONE; OPT_LEVEL_ENUM OptLevel; OptLevel = ParseAcfOptimizationAttr( $3, &OptFlags ); $$ = new node_optimize( OptLevel, OptFlags ); } ; AcfUnimplementedAttr: KWPOINTERSIZE '(' AcfPtrSize ')' { $$ = new acf_attr( ATTR_PTRSIZE ); } ; /**** Implicit and Auto Handle ****/ AcfHandleAttr: KWEXPLICITHANDLE { $$ = new acf_attr( ATTR_EXPLICIT ); } | KWIMPLICITHANDLE '(' AcfImplicitHandleSpec ')' { $$ = $3; } | KWAUTOHANDLE { $$ = new acf_attr( ATTR_AUTO ); } | KWHANDLE { $$ = new battr( ATTR_HANDLE ); } | KWSTRICTCONTEXTHANDLE { $$ = new acf_attr( ATTR_STRICT_CONTEXT_HANDLE ); } ; AcfImplicitHandleSpec: AcfOptionalAttrList AcfHandleTypeSpec ImplicitHandleIDName { node_id_fe * pId = new node_id_fe( $3 ); // if he has specified the handle attribute, the type must have // the handle attribute too! if( $2 && ($2->NodeKind() == NODE_FORWARD ) ) { ParseError( IMPLICIT_HDL_ASSUMED_GENERIC, ((node_forward *) $2)->GetSymName()); } // // if the handle is a context handle type, disallow it. Do that only // if the current interface node is the base interface node. // pId->AddAttributes( $1 ); // generate the new implicit handle attribute $$ = new node_implicit( $2, pId ); } ; ImplicitHandleIDName: IDENTIFIER { $$ = $1; } | KWHANDLE { $$ = "handle"; } ; AcfHandleTypeSpec: KWHANDLET { // return the base type node for handle_t GetBaseTypeNode( &($$),SIGN_UNDEF,SIZE_UNDEF,TYPE_HANDLE_T, 0 ); } | TYPENAME | IDENTIFIER { SymKey SKey( $1, NAME_DEF ); if( ($$ = pBaseSymTbl->SymSearch( SKey ) ) == (node_skl *)0 ) { node_forward * pFwd; SymKey SKey( $1, NAME_DEF ); pFwd = new node_forward( SKey , pBaseSymTbl ); pFwd->SetSymName( $1 ); $$ = pFwd; } } ; /*** Parameterized (non handle) interface attribute ***/ AcfPtrSize: KWSHORT | KWLONG | KWHYPER ; /**** Could ID already be a lexeme? ****/ AcfInterfaceName: IDENTIFIER | TYPENAME { /** this production is necessitated for the hpp switch, which has the ** interface name as a predefined type(def). **/ // $$ = $1; $$ = $1->GetSymName(); } ; /* Note that I DON'T make InterfaceBody a heap-allocated entity. Should I do so? */ AcfOptionalInterfaceBody: AcfBodyElements | /* Empty */ ; AcfBodyElements: AcfBodyElements AcfBodyElement | AcfBodyElement ; /* Note that for type declaration and the operation declarations, we don't really have to propagate anythign up. (Everything's already been done via side-effects). We might want to change the semantic actions to reflect this fact. */ AcfBodyElement: AcfInclude ';' { } | AcfTypeDeclaration ';' { } | Acfoperation ';' { } ; /* What should I do for this?: Should there be a node type? */ AcfInclude: KWINCLUDE AcfIncludeList { $$ = $2; } ; AcfIncludeList: AcfIncludeList ',' AcfIncludeName { } | AcfIncludeName { } ; AcfIncludeName: STRING { // add a file node to the acf includes list. This file node // must have a NODE_STATE_IMPORT for the backend to know that this // is to be emitted like an include. Make the file look like it // has been specified with an import level > 0 unsigned short importlvl = pCurInterfaceNode->GetFileNode()-> GetImportLevel(); node_file * pFile = new node_file( $1, importlvl + 1); pPass2->InsertAcfIncludeFile( pFile ); } ; /*** Type declaration ***/ AcfTypeDeclaration: KWTYPEDEF AcfOptionalAttrList AcfTypeNameList { node_def * pDef; if( $2.NonNull() ) { while( $3->GetPeer( (node_skl **) &pDef ) == STATUS_OK ) { pDef->AddAttributes( $2 ); if ( pDef->FInSummary( ATTR_ENCODE ) || pDef->FInSummary( ATTR_DECODE ) ) { pCurInterfaceNode->SetPickleInterface(); } } } else { pDef = NULL; $3->GetPeer( (node_skl **) &pDef ); if ( pDef ) ParseError( NO_ATTRS_ON_ACF_TYPEDEF, pDef->GetSymName() ); } } ; AcfTypeNameList: AcfTypeNameList ',' AcfType { $$ = $1; if ( $3 ) { SymKey SKey( $3->GetSymName(), NAME_DEF ); node_skl * pDef = (node_skl *) pBaseSymTbl->SymSearch( SKey ); // pDef will not be null. $$->SetPeer( pDef ); } } | AcfType { $$ = new type_node_list; if( $1 ) $$->SetPeer( $1 ); } ; AcfType: TYPENAME | IDENTIFIER { ParseError( UNDEFINED_TYPE, $1 ); $$ = (node_skl *)0; } ; /*** Type attributes ***/ AcfTypeAttr: KWREPRESENTAS '(' AcfRepresentType ')' { $$ = $3; } | KWUSERMARSHAL '(' AcfUserMarshalType ')' { $$ = $3; } | KWCALLAS '(' AcfCallType ')' { $$ = $3; } | KWINLINE { node_base_attr * pN = new acf_attr( ATTR_NONE ); ParseError( IGNORE_UNIMPLEMENTED_ATTRIBUTE, "[inline]" ); $$ = pN; } | KWOUTOFLINE { node_base_attr * pN = new acf_attr( ATTR_NONE ); ParseError( IGNORE_UNIMPLEMENTED_ATTRIBUTE, "[out_of_line]" ); $$ = pN; } | KWALLOCATE '(' AcfAllocationUnitList ')' { node_allocate * pN = new node_allocate( $3 ); ParseError( ALLOCATE_INVALID, pN->GetNodeNameString() ); #ifdef RPCDEBUG short s = pN->GetAllocateDetails(); #endif // RPCDEBUG $$ = pN; } | KWOFFLINE { ParseError( IGNORE_UNIMPLEMENTED_ATTRIBUTE, "offline" ); $$ = new acf_attr( ATTR_NONE ); } | KWHEAP { $$ = new acf_attr( ATTR_HEAP ); } | KWENCODE { $$ = new acf_attr( ATTR_ENCODE ); } | KWDECODE { $$ = new acf_attr( ATTR_DECODE ); } | KWNOSERIALIZE { $$ = new acf_attr( ATTR_NOSERIALIZE ); } | KWSERIALIZE { $$ = new acf_attr( ATTR_SERIALIZE ); } /* Support for [cs_char] and related attributes has been removed because of problems with the DCE spec | KWCSCHAR '(' TYPENAME ')' { $$ = new node_cs_char( $3 );//->GetSymName() ); } */ ; AcfRepresentType: IDENTIFIER { // only non-typedefs get here, so it must be unknown... $$ = new node_represent_as( $1, NULL ); } | TYPENAME { $$ = new node_represent_as( $1->GetSymName(), $1 ); } ; AcfUserMarshalType: IDENTIFIER { // only non-typedefs get here, so it must be unknown... $$ = new node_user_marshal( $1, NULL ); } | TYPENAME { $$ = new node_user_marshal( $1->GetSymName(), $1 ); } ; AcfCallType: IDENTIFIER { // search for a matching proc in our interface SymKey SKey( $1, NAME_PROC ); named_node * pCur = pCurInterfaceNode->GetProcTbl()->SymSearch( SKey ); $$ = new node_call_as( $1, pCur ); } ; AcfAllocationUnitList: AcfAllocationUnitList ',' AcfAllocationUnit { $$ |= $3; } | AcfAllocationUnit ; AcfAllocationUnit: IDENTIFIER { $$ = CheckValidAllocate( $1 ); } ; /* Again, there's not really much to propagate upwards */ /*** Operation declaration ***/ Acfoperation: AcfOptionalAttrList OptFuncModifiers IDENTIFIER { SymKey SKey( $3, NAME_PROC ); // the proc must be defined in the idl file and it must not have the // local attribute if ( pCurInterfaceNode ) { pAcfProc = (node_proc *) pCurInterfaceNode->GetProcTbl()->SymSearch( SKey ); } else pAcfProc = NULL; if( pAcfProc ) { if( pAcfProc->FInSummary( ATTR_LOCAL ) ) { ParseError( LOCAL_PROC_IN_ACF, $3 ); } else { if($1) { pAcfProc->AddAttributes( $1 ); if ( pAcfProc->FInSummary( ATTR_ENCODE ) || pAcfProc->FInSummary( ATTR_DECODE ) ) { pCurInterfaceNode->SetPickleInterface(); } } pAcfProc->GetModifiers().Merge( $2 ); // prepare for parameter matching iParam = 0; } } else if ( pPass2->GetFileNode()->GetImportLevel() == 0 ) { ParseError( UNDEFINED_PROC, $3 ); } } '(' AcfOptionalParameters ')' { pAcfProc = (node_proc *)NULL; } ; /*** Operation attributes ***/ AcfOpAttr: KWCOMMSTATUS { $$ = new acf_attr( ATTR_COMMSTAT ); } | KWFAULTSTATUS { $$ = new acf_attr( ATTR_FAULTSTAT ); } | KWCODE { $$ = new acf_attr( ATTR_CODE ); } | KWNOCODE { $$ = new acf_attr( ATTR_NOCODE ); } | KWENABLEALLOCATE { $$ = new acf_attr( ATTR_ENABLE_ALLOCATE ); } | KWNOTIFY { $$ = new acf_attr( ATTR_NOTIFY ); } | KWNOTIFYFLAG { $$ = new acf_attr( ATTR_NOTIFY_FLAG ); } | KWASYNC { if ( pCommand->GetNdrVersionControl().TargetIsLessThanNT50() ) ParseError( INVALID_FEATURE_FOR_TARGET, "[async]"); $$ = new acf_attr( ATTR_ASYNC ); } /* Support for [cs_char] and related attributes has been removed because of problems with the DCE spec | KWCSTAGRTN '(' IDENTIFIER ')' { SymKey SKey( $3, NAME_PROC ); node_skl *pTagRoutine; pTagRoutine = pBaseSymTbl->SymSearch( SKey ); if( NULL == pTagRoutine ) ParseError( UNDEFINED_PROC, $3 ); $$ = new node_cs_tag_rtn( pTagRoutine ); } */ ; AcfOptionalParameters: Acfparameters { /************************************************************* *** we do not match parameters by number yet, so disable this if( iParam != cParams ) { ParseError(PARAM_COUNT_MISMATCH, (char *)NULL ); } *************************************************************/ } | /* Empty */ { /************************************************************* *** we do not match parameters by number yet, so disable this if( cParams ) { ParseError(PARAM_COUNT_MISMATCH, (char *)NULL ); } *************************************************************/ } ; /*** *** this production valid only if we allow param matching by position *** Acfparameters: Acfparameters ',' Acfparameter | Acfparameters ',' | Acfparameter | ',' ; ***/ Acfparameters: Acfparameters ',' Acfparameter { iParam++; } | Acfparameter { iParam++; } ; Acfparameter: AcfOptionalAttrList IDENTIFIER { // any ordering of parameters is ok here... if( pAcfProc ) { node_param * pParam; if( (pParam = pAcfProc->GetParamNode( $2 ) ) ) { if( $1.NonNull() ) pParam->AddAttributes( $1 ); } else if ( $1.FInSummary( ATTR_COMMSTAT ) || $1.FInSummary( ATTR_FAULTSTAT ) ) { // add parameter to end of param list pAcfProc->AddStatusParam( $2, $1 ); } else ParseError( UNDEF_PARAM_IN_IDL, $2 ); } } /** ** this prodn valid only if parameter matching by position is in effect ** ** | AcfParamAttrList **/ /*** Parameter attributes ***/ AcfParamAttr: KWBYTECOUNT '(' IDENTIFIER ')' { node_param * pParam = NULL; if (pAcfProc) { pParam = pAcfProc->GetParamNode( $3 ); } $$ = new node_byte_count( pParam ); } | KWMANUAL { ParseError( IGNORE_UNIMPLEMENTED_ATTRIBUTE, "manual" ); $$ = new acf_attr( ATTR_NONE ); } /* Support for [cs_char] and related attributes has been removed because of problems with the DCE spec | KWCSDRTAG { $$ = new acf_attr( ATTR_DRTAG ); } | KWCSRTAG { $$ = new acf_attr( ATTR_RTAG ); } | KWCSSTAG { $$ = new acf_attr( ATTR_STAG ); } */ | KWFORCEALLOCATE { $$ = new acf_attr( ATTR_FORCEALLOCATE ); } ; OptFuncModifiers: FuncModifiers | /* Empty */ { $$.Clear(); } FuncModifiers: FuncModifiers FuncModifier { $$ = $1; $$.Merge( $2 ); } | FuncModifier ; FuncModifier: MSCPASCAL { $$ = INITIALIZED_MODIFIER_SET(ATTR_PASCAL); ParseError( BAD_CON_MSC_CDECL, "__pascal" ); } | MSCFORTRAN { $$ = INITIALIZED_MODIFIER_SET(ATTR_FORTRAN); ParseError( BAD_CON_MSC_CDECL, "__fortran" ); } | MSCCDECL { $$ = INITIALIZED_MODIFIER_SET(ATTR_CDECL); ParseError( BAD_CON_MSC_CDECL, "__cdecl" ); } | MSCSTDCALL { $$ = INITIALIZED_MODIFIER_SET(ATTR_STDCALL); ParseError( BAD_CON_MSC_CDECL, "__stdcall" ); } | MSCLOADDS /* potentially interesting */ { $$ = INITIALIZED_MODIFIER_SET(ATTR_LOADDS); ParseError( BAD_CON_MSC_CDECL, "__loadds" ); } | MSCSAVEREGS { $$ = INITIALIZED_MODIFIER_SET(ATTR_SAVEREGS); ParseError( BAD_CON_MSC_CDECL, "__saveregs" ); } | MSCFASTCALL { $$ = INITIALIZED_MODIFIER_SET(ATTR_FASTCALL); ParseError( BAD_CON_MSC_CDECL, "__fastcall" ); } | MSCSEGMENT { $$ = INITIALIZED_MODIFIER_SET(ATTR_SEGMENT); ParseError( BAD_CON_MSC_CDECL, "__segment" ); } | MSCINTERRUPT { $$ = INITIALIZED_MODIFIER_SET(ATTR_INTERRUPT); ParseError( BAD_CON_MSC_CDECL, "__interrupt" ); } | MSCSELF { $$ = INITIALIZED_MODIFIER_SET(ATTR_SELF); ParseError( BAD_CON_MSC_CDECL, "__self" ); } | MSCEXPORT { $$ = INITIALIZED_MODIFIER_SET(ATTR_EXPORT); ParseError( BAD_CON_MSC_CDECL, "__export" ); } | MscDeclSpec | MSCEMIT NUMERICCONSTANT { $$ = INITIALIZED_MODIFIER_SET(ATTR_NONE); ParseError( BAD_CON_MSC_CDECL, "__emit" ); } ; MscDeclSpec: KWMSCDECLSPEC { ParseError( BAD_CON_MSC_CDECL, "__declspec" ); $$ = $1; } ; %%