Esempio n. 1
0
        private static TokenEntry ReadTokenAt(TemplateSource source, int token_index)
        {
            var char_index = token_index + 1;
            var brackets_count = 1;
            var state = ReaderStates.Name;
            var prev_state = state;
            var last_index = source.Length - 1;

            var name = "";
            var body = "";

            while (state != ReaderStates.Done && last_index > char_index)
            {
                char_index++;
                var ch = source[char_index];

                switch (state)
                {
                    case ReaderStates.Name:
                        if (ch == ':') state = ReaderStates.Splitter;
                        else if (ch == '}') state = ReaderStates.CloseBracket;
                        else name += ch;
                        break;
                    case ReaderStates.Splitter:
                        prev_state = state = ReaderStates.Body;
                        if (ch == '{') state = ReaderStates.OpenBracket;
                        else if (ch == '}') state = ReaderStates.CloseBracket;
                        else body += ch;
                        break;
                    case ReaderStates.Body:
                        if (ch == '{') state = ReaderStates.OpenBracket;
                        else if (ch == '}') state = ReaderStates.CloseBracket;
                        else body += ch;
                        break;
                    case ReaderStates.OpenBracket:
                        if (ch == '{') brackets_count++;
                        state = prev_state;
                        if (state == ReaderStates.Body) body = string.Concat(body, '{', ch);
                        else if (state == ReaderStates.Name) name = string.Concat(name, '{', ch);
                        break;
                    case ReaderStates.CloseBracket:
                        if (ch == '}')
                        {
                            brackets_count--;
                            if(brackets_count==0)state = ReaderStates.Done;
                        }
                        if (state != ReaderStates.Done)
                        {
                            state = prev_state;
                            if (state == ReaderStates.Body) body = string.Concat(body, '}', ch);
                            else if (state == ReaderStates.Name) name = string.Concat(name, '}', ch);
                        }
                        break;
                    case ReaderStates.Done:
                    default:
                        throw new ArgumentOutOfRangeException();
                }
            }

            if(state!=ReaderStates.Done)
                throw new Exception("Can't read token: "+source.ToString());

            return new TokenEntry
                {
                    Name = name,
                    Body = body,
                    StartsAt = token_index,
                    EndsAt = char_index
                };
        }