/** 外部声明 <external_declaration>::=<type_specifier>(<TK_SEMICOLON> |<declarator><funcbody> |<declarator>[<TK_ASSIGN><initializer>] {TK_COMMA><declarator>[<TK_ASSIGN><initializer>]}<TK_SEMICOLON> ) DO:parse external statement storage type:local | global */ void external_declaration(int l){ if(!type_specifier()) expect("<Type specifier>"); if(token == TK_SEMICOLON){ get_token(); return; } while(1){ declarator(); if(token == TK_BEGIN){ if(l == SC_LOCAL) error("don't support function nesting define"); funcbody(); break; }else { if(token == TK_ASSIGN){ get_token(); initializer(); } if(token == TK_COMMA) get_token(); else{ syntax_state = SNTX_LF_HT; skip(TK_SEMICOLON); break; } } } }
/** @brief 解析外部命令 @param l 存储类型,局部的or全局的 */ void external_declaration(int l){ if(!type_specifier()){ expect("<类型区分符>"); } if(token == TK_SEMICOLON){ get_token(); return; } while(1){ declarator(); if(token == TK_BEGIN){ if(l == SC_LOCAL){ error("不支持函数嵌套定义"); } funcbody(); break; }else{ if(token == TK_ASSIGN){ get_token(); initializer(); } if(token == TK_COMMA){ get_token(); }else{ syntax_state = SNTX_LE_HT; skip(TK_SEMICOLON); break; } } } }
/** 形参列表 <parameter_type_list>::=<type_specifier>{<declarator>} {<TK_COMMA><type_specifier>{<declarator>}}<TK_COMMA><TK_ELLIPSIS> */ void parameter_type_list(){ int func_call; /// 原书将这个变量当做参数 get_token(); while(TK_CLOSEPA != token){ if(!type_specifier()) error("invalid identifier"); declarator(); if(TK_CLOSEPA == token) break; skip(TK_COMMA); if(TK_ELLIPSIS == token){ func_call = KW_CDECL; get_token(); break; } } syntax_state = SNTX_DELAY; skip(TK_CLOSEPA); get_token(); if(TK_BEGIN == token) /// define function syntax_state = SNTX_LF_HT; else syntax_state = SNTX_NUL; syntax_indent(); }
TOKEN declaration_specifiers(SYMBOL s) { TOKEN t = NULL; //check the storage class of the thing being declared //if the storage class is specified, else use the default //that is already inside the symbol TOKEN storage_class = storage_class_specifier(); if( NULL != storage_class ) { setStorageClass(s, get_token_storage_class(storage_class)); } TOKEN type_spec = type_specifier(); if( false == token_matches_keyword(type_spec, VOID)) { SYMBOL type = searchst(get_token_string_value(type_spec)); s->basicdt = type->basicdt; s->datatype = type; s->size = type->size; } else { s->basicdt = 0; s->datatype = 0; s->size = 0; } //TOKEN type_qual = type_qualifier(); //TOKEN function_spec = function_specifier(); return t; }
int specifier_qualifier_list(void) { if( type_specifier() ) { if( specifier_qualifier_list() ) { } } else if( type_qualifier() ) { if( specifier_qualifier_list() ) { } } else { abort(); } }
/** 结构声明 <struct_declaration>::= <type_specifier><declarator>{<TK_COMMA><declarator>} <TK_SEMICOLON> */ void struct_declaration(){ type_specifier(); while(1){ declarator(); if(token == TK_SEMICOLON) break; skip(TK_COMMA); } syntax_state = SNTX_LF_HT; skip(TK_SEMICOLON); }
int declaration_specifiers(void) { if( storage_class_specifier() ) { if( declaration_specifiers() ) { } } else if( type_specifier() ) { if( declaration_specifiers() ) { } } else if( type_qualifier() ) { if( declaration_specifiers() ) { } } }
char *cpp_operator(int *poper,type **pt) { int i; type *typ_spec; char *s; *pt = NULL; stoken(); /* skip over operator keyword */ for (i = 0; i < arraysize(oparray); i++) { if (oparray[i].tokn == tok.TKval) goto L1; } /* Look for type conversion */ if (type_specifier(&typ_spec)) { type *t; t = ptr_operator(typ_spec); // parse ptr-operator fixdeclar(t); type_free(typ_spec); *pt = t; return cpp_typetostring(t,"?B"); } cpperr(EM_not_overloadable); // that token cannot be overloaded s = "_"; goto L2; L1: s = oparray[i].string; *poper = oparray[i].oper; switch (*poper) { case OPcall: if (stoken() != TKrpar) synerr(EM_rpar); /* ')' expected */ break; case OPbrack: if (stoken() != TKrbra) synerr(EM_rbra); /* ']' expected */ break; case OPnew: if (stoken() != TKlbra) goto Lret; *poper = OPanew; // operator new[] s = cpp_name_anew; goto L3; case OPdelete: if (stoken() != TKlbra) goto Lret; *poper = OPadelete; // operator delete[] s = cpp_name_adelete; L3: if (stoken() != TKrbra) synerr(EM_rbra); // ']' expected if (!(config.flags4 & CFG4anew)) { cpperr(EM_enable_anew); // throw -Aa to support this config.flags4 |= CFG4anew; } break; } L2: stoken(); Lret: return s; }
/** <sizeof_expression>::=<KW_SIZEOF><TK_OPENPA><type_specifier><TK_CLOSEPA> */ void sizeof_expression(){ get_token(); skip(TK_OPENPA); type_specifier(); skip(TK_CLOSEPA); }