bool CScanner::SkipWhiteSpace() { enum EScannerState { SEARCH_FOR_WHITE_SPACE, NEXT_TOKEN, BEGIN_COMMENT, C_COMMENT_BODY, CPP_COMMENT_BODY, CPP_COMMENT_GOING_NEWLINE, PREPARE_TO_EXIT_C_COMMENT_BLOCK, PREPARE_TO_EXIT_CPP_COMMENT_BLOCK, BEGIN_PP, PP_GOING_NEW_LINE, BEGIN_SYMBOL, BEGIN_IDENTIFIER, BEGIN_NUMBER, END_SCAN, }; char c; EScannerState State = SEARCH_FOR_WHITE_SPACE; while (cget() != 0) { c = cget(); if (c == '\n') IncLineCounter(); switch (State) { case SEARCH_FOR_WHITE_SPACE: switch(c) { case '\t': case'\n': case '\v': case '\r': case ' ': case '\f': break; case '/': State = BEGIN_COMMENT; break; case '#': State = BEGIN_PP; break; default: return true; } break; case BEGIN_COMMENT: if (c == '*') State = C_COMMENT_BODY; else if (c == '/') State = CPP_COMMENT_BODY; else { State = BEGIN_SYMBOL; Pos--; return true; } break; case C_COMMENT_BODY: if (c != '*') break; else State = PREPARE_TO_EXIT_C_COMMENT_BLOCK; break; case PREPARE_TO_EXIT_C_COMMENT_BLOCK: switch (c) { case '*': break; case '/': State = SEARCH_FOR_WHITE_SPACE; break; default: State = C_COMMENT_BODY; break; } break; case CPP_COMMENT_BODY: if (c == '\\') State = CPP_COMMENT_GOING_NEWLINE; else if (c != '\r' && c != '\n') break; else if (c == '\n') State = SEARCH_FOR_WHITE_SPACE; break; case CPP_COMMENT_GOING_NEWLINE: if (c == '\r' || c == '\\') break; State = CPP_COMMENT_BODY; break; case BEGIN_PP: switch(c) { case '\\': State = PP_GOING_NEW_LINE; break; case '\n': State = SEARCH_FOR_WHITE_SPACE; break; default: break; } break; case PP_GOING_NEW_LINE: if (c == '\r' || c == '\\') break; State = BEGIN_PP; break; default: assert(false); break; } IncPos(); } if (State == C_COMMENT_BODY || State == PREPARE_TO_EXIT_C_COMMENT_BLOCK) { ErrorString = "Unclosed multi-line comment."; return false; } return true; }
void operator()(const char *begin, const char *end) const { IncLineCounter(); }