public void Parse() { (SourceCode.NotEmpty()).OrThrows("Null Source Code"); // avoid re-parse if (state_ == State.Finished) { return; } while (currentIdx_ < SourceCode.Length) { var ch = SourceCode[currentIdx_]; switch (state_) { case State.Start: parseStart(ch); break; // start case State.InComment: if (ch == '\n') { resetState(); lineCount_++; currentLineIdx_ = currentIdx_ + 1; } break; case State.InNote: if (ch == '\n') { currentIdx_--; addToken(TokenType.Note); currentIdx_++; resetState(); } break; case State.InInteger: if (currentIdx_ != SourceCode.Count() - 1) { var next = SourceCode[currentIdx_ + 1]; if (ch == '.' && next.IsDigit()) { state_ = State.InFloat; } else if (ch == 'E' || ch == 'e') { state_ = State.InSciNumber; } else if (!ch.IsDigit()) { currentIdx_--; addToken(TokenType.Integer); resetState(); } } else if (ch.IsDigit()) // last char { addToken(TokenType.Integer); resetState(); } else // last char is not digit { currentIdx_--; addToken(TokenType.Integer); currentIdx_++; if (tryAddSingle(ch)) { resetState(); } else { addError("Illegal Ending Char[" + ch + "] Following Integer"); } } break; case State.InFloat: if (currentIdx_ != SourceCode.Count() - 1) { var next = SourceCode[currentIdx_ + 1]; if (next == 'E' || next == 'e') { state_ = State.InSciNumber; currentIdx_++; } if (!ch.IsDigit()) { currentIdx_--; addToken(TokenType.Float); resetState(); } } else if (ch.IsDigit()) // last char { addToken(TokenType.Float); resetState(); } else // last char is not digit { currentIdx_--; addToken(TokenType.Float); currentIdx_++; if (tryAddSingle(ch)) { resetState(); } else { addError("Illegal Ending Char[" + ch + "] Following Integer"); } } break; case State.InSciNumber: if (ch == '+' || ch == '-') { var prev = SourceCode[currentIdx_ - 1]; if (prev != 'E' && prev != 'e') { currentIdx_--; addToken(TokenType.SciNumber); resetState(); Console.WriteLine(" cur idx{0}", currentIdx_); } } else if (!ch.IsDigit()) { currentIdx_--; addToken(TokenType.SciNumber); resetState(); } break; case State.InIdentifier: if (!ch.IsValidTailingIdCh()) { currentIdx_--; addToken(TokenType.Identifier); resetState(); } break; case State.InString: { if (ch == '\"') { currentIdx_--; // skip " addToken(TokenType.String); currentIdx_++; resetState(); break; } else if (ch == '\\') { state_ = State.InEscapingString; Console.WriteLine("escape"); } else if (ch == '\n') { addError("Multi-line string"); } } break; case State.InEscapingString: // next char after if (ch == '\n') { addError("Multi-line string"); resetState(); } else { state_ = State.InString; } break; } // while: foreach ch currentIdx_++; } currentIdx_--; switch (state_) { case State.InInteger: addToken(TokenType.Integer); break; case State.InFloat: addToken(TokenType.Float); break; case State.InSciNumber: addToken(TokenType.SciNumber); break; case State.InIdentifier: addToken(TokenType.Identifier); break; case State.InString: case State.InEscapingString: addError("Multi-Line String!"); break; } // ok we are done // mark as finished to prevent reparse // to re do parsing, see Reparse(); state_ = State.Finished; }