public static ScanWordCursor PositionBegin() { ScanWordCursor cursor = new ScanWordCursor(); cursor.Position = RelativePosition.Begin; return(cursor); }
public ScanWordCursor(ScanWordCursor Cursor) { this.Word = Cursor.Word; this.WordBx = Cursor.WordBx; this.Position = Cursor.Position; this.DelimBx = Cursor.DelimBx; this.DelimPattern = Cursor.DelimPattern; this.StayAtFlag = Cursor.StayAtFlag; }
// ----------------------- CalcScanNextStart --------------------------- // calc start position from which to start scan to the next word. private static int CalcScanNextStart( ScanStream ScanStream, TextTraits Traits, ScanWordCursor Cursor) { int bx; switch (Cursor.Position) { case RelativePosition.Begin: bx = 0; break; case RelativePosition.Before: bx = Cursor.CursorBx.ToStreamLocation(ScanStream).Value; break; case RelativePosition.After: case RelativePosition.At: if (Traits.IsNonWordPattern(Cursor.DelimPattern)) { bx = Cursor.DelimEx.ToStreamLocation(ScanStream).Value + 1; } else if (Cursor.WordIsDelim == true) { bx = Cursor.WordEx.ToStreamLocation(ScanStream).Value + 1; } else { bx = Cursor.DelimBx.ToStreamLocation(ScanStream).Value; } break; case RelativePosition.End: bx = ScanStream.Stream.Length; break; case RelativePosition.None: bx = -1; break; default: bx = -1; break; } if (bx > (ScanStream.Stream.Length - 1)) { bx = -1; } return(bx); }
// ------------------------ ScanNextWord ------------------------- // Scans to the next word in the string. ( a word being the text bounded by the // delimeter and whitespace characters as spcfd in the TextTraits argument ) // Return null when end of string. public static ScanWordCursor ScanNextWord( ScanStream ScanStream, TextTraits Traits, ScanWordCursor CurrentWord) { // components of the next word. TextWord wordPart = null; TextLocation wordBx = null; ScanPattern nonWordPat = null; TextLocation nonWordLoc = null; int nonWordIx = -1; // stay at the current location. return copy of the cursor, but with stayatflag // turned off. if (CurrentWord.StayAtFlag == true) { nonWordPat = CurrentWord.DelimPattern; nonWordLoc = CurrentWord.DelimBx; wordPart = CurrentWord.Word; wordBx = CurrentWord.WordBx; } else { #region STEP1 setup the begin pos of the next word. // ----------------------------- STEP 1 ------------------------------ // setup the begin pos of the next word. int bx; { // calc scan start position bx = ScanWord.CalcScanNextStart(ScanStream, Traits, CurrentWord); // advance past whitespace if (bx != -1) { bx = Scanner.ScanNotEqual(ScanStream.Stream, Traits.WhitespacePatterns, bx); } } // end STEP 1. #endregion #region STEP 2. Isolate either numeric lib, quoted lit or scan to non word pattern // ------------------------------- STEP 2 ---------------------------------- // Isolate either numeric literal, quoted literal or scan to the next non word // pattern. LiteralType?litType = null; string litText = null; { // got a decimal digit. isolate the numeric literal string. if ((bx != -1) && (Char.IsDigit(ScanStream.Stream[bx]) == true)) { var rv = ScanWord.IsolateNumericLiteral(ScanStream, Traits, bx); litType = rv.Item1; litText = rv.Item2; nonWordPat = rv.Item3; // the non word pattern immed after numeric literal nonWordIx = rv.Item4; // pos of foundPat } // got something. now scan forward for the pattern that delimits the word. else if (bx != -1) { { var rv = Scanner.ScanEqualAny(ScanStream.Stream, bx, Traits.DelimPatterns); nonWordPat = rv.Item1; nonWordIx = rv.Item2; } // got a quote char. Isolate the quoted string, then find the delim that follows // the quoted string. if ((nonWordPat != null) && (nonWordPat.DelimClassification == DelimClassification.Quote) && (nonWordIx == bx)) { var rv = IsolateQuotedWord(ScanStream, Traits, nonWordIx); litType = rv.Item1; litText = rv.Item2; nonWordPat = rv.Item3; // the non word pattern immed after quoted literal nonWordIx = rv.Item4; // pos of foundPat. } } } // end STEP 2. #endregion #region STEP 3 - setup wordBx and wordPart with the found word. { // got nothing. if (bx == -1) { } // no delim found. word text all the way to the end. else if (nonWordIx == -1) { var rv = ScanWord.IsolateWordText( ScanStream, Traits, litType, litText, bx, null); wordBx = rv.Item1; wordPart = rv.Item2; #if skip wordBx = new StreamLocation(bx).ToTextLocation(ScanStream); if (litType != null) { wordPart = new TextWord(litText, WordClassification.Quoted, Traits); } else { wordPart = new TextWord( ScanStream.Substring(bx), WordClassification.Identifier, Traits); } #endif } // got a word and a non word pattern. else if (nonWordIx > bx) { var rv = ScanWord.IsolateWordText( ScanStream, Traits, litType, litText, bx, nonWordIx); wordBx = rv.Item1; wordPart = rv.Item2; #if skip wordBx = new StreamLocation(bx).ToTextLocation(ScanStream); int lx = foundIx - bx; wordPart = new TextWord( ScanStream.Substring(bx, lx), WordClassification.Identifier, Traits); #endif nonWordLoc = new StreamLocation(nonWordIx).ToTextLocation(ScanStream); } // no word. just delim. else { nonWordLoc = new StreamLocation(nonWordIx).ToTextLocation(ScanStream); // the delim is comment to end. store as a word. if (nonWordPat.DelimClassification == DelimClassification.CommentToEnd) { var rv = Scanner.ScanEqualAny(ScanStream.Stream, bx, Traits.NewLinePatterns); var eolPat = rv.Item1; var eolIx = rv.Item2; if (eolPat == null) { wordBx = new StreamLocation(nonWordIx).ToTextLocation(ScanStream); wordPart = new TextWord( ScanStream.Substring(nonWordIx), WordClassification.CommentToEnd, Traits); nonWordLoc = null; nonWordPat = null; } else { wordBx = new StreamLocation(nonWordIx).ToTextLocation(ScanStream); int lx = eolIx - nonWordIx; var sloc = wordBx.ToStreamLocation(ScanStream); wordPart = new TextWord( ScanStream.Substring(sloc.Value, lx), WordClassification.CommentToEnd, Traits); nonWordLoc = new StreamLocation(eolIx).ToTextLocation(ScanStream); nonWordPat = eolPat; } } // if the delim pattern is not non word ( a divider ), store the pattern also // as the word. else if (Traits.DelimPatternsThatAreNonWords.Contains(nonWordPat) == false) { wordBx = nonWordLoc; wordPart = new TextWord( nonWordPat.PatternValue, nonWordPat.DelimClassification.ToWordClassification().Value, Traits); } } } #endregion // delim is whitespace. scan ahead for something more meaningful than whitespace. if ((nonWordPat != null) && (Traits.IsWhitespace(nonWordPat))) { StreamLocation dx = nonWordLoc.ToStreamLocation(ScanStream); int fx = Scanner.ScanNotEqual( ScanStream.Stream, Traits.WhitespacePatterns, dx.Value + nonWordPat.Length); var pat = Traits.DelimPatterns.MatchAt(ScanStream.Stream, fx); if (pat != null) { nonWordLoc = new StreamLocation(fx).ToTextLocation(ScanStream); nonWordPat = pat; } } } // store the results in the return cursor. ScanWordCursor nx = null; if ((wordPart == null) && (nonWordPat == null)) { nx = new ScanWordCursor( ); nx.Position = RelativePosition.End; } else { nx = new ScanWordCursor(wordPart, wordBx, nonWordLoc, nonWordPat); nx.Position = RelativePosition.At; } return(nx); }