📄 gcppparser.cpp
字号:
{ if(pFile[nPos] == '#') { const char* pStart = &pFile[nPos]; nPos++; while((pFile[nPos] != '\n' || pFile[nPos - 1] == '\\' || (pFile[nPos - 1] == '\r' && pFile[nPos - 2] == '\\')) && pFile[nPos] != '\0') nPos++; GetCurrentFile()->m_nFilePos = nPos; int nLen = &pFile[nPos] - pStart; if(!ParseCompilerDirective(pStart, nLen)) m_nRecoveries++; pFile = GetCurrentFile()->m_pFile; nPos = GetCurrentFile()->m_nFilePos; } else if(m_nIfDefSkips > 0) { while(pFile[nPos] != '\n' && pFile[nPos] != '\0') nPos++; if(pFile[nPos] == '\n') { OnNewLine(nPos); nPos++; } } else if(pFile[nPos] <= ' ') { while(pFile[nPos] <= ' ' && pFile[nPos] != '\0') { if(pFile[nPos] == '\n') OnNewLine(nPos); nPos++; } } else if(pFile[nPos] == '/' && pFile[nPos + 1] == '/') { if(m_bRetainComments) { if(!m_pComment) m_pComment = new GQueue(64); nPos += 2; while(pFile[nPos] != '\n' && pFile[nPos] != '\0') { m_pComment->Push(pFile[nPos]); nPos++; } } else { nPos += 2; while(pFile[nPos] != '\n' && pFile[nPos] != '\0') nPos++; } } else if(pFile[nPos] == '/' && pFile[nPos + 1] == '*') { nPos += 2; while(true) { if(pFile[nPos] == '\0') break; if(pFile[nPos] == '*' && pFile[nPos + 1] == '/') break; if(pFile[nPos] == '\n') OnNewLine(nPos); nPos++; } if(pFile[nPos] != '\0') nPos += 2; } else break; } GAssert(pFile[nPos] != '#', "How'd that happen?"); // Record where the token starts *pnStart = nPos; *pnLine = GetCurrentFile()->m_nLine; *pnCol = GetCurrentFile()->m_nLineStart - nPos; // Move past the token if(pFile[nPos] == '\0') { } else if(pFile[nPos] == '"') { while(true) { int nTmpPos = nPos; while(pFile[nTmpPos] <= ' ' && pFile[nTmpPos] != '\0') nTmpPos++; if(pFile[nTmpPos] != '"') break; while(nPos <= nTmpPos) { if(pFile[nPos] == '\n') OnNewLine(nPos); nPos++; } while((pFile[nPos] != '"' || pFile[nPos - 1] == '\\') && pFile[nPos] != '\n' && pFile[nPos] != '\0') nPos++; if(pFile[nPos] == '"') nPos++; } } else if((pFile[nPos] >= '0' && pFile[nPos] <= '9') || (pFile[nPos] >= 'A' && pFile[nPos] <= 'Z') || (pFile[nPos] >= 'a' && pFile[nPos] <= 'z') || (pFile[nPos] == '_')) { nPos++; while((pFile[nPos] >= '0' && pFile[nPos] <= '9') || (pFile[nPos] >= 'A' && pFile[nPos] <= 'Z') || (pFile[nPos] >= 'a' && pFile[nPos] <= 'z') || (pFile[nPos] == '_')) nPos++; } else if(pFile[nPos + 1] == '=' && ( pFile[nPos] == '=' || pFile[nPos] == '!' || pFile[nPos] == '<' || pFile[nPos] == '>' || pFile[nPos] == '~' || pFile[nPos] == '&' || pFile[nPos] == '|' || pFile[nPos] == '^' || pFile[nPos] == '+' || pFile[nPos] == '-' || pFile[nPos] == '*' || pFile[nPos] == '/' || pFile[nPos] == '%')) nPos += 2; else if(pFile[nPos + 1] == pFile[nPos] && ( pFile[nPos] == ':' || pFile[nPos] == '+' || pFile[nPos] == '-' || pFile[nPos] == '&' || pFile[nPos] == '|' || pFile[nPos] == '>' || pFile[nPos] == '<')) { if(pFile[nPos + 2] == '=' && ( pFile[nPos] == '>' || pFile[nPos] == '<')) nPos += 3; else nPos += 2; } else if(pFile[nPos] == '-' && pFile[nPos + 1] == '>') nPos += 2; else nPos++; *pnLength = nPos - *pnStart; GetCurrentFile()->m_nFilePos = nPos;}bool GCppParser::ParseScopeItem(){ GCppToken* pTok = GetToken(0); if(pTok->Equals(";")) { Advance(); return true; } else if(pTok->Equals("extern")) { Advance(); return true; } else if(pTok->Equals("struct")) return ParseStruct(false); else if(pTok->Equals("class")) return ParseStruct(true); else if(pTok->Equals("enum")) return ParseEnum(); else if(pTok->Equals("union")) return ParseUnion(); else if(pTok->Equals("typedef")) return ParseTypeDef(); else if(pTok->Equals("}")) { Advance(); return PopScope(); } else if(pTok->Equals("friend")) return ParseFriend(); else if(pTok->Equals("public")) return ParseSetAccess(PUBLIC); else if(pTok->Equals("protected")) return ParseSetAccess(PROTECTED); else if(pTok->Equals("private")) return ParseSetAccess(PRIVATE); else if(pTok->Equals("static")) return ParseMethodModifier(MM_STATIC); else if(pTok->Equals("virtual")) return ParseMethodModifier(MM_VIRTUAL); else if(pTok->Equals("inline")) return ParseMethodModifier(MM_INLINE);/* else if(pTok->Equals("_CRTIMP")) // hack for stdio.h { Advance(); return true; } else if(pTok->Equals("NTSYSAPI")) // hack for winnt.h { Advance(); return true; }*/ return ParseDeclaration();}bool GCppParser::GetMacro(const char* pTok, int nLength, const char** pszValue){ char* szTok = (char*)alloca(nLength + 1); memcpy(szTok, pTok, nLength); szTok[nLength] = '\0'; return m_pDefines->Get(szTok, (void**)pszValue);}bool startsWith(const char* pStart, int nLength, const char* szString){ int n; for(n = 0; n < nLength && szString[n] != '\0'; n++) { if(pStart[n] != szString[n]) return false; } return true;}bool GCppParser::ParseCompilerDirective(const char* pStart, int nLength){ if(startsWith(pStart, nLength, "#else")) return ParseElse(pStart, nLength); else if(startsWith(pStart, nLength, "#endif")) return ParseEndIf(pStart, nLength); else if(startsWith(pStart, nLength, "#elif")) return ParseElIf(pStart, nLength); else if(startsWith(pStart, nLength, "#ifdef")) return ParseIfDef(pStart, nLength, true); else if(startsWith(pStart, nLength, "#ifndef")) return ParseIfDef(pStart, nLength, false); else if(startsWith(pStart, nLength, "#if")) return ParseIfDef(pStart, nLength, true); else if(m_nIfDefSkips > 0) return true; else if(startsWith(pStart, nLength, "#include")) return ParseInclude(pStart, nLength); else if(startsWith(pStart, nLength, "#define")) return ParseDefine(pStart, nLength); else if(startsWith(pStart, nLength, "#undef")) return ParseUnDef(pStart, nLength); else if(startsWith(pStart, nLength, "#pragma")) return true; else if(startsWith(pStart, nLength, "#error")) return true; return OnError(NULL, "unrecognized compiler directive");}bool GCppParser::ParseInclude(const char* pFile, int nEnd){ // Parse out the filename int nPos = 8; // 8 = strlen("#include") while(pFile[nPos] <= ' ' && pFile[nPos] != '\0' && nPos < nEnd) nPos++; bool bUseIncludePaths = false; char cClose = '>'; if(pFile[nPos] == '"') cClose = '"'; else if(pFile[nPos] == '<') bUseIncludePaths = true; else return OnError(NULL, "Expected a '\"' or '<'"); nPos++; int nStart = nPos; while(pFile[nPos] != cClose && pFile[nPos] != '\0' && nPos < nEnd) nPos++; if(pFile[nPos] != cClose) return OnError(NULL, "unterminated #include"); int nLength = nPos - nStart; // Find the corresponding file char szFilename[260]; if(bUseIncludePaths) { int nCount = m_pIncludePaths->GetSize(); int n; for(n = 0; n < nCount; n++) { strcpy(szFilename, (const char*)m_pIncludePaths->GetPointer(n)); int nLen = strlen(szFilename); if(szFilename[nLen - 1] == '/' || szFilename[nLen - 1] == '\\') { } else { szFilename[nLen] = '/'; nLen++; } memcpy(szFilename + nLen, &pFile[nStart], nLength); szFilename[nLen + nLength] = '\0'; if(GFile::DoesFileExist(szFilename)) break; } } else { memcpy(szFilename, &pFile[nStart], nLength); szFilename[nLength] = '\0'; } // Put the file on the stack bool bProjectFile = !bUseIncludePaths && GetCurrentFile()->IsProjectFile(); return PushFile(szFilename, bProjectFile);}bool GCppParser::ParseDefine(const char* pFile, int nEnd){ // Parse the statement (not including macro parameters) int nPos = 8; // 8 = strlen("#define ") while(pFile[nPos] <= ' ' && pFile[nPos] != '\0' && nPos < nEnd) nPos++; int nStart = nPos; while(pFile[nPos] > ' ' && pFile[nPos] != '\0' && pFile[nPos] != '(' && nPos < nEnd) nPos++; int nLength = nPos - nStart; if(nLength < 1) return OnError(NULL, "Expected a statement after #define");//if(strnicmp(&pFile[nStart], "WINBASEAPI", 10) == 0) GAssert(false, "break"); // Parse the macro parameters and value int nValueStart = nPos; while(pFile[nPos] != '\0' && nPos < nEnd && !(pFile[nPos] == '/' && (pFile[nPos + 1] == '/' || pFile[nPos + 1] == '*')) ) nPos++; int nValueLength = nPos - nValueStart; while(nValueLength > 0 && (pFile[nValueStart + nValueLength - 1] == '\r' || pFile[nValueStart + nValueLength - 1] == '\n')) nValueLength--; // Add the define char* pStatement = m_pStringHeap->Add(&pFile[nStart], nLength); char* pValue = NULL; if(nValueLength > 0) pValue = m_pStringHeap->Add(&pFile[nValueStart], nValueLength); m_pDefines->Add(pStatement, pValue); return true;}bool GCppParser::ParseIfDef(const char* pFile, int nEnd, bool bPositive){ if(m_nIfDefSkips > 0) { m_nIfDefSkips++; return true; } // Parse the statement int nPos = 6 + (bPositive ? 0 : 1); // 6 = strlen("#ifdef") + 1 for the 'n' in #ifndef nPos++; // for the space after it while(pFile[nPos] <= ' ' && pFile[nPos] != '\0' && nPos < nEnd) nPos++; int nStart = nPos; while(pFile[nPos] > ' ' && pFile[nPos] != '\0' && nPos < nEnd) nPos++; int nLength = nPos - nStart; if(nLength < 1) return OnError(NULL, "Missing statement"); // See if it's defined char* szDefine = (char*)alloca(nLength + 1); memcpy(szDefine, &pFile[nStart], nLength); szDefine[nLength] = '\0'; char* szValue; bool bDefined = m_pDefines->Get(szDefine, (void**)&szValue); if(bPositive != bDefined) m_nIfDefSkips++; return true;}bool GCppParser::ParseElse(const char* pFile, int nEnd){ if(m_nIfDefSkips == 0) m_nIfDefSkips++; else if(m_nIfDefSkips == 1) m_nIfDefSkips--; return true;}bool GCppParser::ParseEndIf(const char* pFile, int nEnd){ if(m_nIfDefSkips > 0) m_nIfDefSkips--; return true;}bool GCppParser::ParseElIf(const char* pFile, int nEnd){ // todo: fix this incorrect behavior if(m_nIfDefSkips == 0) m_nIfDefSkips++; return true;}bool GCppParser::ParseUnDef(const char* pFile, int nEnd){ // Parse the statement int nPos = 7; // 7 = strlen("#undef ") while(pFile[nPos] <= ' ' && pFile[nPos] != '\0' && nPos < nEnd) nPos++; int nStart = nPos; while(pFile[nPos] > ' ' && pFile[nPos] != '\0' && nPos < nEnd) nPos++; int nLength = nPos - nStart; if(nLength < 1) return OnError(NULL, "Expected a statement after #undef"); // Remove it from the defines char* pDefine = (char*)alloca(nLength + 1); memcpy(pDefine, &pFile[nPos], nLength); pDefine[nLength] = '\0'; m_pDefines->Remove(pDefine); return true;}GCppType* GCppParser::FindType(const char* pName, int nLength){ char* szName = (char*)alloca(nLength + 1); memcpy(szName, pName, nLength); szName[nLength] = '\0'; int n; for(n = m_nScopeStackPointer - 1; n >= 0; n--) { GCppType* pType; if(m_pScopeStack[n]->m_pTypes->Get(szName, (void**)&pType)) return pType; } return NULL;}GCppVariable* GCppParser::FindVariable(const char* szName, GCppScope* pScope){ GCppVariable* pVar; while(pScope) { if(pScope->m_pVariables->Get(szName, (void**)&pVar)) return pVar; if(!pScope->IsClass()) break; GCppClass* pClass = (GCppClass*)pScope; pScope = pClass->GetParent(); } return NULL;}GCppVariable* GCppParser::FindVariable(const char* pName, int nLength, GCppScope* pScope){ char* szName = (char*)alloca(nLength + 1); memcpy(szName, pName, nLength); szName[nLength] = '\0'; return FindVariable(szName, pScope);}GCppVariable* GCppParser::FindVariable(const char* pName, int nLength, GCppMethod* pMethod){ char* szName = (char*)alloca(nLength + 1); memcpy(szName, pName, nLength); szName[nLength] = '\0'; GCppVariable* pVar; if(pMethod->m_pLocals && pMethod->m_pLocals->Get(szName, (void**)&pVar)) return pVar; int n; for(n = m_nScopeStackPointer - 1; n >= 0; n--) { GCppScope* pScope = m_pScopeStack[n]; pVar = FindVariable(szName, pScope); if(pVar) return pVar; } return NULL;}GCppMethod* GCppParser::FindMethod(const char* szName, GCppScope* pScope){ GCppMethod* pMethod; while(pScope) { if(pScope->m_pMethods->Get(szName, (void**)&pMethod)) return pMethod; if(!pScope->IsClass()) break; GCppClass* pClass = (GCppClass*)pScope; pScope = pClass->GetParent(); } return NULL;}GCppMethod* GCppParser::FindMethod(const char* pName, int nLength, GCppScope* pScope){ char* szName = (char*)alloca(nLength + 1); memcpy(szName, pName, nLength); szName[nLength] = '\0'; return FindMethod(szName, pScope);}GCppMethod* GCppParser::FindMethod(const char* pName, int nLength){ char* szName = (char*)alloca(nLength + 1); memcpy(szName, pName, nLength); szName[nLength] = '\0'; GCppMethod* pMethod; int n; for(n = m_nScopeStackPointer - 1; n >= 0; n--) { GCppScope* pScope = m_pScopeStack[n]; pMethod = FindMethod(szName, pScope); if(pMethod) return pMethod; } return NULL;}bool GCppParser::ParseStruct(bool bClass){ GCppType* pType = ParseStruct2(bClass, false); if(pType) return true; else return false;}bool GCppParser::ParseUnion(){ GCppType* pType = ParseUnion2(false); if(pType) return true; else return false;}GCppType* GCppParser::ParseUnion2(bool bTypeDef){ return ParseStruct2(false, bTypeDef);}void GetRandomName(char* pBuf){ int n; for(n = 0; n < 8; n++) pBuf[n] = (char)((rand() % 96) + 32);}GCppType* GCppParser::ParseStruct2(bool bClass, bool bTypeDef){ // Find or make the struct
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -