Base class for parsing events.
예제 #1
0
        public bool MoveNext()
        {
            if (_currentIndex < 0)
            {
                while (_innerParser.MoveNext())
                {
                    _allEvents.Add(_innerParser.Current);
                }

                for (int i = _allEvents.Count - 2; i >= 0; --i)
                {
                    var merge = _allEvents[i] as Scalar;
                    if (merge != null && merge.Value == "<<")
                    {
                        var anchorAlias = _allEvents[i + 1] as AnchorAlias;
                        if (anchorAlias != null)
                        {
                            var mergedEvents = GetMappingEvents(anchorAlias.Value);
                            _allEvents.RemoveRange(i, 2);
                            _allEvents.InsertRange(i, mergedEvents);
                        }

                    }
                }
            }

            var nextIndex = _currentIndex + 1;
            if (nextIndex < _allEvents.Count)
            {
                Current = _allEvents[nextIndex];
                _currentIndex = nextIndex;
                return true;
            }
            return false;
        }
예제 #2
0
		private IEnumerable<ParsingEvent> Wrap(IEnumerable<ParsingEvent> events, ParsingEvent start, ParsingEvent end)
		{
			yield return start;
			foreach (var @event in events)
			{
				yield return @event;
			}
			yield return end;
		}
예제 #3
0
        public void ACommentAsTheFirstEventAddsANewLine()
        {
            var events = new ParsingEvent[]
            {
                StandaloneComment("Top comment"),
                Scalar("first").ImplicitPlain,
            };

            var yaml = EmittedTextFrom(StreamedDocumentWith(events));

            yaml.Should()
                .Contain("# Top comment")
                .And.Contain("first")
                .And.NotContain("# Top commentfirst");
        }
예제 #4
0
        private void AssertCurrent(Parser parser, ParsingEvent expected)
        {
            Console.WriteLine(expected.GetType().Name);
            Assert.True(expected.GetType().IsAssignableFrom(parser.Current.GetType()), string.Format("The event is not of the expected type. Exprected: {0}, Actual: {1}", expected.GetType().Name, parser.Current.GetType().Name));

            foreach (var property in expected.GetType().GetProperties()) {
                if(property.PropertyType != typeof(Mark) && property.CanRead) {
                    object value = property.GetValue(parser.Current, null);
                    object expectedValue = property.GetValue(expected, null);
                    if(expectedValue != null && Type.GetTypeCode(expectedValue.GetType()) == TypeCode.Object && expectedValue is IEnumerable) {
                        Console.Write("\t{0} = {{", property.Name);
                        bool isFirst = true;
                        foreach(var item in (IEnumerable)value) {
                            if(isFirst) {
                                isFirst = false;
                            } else {
                                Console.Write(", ");
                            }
                            Console.Write(item);
                        }
                        Console.WriteLine("}");

                        if(expectedValue is ICollection && value is ICollection) {
                            Assert.Equal(((ICollection)expectedValue).Count, ((ICollection)value).Count);
                        }

                        IEnumerator values = ((IEnumerable)value).GetEnumerator();
                        IEnumerator expectedValues = ((IEnumerable)expectedValue).GetEnumerator();
                        while(expectedValues.MoveNext()) {
                            Assert.True(values.MoveNext());
                            Assert.Equal(expectedValues.Current, values.Current);
                        }

                        Assert.False(values.MoveNext());
                    } else {
                        Console.WriteLine("\t{0} = {1}", property.Name, value);
                        Assert.Equal(expectedValue, value);
                    }
                }
            }
        }
예제 #5
0
        /// <summary>
        /// Expect SEQUENCE-START.
        /// </summary>
        private void EmitSequenceStart(ParsingEvent evt)
        {
            ProcessAnchor();
            ProcessTag();

            var sequenceStart = (SequenceStart) evt;

            if (flowLevel != 0 || isCanonical || sequenceStart.Style == SequenceStyle.Flow || CheckEmptySequence())
            {
                state = EmitterState.FlowSequenceFirstItem;
            }
            else
            {
                state = EmitterState.BlockSequenceFirstItem;
            }
        }
예제 #6
0
        /// <summary>
        /// Expect a node.
        /// </summary>
        private void EmitNode(ParsingEvent evt, bool isRoot, bool isMapping, bool isSimpleKey)
        {
            isRootContext = isRoot;
            isMappingContext = isMapping;
            isSimpleKeyContext = isSimpleKey;

            switch (evt.Type)
            {
                case EventType.Alias:
                    EmitAlias();
                    break;

                case EventType.Scalar:
                    EmitScalar(evt);
                    break;

                case EventType.SequenceStart:
                    EmitSequenceStart(evt);
                    break;

                case EventType.MappingStart:
                    EmitMappingStart(evt);
                    break;

                default:
                    throw new YamlException(string.Format("Expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS, got {0}", evt.Type));
            }
        }
예제 #7
0
        /// <summary>
        /// Expect a flow item node.
        /// </summary>
        private void EmitFlowSequenceItem(ParsingEvent evt, bool isFirst)
        {
            if (isFirst)
            {
                WriteIndicator("[", true, true, false);
                IncreaseIndent(true, false);
                ++flowLevel;
            }

            if (evt is SequenceEnd)
            {
                --flowLevel;
                indent = indents.Pop();
                if (isCanonical && !isFirst)
                {
                    WriteIndicator(",", false, false, false);
                    WriteIndent();
                }
                WriteIndicator("]", false, false, false);
                state = states.Pop();
                return;
            }

            if (!isFirst)
            {
                WriteIndicator(",", false, false, false);
            }

            if (isCanonical || column > bestWidth)
            {
                WriteIndent();
            }

            states.Push(EmitterState.FlowSequenceItem);

            EmitNode(evt, false, false, false);
        }
예제 #8
0
        /// <summary>
        /// Expect a flow key node.
        /// </summary>
        private void EmitFlowMappingKey(ParsingEvent evt, bool isFirst)
        {
            if (isFirst)
            {
                WriteIndicator("{", true, true, false);
                IncreaseIndent(true, false);
                ++flowLevel;
            }

            if (evt is MappingEnd)
            {
                --flowLevel;
                indent = indents.Pop();
                if (isCanonical && !isFirst)
                {
                    WriteIndicator(",", false, false, false);
                    WriteIndent();
                }
                WriteIndicator("}", false, false, false);
                state = states.Pop();
                return;
            }

            if (!isFirst)
            {
                WriteIndicator(",", false, false, false);
            }
            if (isCanonical || column > bestWidth)
            {
                WriteIndent();
            }

            if (!isCanonical && CheckSimpleKey())
            {
                states.Push(EmitterState.FlowMappingSimpleValue);
                EmitNode(evt, false, true, true);
            }
            else
            {
                WriteIndicator("?", true, false, false);
                states.Push(EmitterState.FlowMappingValue);
                EmitNode(evt, false, true, false);
            }
        }
예제 #9
0
        /// <summary>
        /// Expect DOCUMENT-END.
        /// </summary>
        private void EmitDocumentEnd(ParsingEvent evt)
        {
            var documentEnd = evt as DocumentEnd;
            if (documentEnd != null)
            {
                WriteIndent();
                if (!documentEnd.IsImplicit)
                {
                    WriteIndicator("...", true, false, false);
                    WriteIndent();
                    isDocumentEndWritten = true;
                }

                state = EmitterState.DocumentStart;

                tagDirectives.Clear();
            }
            else
            {
                throw new YamlException("Expected DOCUMENT-END.");
            }
        }
예제 #10
0
		public bool MoveNext()
		{
			if (_currentIndex < 0)
			{
				while (_innerParser.MoveNext())
				{
					_allEvents.Add(_innerParser.Current);
				}

				for (int i = _allEvents.Count - 2; i >= 0; --i)
				{
					var merge = _allEvents[i] as Scalar;
					if (merge != null && merge.Value == "<<")
					{
						var anchorAlias = _allEvents[i + 1] as AnchorAlias;
						if (anchorAlias != null)
						{
							var mergedEvents = GetMappingEvents(anchorAlias.Value);
							_allEvents.RemoveRange(i, 2);
							_allEvents.InsertRange(i, mergedEvents);
							continue;
						}

						var sequence = _allEvents[i + 1] as SequenceStart;
						if (sequence != null)
						{
							var mergedEvents = new List<IEnumerable<ParsingEvent>>();
							var sequenceEndFound = false;
							for (var itemIndex = i + 2; itemIndex < _allEvents.Count; ++itemIndex)
							{
								anchorAlias = _allEvents[itemIndex] as AnchorAlias;
								if (anchorAlias != null)
								{
									mergedEvents.Add(GetMappingEvents(anchorAlias.Value));
									continue;
								}

								if (_allEvents[itemIndex] is SequenceEnd)
								{
									_allEvents.RemoveRange(i, itemIndex - i + 1);
									_allEvents.InsertRange(i, mergedEvents.SelectMany(e => e));
									sequenceEndFound = true;
									break;
								}
							}

							if (sequenceEndFound)
							{
								continue;
							}
						}

						throw new SemanticErrorException(merge.Start, merge.End, "Unrecognized merge key pattern");
					}
				}
			}

			var nextIndex = _currentIndex + 1;
			if (nextIndex < _allEvents.Count)
			{
				Current = _allEvents[nextIndex];
				_currentIndex = nextIndex;
				return true;
			}
			return false;
		}
예제 #11
0
			void IParsingEventVisitor.Visit(MappingEnd e)
			{
				clonedEvent = new MappingEnd(e.Start, e.End);
			}
예제 #12
0
			void IParsingEventVisitor.Visit(MappingStart e)
			{
				clonedEvent = new MappingStart(null, e.Tag, e.IsImplicit, e.Style, e.Start, e.End);
			}
예제 #13
0
			void IParsingEventVisitor.Visit(SequenceEnd e)
			{
				clonedEvent = new SequenceEnd(e.Start, e.End);
			}
예제 #14
0
			void IParsingEventVisitor.Visit(SequenceStart e)
			{
				clonedEvent = new SequenceStart(null, e.Tag, e.IsImplicit, e.Style, e.Start, e.End);
			}
예제 #15
0
			void IParsingEventVisitor.Visit(Scalar e)
			{
				clonedEvent = new Scalar(null, e.Tag, e.Value, e.Style, e.IsPlainImplicit, e.IsQuotedImplicit, e.Start, e.End);
			}
예제 #16
0
        /// <summary>
        /// Expect a block item node.
        /// </summary>
        private void EmitBlockSequenceItem(ParsingEvent evt, bool isFirst)
        {
            if (isFirst)
            {
                IncreaseIndent(false, (isMappingContext && !isIndentation));
            }

            if (evt is SequenceEnd)
            {
                indent = indents.Pop();
                state = states.Pop();
                return;
            }

            WriteIndent();
            WriteIndicator("-", true, false, true);
            states.Push(EmitterState.BlockSequenceItem);

            EmitNode(evt, false, false, false);
        }
예제 #17
0
 /// <summary>
 /// Expect the root node.
 /// </summary>
 private void EmitDocumentContent(ParsingEvent evt)
 {
     states.Push(EmitterState.DocumentEnd);
     EmitNode(evt, true, false, false);
 }
예제 #18
0
        private void AssertEvent(ParsingEvent expected, ParsingEvent actual, int eventNumber)
        {
            actual.GetType().Should().Be(expected.GetType(), "Parse event {0} is not of the expected type.", eventNumber);

            foreach (var property in expected.GetType().GetProperties())
            {
                if (property.PropertyType == typeof(Mark) || !property.CanRead)
                {
                    continue;
                }

                var value = property.GetValue(actual, null);
                var expectedValue = property.GetValue(expected, null);
                if (expectedValue is IEnumerable && !(expectedValue is string))
                {
                    Dump.Write("\t{0} = {{", property.Name);
                    Dump.Write(string.Join(", ", (IEnumerable)value));
                    Dump.WriteLine("}");

                    if (expectedValue is ICollection && value is ICollection)
                    {
                        var expectedCount = ((ICollection)expectedValue).Count;
                        var valueCount = ((ICollection)value).Count;
                        valueCount.Should().Be(expectedCount, "Compared size of collections in property {0} in parse event {1}",
                            property.Name, eventNumber);
                    }

                    var values = ((IEnumerable)value).GetEnumerator();
                    var expectedValues = ((IEnumerable)expectedValue).GetEnumerator();
                    while (expectedValues.MoveNext())
                    {
                        values.MoveNext().Should().BeTrue("Property {0} in parse event {1} had too few elements", property.Name, eventNumber);
                        values.Current.Should().Be(expectedValues.Current,
                            "Compared element in property {0} in parse event {1}", property.Name, eventNumber);
                    }
                    values.MoveNext().Should().BeFalse("Property {0} in parse event {1} had too many elements", property.Name, eventNumber);
                }
                else
                {
                    Dump.WriteLine("\t{0} = {1}", property.Name, value);
                    value.Should().Be(expectedValue, "Compared property {0} in parse event {1}", property.Name, eventNumber);
                }
            }
        }
예제 #19
0
        /// <summary>
        /// Expect DOCUMENT-START or STREAM-END.
        /// </summary>
        private void EmitDocumentStart(ParsingEvent evt, bool isFirst)
        {
            var documentStart = evt as DocumentStart;
            if (documentStart != null)
            {
                var isImplicit = documentStart.IsImplicit && isFirst && !isCanonical;

                var documentTagDirectives = NonDefaultTagsAmong(documentStart.Tags);

                if (!isFirst && !isDocumentEndWritten && (documentStart.Version != null || documentTagDirectives.Count > 0))
                {
                    isDocumentEndWritten = false;
                    WriteIndicator("...", true, false, false);
                    WriteIndent();
                }

                if (documentStart.Version != null)
                {
                    AnalyzeVersionDirective(documentStart.Version);

                    isImplicit = false;
                    WriteIndicator("%YAML", true, false, false);
                    WriteIndicator(string.Format(CultureInfo.InvariantCulture,
                        "{0}.{1}", Constants.MajorVersion, Constants.MinorVersion),
                        true, false, false);
                    WriteIndent();
                }

                foreach (var tagDirective in documentTagDirectives)
                {
                    AppendTagDirectiveTo(tagDirective, false, tagDirectives);
                }

                foreach (var tagDirective in Constants.DefaultTagDirectives)
                {
                    AppendTagDirectiveTo(tagDirective, true, tagDirectives);
                }

                if (documentTagDirectives.Count > 0)
                {
                    isImplicit = false;
                    foreach (var tagDirective in Constants.DefaultTagDirectives)
                    {
                        AppendTagDirectiveTo(tagDirective, true, documentTagDirectives);
                    }

                    foreach (var tagDirective in documentTagDirectives)
                    {
                        WriteIndicator("%TAG", true, false, false);
                        WriteTagHandle(tagDirective.Handle);
                        WriteTagContent(tagDirective.Prefix, true);
                        WriteIndent();
                    }
                }

                if (CheckEmptyDocument())
                {
                    isImplicit = false;
                }

                if (!isImplicit)
                {
                    WriteIndent();
                    WriteIndicator("---", true, false, false);
                    if (isCanonical)
                    {
                        WriteIndent();
                    }
                }

                state = EmitterState.DocumentContent;
            }

            else if (evt is StreamEnd)
            {
                if (isOpenEnded)
                {
                    WriteIndicator("...", true, false, false);
                    WriteIndent();
                }

                state = EmitterState.StreamEnd;
            }
            else
            {
                throw new YamlException("Expected DOCUMENT-START or STREAM-END");
            }
        }
예제 #20
0
        private void SelectScalarStyle(ParsingEvent evt)
        {
            var scalar = (Scalar)evt;

            var style = scalar.Style;
            var noTag = tagData.handle == null && tagData.suffix == null;

            if (noTag && !scalar.IsPlainImplicit && !scalar.IsQuotedImplicit)
            {
                throw new YamlException("Neither tag nor isImplicit flags are specified.");
            }

            if (style == ScalarStyle.Any)
            {
                style = scalarData.isMultiline ? ScalarStyle.Folded : ScalarStyle.Plain;
            }

            if (isCanonical)
            {
                style = ScalarStyle.DoubleQuoted;
            }

            if (isSimpleKeyContext && scalarData.isMultiline)
            {
                style = ScalarStyle.DoubleQuoted;
            }

            if (style == ScalarStyle.Plain)
            {
                if ((flowLevel != 0 && !scalarData.isFlowPlainAllowed) || (flowLevel == 0 && !scalarData.isBlockPlainAllowed))
                {
                    style = ScalarStyle.SingleQuoted;
                }
                if (string.IsNullOrEmpty(scalarData.value) && (flowLevel != 0 || isSimpleKeyContext))
                {
                    style = ScalarStyle.SingleQuoted;
                }
                if (noTag && !scalar.IsPlainImplicit)
                {
                    style = ScalarStyle.SingleQuoted;
                }
            }

            if (style == ScalarStyle.SingleQuoted)
            {
                if (!scalarData.isSingleQuotedAllowed)
                {
                    style = ScalarStyle.DoubleQuoted;
                }
            }

            if (style == ScalarStyle.Literal || style == ScalarStyle.Folded)
            {
                if (!scalarData.isBlockAllowed || flowLevel != 0 || isSimpleKeyContext)
                {
                    style = ScalarStyle.DoubleQuoted;
                }
            }

            scalarData.style = style;
        }
예제 #21
0
 /// <summary>
 /// Expect a flow value node.
 /// </summary>
 private void EmitFlowMappingValue(ParsingEvent evt, bool isSimple)
 {
     if (isSimple)
     {
         WriteIndicator(":", false, false, false);
     }
     else
     {
         if (isCanonical || column > bestWidth)
         {
             WriteIndent();
         }
         WriteIndicator(":", true, false, false);
     }
     states.Push(EmitterState.FlowMappingKey);
     EmitNode(evt, false, true, false);
 }
예제 #22
0
        private void StateMachine(ParsingEvent evt)
        {
            var comment = evt as Comment;
            if (comment != null)
            {
                EmitComment(comment);
                return;
            }

            switch (state)
            {
                case EmitterState.StreamStart:
                    EmitStreamStart(evt);
                    break;

                case EmitterState.FirstDocumentStart:
                    EmitDocumentStart(evt, true);
                    break;

                case EmitterState.DocumentStart:
                    EmitDocumentStart(evt, false);
                    break;

                case EmitterState.DocumentContent:
                    EmitDocumentContent(evt);
                    break;

                case EmitterState.DocumentEnd:
                    EmitDocumentEnd(evt);
                    break;

                case EmitterState.FlowSequenceFirstItem:
                    EmitFlowSequenceItem(evt, true);
                    break;

                case EmitterState.FlowSequenceItem:
                    EmitFlowSequenceItem(evt, false);
                    break;

                case EmitterState.FlowMappingFirstKey:
                    EmitFlowMappingKey(evt, true);
                    break;

                case EmitterState.FlowMappingKey:
                    EmitFlowMappingKey(evt, false);
                    break;

                case EmitterState.FlowMappingSimpleValue:
                    EmitFlowMappingValue(evt, true);
                    break;

                case EmitterState.FlowMappingValue:
                    EmitFlowMappingValue(evt, false);
                    break;

                case EmitterState.BlockSequenceFirstItem:
                    EmitBlockSequenceItem(evt, true);
                    break;

                case EmitterState.BlockSequenceItem:
                    EmitBlockSequenceItem(evt, false);
                    break;

                case EmitterState.BlockMappingFirstKey:
                    EmitBlockMappingKey(evt, true);
                    break;

                case EmitterState.BlockMappingKey:
                    EmitBlockMappingKey(evt, false);
                    break;

                case EmitterState.BlockMappingSimpleValue:
                    EmitBlockMappingValue(evt, true);
                    break;

                case EmitterState.BlockMappingValue:
                    EmitBlockMappingValue(evt, false);
                    break;

                case EmitterState.StreamEnd:
                    throw new YamlException("Expected nothing after STREAM-END");

                default:
                    throw new InvalidOperationException();
            }
        }
예제 #23
0
        /// <summary>
        /// Expect MAPPING-START.
        /// </summary>
        private void EmitMappingStart(ParsingEvent evt)
        {
            ProcessAnchor();
            ProcessTag();

            var mappingStart = (MappingStart) evt;

            if (flowLevel != 0 || isCanonical || mappingStart.Style == MappingStyle.Flow || CheckEmptyMapping())
            {
                state = EmitterState.FlowMappingFirstKey;
            }
            else
            {
                state = EmitterState.BlockMappingFirstKey;
            }
        }
예제 #24
0
        /// <summary>
        /// Emit an evt.
        /// </summary>
        public void Emit(ParsingEvent @event)
        {
            events.Enqueue(@event);

            while (!NeedMoreEvents())
            {
                var current = events.Peek();
                try
                {

                    AnalyzeEvent(current);
                    StateMachine(current);
                }
                finally
                {
                    // Only dequeue after calling state_machine because it checks how many events are in the queue.
                    // Todo: well, move into StateMachine() then
                    events.Dequeue();
                }
            }
        }
예제 #25
0
        /// <summary>
        /// Expect SCALAR.
        /// </summary>
        private void EmitScalar(ParsingEvent evt)
        {
            SelectScalarStyle(evt);
            ProcessAnchor();
            ProcessTag();
            IncreaseIndent(true, false);
            ProcessScalar();

            indent = indents.Pop();
            state = states.Pop();
        }
예제 #26
0
        private void AnalyzeEvent(ParsingEvent evt)
        {
            anchorData.anchor = null;
            tagData.handle = null;
            tagData.suffix = null;

            var alias = evt as AnchorAlias;
            if (alias != null)
            {
                AnalyzeAnchor(alias.Value, true);
                return;
            }

            var nodeEvent = evt as NodeEvent;
            if (nodeEvent != null)
            {
                var scalar = evt as Scalar;
                if (scalar != null)
                {
                    AnalyzeScalar(scalar);
                }

                AnalyzeAnchor(nodeEvent.Anchor, false);

                if (!string.IsNullOrEmpty(nodeEvent.Tag) && (isCanonical || nodeEvent.IsCanonical))
                {
                    AnalyzeTag(nodeEvent.Tag);
                }
            }
        }
예제 #27
0
        /// <summary>
        /// Expect STREAM-START.
        /// </summary>
        private void EmitStreamStart(ParsingEvent evt)
        {
            if (!(evt is StreamStart))
            {
                throw new ArgumentException("Expected STREAM-START.", "evt");
            }

            indent = -1;
            column = 0;
            isWhitespace = true;
            isIndentation = true;

            state = EmitterState.FirstDocumentStart;
        }
예제 #28
0
        /// <summary>
        /// Expect a block key node.
        /// </summary>
        private void EmitBlockMappingKey(ParsingEvent evt, bool isFirst)
        {
            if (isFirst)
            {
                IncreaseIndent(false, false);
            }

            if (evt is MappingEnd)
            {
                indent = indents.Pop();
                state = states.Pop();
                return;
            }

            WriteIndent();

            if (CheckSimpleKey())
            {
                states.Push(EmitterState.BlockMappingSimpleValue);
                EmitNode(evt, false, true, true);
            }
            else
            {
                WriteIndicator("?", true, false, true);
                states.Push(EmitterState.BlockMappingValue);
                EmitNode(evt, false, true, false);
            }
        }
예제 #29
0
 private void AssertNext(Parser parser, ParsingEvent expected)
 {
     AssertHasNext(parser);
     AssertCurrent(parser, expected);
 }
예제 #30
0
 /// <summary>
 /// Expect a block value node.
 /// </summary>
 private void EmitBlockMappingValue(ParsingEvent evt, bool isSimple)
 {
     if (isSimple)
     {
         WriteIndicator(":", false, false, false);
     }
     else
     {
         WriteIndent();
         WriteIndicator(":", true, false, true);
     }
     states.Push(EmitterState.BlockMappingKey);
     EmitNode(evt, false, true, false);
 }