// // Get a single character from the input stream and return it, or 0=end. // TCHAR FBaseParser::GetChar(bool bLiteral) { bool bInsideComment = false; PrevPos = InputPos; PrevLine = InputLine; Loop: const TCHAR c = Input[InputPos++]; if (bInsideComment) { // Record the character as a comment. PrevComment += c; } if (c == TEXT('\n')) { InputLine++; } else if (!bLiteral) { const TCHAR NextChar = PeekChar(); if ( c==TEXT('/') && NextChar==TEXT('*') ) { if (!bInsideComment) { ClearComment(); // Record the slash and star. PrevComment += c; PrevComment += NextChar; bInsideComment = true; // Move past the star. Do it only when not in comment, // otherwise end of comment might be missed e.g. // /*/ Comment /*/ // ~~~~~~~~~~~~~^ Will report second /* as beginning of comment // And throw error that end of file is found in comment. InputPos++; } goto Loop; } else if( c==TEXT('*') && NextChar==TEXT('/') ) { if (!bInsideComment) { ClearComment(); FError::Throwf(TEXT("Unexpected '*/' outside of comment") ); } /** Asterisk and slash always end comment. */ bInsideComment = false; // Star already recorded; record the slash. PrevComment += Input[InputPos]; InputPos++; goto Loop; } } if (bInsideComment) { if (c == 0) { ClearComment(); FError::Throwf(TEXT("End of class header encountered inside comment") ); } goto Loop; } return c; }
// // Skip past all spaces and tabs in the input stream. // TCHAR FBaseParser::GetLeadingChar() { TCHAR TrailingCommentNewline = 0; for (;;) { bool MultipleNewlines = false; TCHAR c; // Skip blanks. do { c = GetChar(); // Check if we've encountered another newline since the last one if (c == TrailingCommentNewline) { MultipleNewlines = true; } } while (IsWhitespace(c)); if (c != TEXT('/') || PeekChar() != TEXT('/')) { return c; } // Clear the comment if we've encountered newlines since the last comment if (MultipleNewlines) { ClearComment(); } // Record the first slash. The first iteration of the loop will get the second slash. PrevComment += c; do { c = GetChar(true); if (c == 0) return c; PrevComment += c; } while (!IsEOL(c)); TrailingCommentNewline = c; for (;;) { c = GetChar(); if (c == 0) return c; if (c == TrailingCommentNewline || !IsEOL(c)) { UngetChar(); break; } PrevComment += c; } } }
// // Get a single character from the input stream and return it, or 0=end. // TCHAR FBaseParser::GetChar(bool bLiteral) { int32 CommentCount = 0; PrevPos = InputPos; PrevLine = InputLine; Loop: const TCHAR c = Input[InputPos++]; if ( CommentCount > 0 ) { // Record the character as a comment. PrevComment += c; } if (c == TEXT('\n')) { InputLine++; } else if (!bLiteral) { const TCHAR NextChar = PeekChar(); if ( c==TEXT('/') && NextChar==TEXT('*') ) { if ( CommentCount == 0 ) { ClearComment(); // Record the slash and star. PrevComment += c; PrevComment += NextChar; } CommentCount++; InputPos++; goto Loop; } else if( c==TEXT('*') && NextChar==TEXT('/') ) { if (--CommentCount < 0) { ClearComment(); FError::Throwf(TEXT("Unexpected '*/' outside of comment") ); } // Star already recorded; record the slash. PrevComment += Input[InputPos]; InputPos++; goto Loop; } } if (CommentCount > 0) { if (c == 0) { ClearComment(); FError::Throwf(TEXT("End of class header encountered inside comment") ); } goto Loop; } return c; }