예제 #1
0
        private YMapping GetMappingValueDependent(ITokenizer tokenizer)
        {
            switch (tokenizer.Current.Value.Kind)
            {
            case TokenKind.Indent when tokenizer.Current.Next?.Value.Kind == TokenKind.MappingKey:
            {
                var mappingNode = new YMapping(tokenizer.Current.Value.IndentLevel);
                var items       = new YKeyValueList();
                tokenizer.MoveNext();
                while (tokenizer.Current.Value.Kind == TokenKind.MappingKey)
                {
                    var keyValueNode = this.ParseMappingKey(tokenizer);
                    items.AddNode(keyValueNode);
                }

                while (tokenizer.Current.Value.Kind == TokenKind.Unindent)
                {
                    tokenizer.MoveNext();
                }

                mappingNode.Add(items.ToNodes());

                return(mappingNode);
            }

            case TokenKind.MappingValue:
            {
                var mappingNode = new YMapping(tokenizer.Current.Value.IndentLevel);
                tokenizer.MoveNext();
                var value = this.GetNodeValue(tokenizer);
                mappingNode.Add(value);

                return(mappingNode);
            }

            case TokenKind.Indent when tokenizer.Current.Next?.Next?.Value.Kind == TokenKind.MappingValue:
            {
                var mappingNode = new YMapping(tokenizer.Current.Value.IndentLevel);
                var items       = new YKeyValueList();
                tokenizer.MoveNext();

                // Добавлеяем элементы в список
                do
                {
                    var keyValueNode = this.ParseMappingKey(tokenizer);
                    items.AddNode(keyValueNode);
                } while (tokenizer.Current.Value.Kind != TokenKind.Unindent &&
                         tokenizer.Current.Value.Kind != TokenKind.Eof &&
                         tokenizer.Current.Value.Kind != TokenKind.Indent &&
                         tokenizer.Current.Value.IndentLevel >= mappingNode.IndentLevel);

                // Удаляем ненужные отступы
                while (tokenizer.Current.Value.Kind == TokenKind.Unindent)
                {
                    tokenizer.MoveNext();
                }

                // Проверяем уровень вложенности
                if (tokenizer.Current.Value.IndentLevel != 0 && tokenizer.Current.Value.Kind == TokenKind.Indent)
                {
                    while (tokenizer.Current.Value.IndentLevel == mappingNode.IndentLevel &&
                           tokenizer.Current.Value.Kind != TokenKind.Eof)
                    {
                        if (tokenizer.Current.Value.Kind == TokenKind.Indent)
                        {
                            tokenizer.MoveNext();
                        }

                        var keyValueNode = this.ParseMappingKey(tokenizer);
                        items.AddNode(keyValueNode);
                    }
                }

                mappingNode.Add(items.ToNodes());

                return(mappingNode);
            }

            case TokenKind.MappingBegin:
            {
                var mappingNode = new YMapping(tokenizer.Current.Value.IndentLevel);
                var items       = new YKeyValueList();
                tokenizer.MoveNext();
                do
                {
                    if (tokenizer.Current.Value.Kind == TokenKind.MappingEnd)
                    {
                        break;
                    }

                    var keyValueNode = this.ParseMappingKey(tokenizer);
                    items.AddNode(keyValueNode);
                } while (tokenizer.Current.Value.Kind == TokenKind.ItemDelimiter && tokenizer.MoveNext());

                if (tokenizer.Current.Value.Kind != TokenKind.MappingEnd)
                {
                    throw ParseException.UnexpectedToken(tokenizer, TokenKind.MappingEnd);
                }

                tokenizer.MoveNext();
                mappingNode.Add(items.ToNodes());

                return(mappingNode);
            }

            default:
                return(null);
            }
        }