public
Fork of olsonjeffery/boolangstudio
Description: Boo language integration for Visual Studio 2008
Homepage: http://www.codeplex.com/BooLangStudio
Clone URL: git://github.com/jagregory/boolangstudio.git
100644 64 lines (52 sloc) 2.019 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
using System;
using System.Collections.Generic;
 
namespace Boo.BooLangService.StringParsing
{
    public class StringWalker
    {
        private const char LeftParenthesis = '(';
        private const char RightParenthesis = ')';
        private const char DoubleQuote = '"';
        private const char BackSlash = '\\';
 
        private bool abort;
        private Stack<StringWalkerState> state;
 
        public IEnumerable<StringPosition> Iterate(string value)
        {
            state = new Stack<StringWalkerState>();
 
            for (var currentIndex = 0; currentIndex < value.Length; currentIndex++)
            {
                if (abort) break;
 
                var currentChar = value[currentIndex];
 
                if (currentChar == LeftParenthesis)
                    state.Push(StringWalkerState.InsideParentheses);
                else if (currentChar == RightParenthesis && StateIs(StringWalkerState.InsideParentheses))
                    state.Pop();
                else if (currentChar == DoubleQuote && StateIs(StringWalkerState.InsideString))
                    state.Pop();
                else if (currentChar == DoubleQuote)
                    state.Push(StringWalkerState.InsideString);
                else if (currentChar == BackSlash && StateIs(StringWalkerState.InsideString))
                    currentIndex += 1; // skip next (escaped) char
 
                if (ShouldYield(currentChar))
                    yield return new StringPosition(currentChar, currentIndex);
            }
        }
 
        protected virtual bool ShouldYield(char currentChar)
        {
            return true;
        }
 
        public bool StateIs(StringWalkerState expectedState)
        {
            if (state.Count == 0) return false;
 
            return state.Peek() == expectedState;
        }
 
        public void Abort()
        {
            abort = true;
        }
 
        public bool HasNoState
        {
            get { return state == null || state.Count == 0; }
        }
    }
}