Exemple #1
0
		/// <summary>
		/// Parse the productions:
		/// block_node_or_indentless_sequence    ::=
		///                          ALIAS
		///                          *****
		///                          | properties (block_content | indentless_block_sequence)?
		///                            **********  *
		///                          | block_content | indentless_block_sequence
		///                            *
		/// block_node           ::= ALIAS
		///                          *****
		///                          | properties block_content?
		///                            ********** *
		///                          | block_content
		///                            *
		/// flow_node            ::= ALIAS
		///                          *****
		///                          | properties flow_content?
		///                            ********** *
		///                          | flow_content
		///                            *
		/// properties           ::= TAG ANCHOR? | ANCHOR TAG?
		///                          *************************
		/// block_content        ::= block_collection | flow_collection | SCALAR
		///                                                               ******
		/// flow_content         ::= flow_collection | SCALAR
		///                                            ******
		/// </summary>
		private ParsingEvent ParseNode(bool isBlock, bool isIndentlessSequence)
		{
			AnchorAlias alias = GetCurrentToken() as AnchorAlias;
			if (alias != null)
			{
				state = states.Pop();
				ParsingEvent evt = new Events.AnchorAlias(alias.Value, alias.Start, alias.End);
				Skip();
				return evt;
			}

			Mark start = GetCurrentToken().Start;

			Anchor anchor = null;
			Tag tag = null;

			// The anchor and the tag can be in any order. This loop repeats at most twice.
			while (true)
			{
				if (anchor == null && (anchor = GetCurrentToken() as Anchor) != null)
				{
					Skip();
				}
				else if (tag == null && (tag = GetCurrentToken() as Tag) != null)
				{
					Skip();
				}
				else
				{
					break;
				}
			}

			string tagName = null;
			if (tag != null)
			{
				if (string.IsNullOrEmpty(tag.Handle))
				{
					tagName = tag.Suffix;
				}
				else if (tagDirectives.Contains(tag.Handle))
				{
					tagName = string.Concat(tagDirectives[tag.Handle].Prefix, tag.Suffix);
				}
				else
				{
					throw new SemanticErrorException(tag.Start, tag.End, "While parsing a node, find undefined tag handle.");
				}
			}
			if (string.IsNullOrEmpty(tagName))
			{
				tagName = null;
			}

			string anchorName = anchor != null ? string.IsNullOrEmpty(anchor.Value) ? null : anchor.Value : null;

			bool isImplicit = string.IsNullOrEmpty(tagName);

			if (isIndentlessSequence && GetCurrentToken() is BlockEntry)
			{
				state = ParserState.IndentlessSequenceEntry;

				return new Events.SequenceStart(
				           anchorName,
				           tagName,
				           isImplicit,
				           SequenceStyle.Block,
				           start,
				           GetCurrentToken().End
				       );
			}
			else
			{
				Scalar scalar = GetCurrentToken() as Scalar;
				if (scalar != null)
				{
					bool isPlainImplicit = false;
					bool isQuotedImplicit = false;
					if ((scalar.Style == ScalarStyle.Plain && tagName == null) || tagName == Constants.DefaultHandle)
					{
						isPlainImplicit = true;
					}
					else if (tagName == null)
					{
						isQuotedImplicit = true;
					}

					state = states.Pop();
					ParsingEvent evt = new Events.Scalar(anchorName, tagName, scalar.Value, scalar.Style, isPlainImplicit, isQuotedImplicit, start, scalar.End);

					Skip();
					return evt;
				}

				FlowSequenceStart flowSequenceStart = GetCurrentToken() as FlowSequenceStart;
				if (flowSequenceStart != null)
				{
					state = ParserState.FlowSequenceFirstEntry;
					return new Events.SequenceStart(anchorName, tagName, isImplicit, SequenceStyle.Flow, start, flowSequenceStart.End);
				}

				FlowMappingStart flowMappingStart = GetCurrentToken() as FlowMappingStart;
				if (flowMappingStart != null)
				{
					state = ParserState.FlowMappingFirstKey;
					return new Events.MappingStart(anchorName, tagName, isImplicit, MappingStyle.Flow, start, flowMappingStart.End);
				}

				if (isBlock)
				{
					BlockSequenceStart blockSequenceStart = GetCurrentToken() as BlockSequenceStart;
					if (blockSequenceStart != null)
					{
						state = ParserState.BlockSequenceFirstEntry;
						return new Events.SequenceStart(anchorName, tagName, isImplicit, SequenceStyle.Block, start, blockSequenceStart.End);
					}

					BlockMappingStart blockMappingStart = GetCurrentToken() as BlockMappingStart;
					if (blockMappingStart != null)
					{
						state = ParserState.BlockMappingFirstKey;
						return new Events.MappingStart(anchorName, tagName, isImplicit, MappingStyle.Block, start, GetCurrentToken().End);
					}
				}

				if (anchorName != null || tag != null)
				{
					state = states.Pop();
					return new Events.Scalar(anchorName, tagName, string.Empty, ScalarStyle.Plain, isImplicit, false, start, GetCurrentToken().End);
				}

				var current = GetCurrentToken();
				throw new SemanticErrorException(current.Start, current.End, "While parsing a node, did not find expected node content.");
			}
		}
Exemple #2
0
        /// <summary>
        /// Parse the productions:
        /// block_node_or_indentless_sequence    ::=
        ///                          ALIAS
        ///                          *****
        ///                          | properties (block_content | indentless_block_sequence)?
        ///                            **********  *
        ///                          | block_content | indentless_block_sequence
        ///                            *
        /// block_node           ::= ALIAS
        ///                          *****
        ///                          | properties block_content?
        ///                            ********** *
        ///                          | block_content
        ///                            *
        /// flow_node            ::= ALIAS
        ///                          *****
        ///                          | properties flow_content?
        ///                            ********** *
        ///                          | flow_content
        ///                            *
        /// properties           ::= TAG ANCHOR? | ANCHOR TAG?
        ///                          *************************
        /// block_content        ::= block_collection | flow_collection | SCALAR
        ///                                                               ******
        /// flow_content         ::= flow_collection | SCALAR
        ///                                            ******
        /// </summary>
        private ParsingEvent ParseNode(bool isBlock, bool isIndentlessSequence)
        {
            AnchorAlias alias = GetCurrentToken() as AnchorAlias;

            if (alias != null)
            {
                state = states.Pop();
                ParsingEvent evt = new Events.AnchorAlias(alias.Value, alias.Start, alias.End);
                Skip();
                return(evt);
            }

            Mark start = GetCurrentToken().Start;

            Anchor anchor = null;
            Tag    tag    = null;

            // The anchor and the tag can be in any order. This loop repeats at most twice.
            while (true)
            {
                if (anchor == null && (anchor = GetCurrentToken() as Anchor) != null)
                {
                    Skip();
                }
                else if (tag == null && (tag = GetCurrentToken() as Tag) != null)
                {
                    Skip();
                }
                else
                {
                    break;
                }
            }

            string tagName = null;

            if (tag != null)
            {
                if (string.IsNullOrEmpty(tag.Handle))
                {
                    tagName = tag.Suffix;
                }
                else if (tagDirectives.Contains(tag.Handle))
                {
                    tagName = string.Concat(tagDirectives[tag.Handle].Prefix, tag.Suffix);
                }
                else
                {
                    throw new SemanticErrorException(tag.Start, tag.End, "While parsing a node, find undefined tag handle.");
                }
            }
            if (string.IsNullOrEmpty(tagName))
            {
                tagName = null;
            }

            string anchorName = anchor != null?string.IsNullOrEmpty(anchor.Value) ? null : anchor.Value : null;

            bool isImplicit = string.IsNullOrEmpty(tagName);

            if (isIndentlessSequence && GetCurrentToken() is BlockEntry)
            {
                state = ParserState.IndentlessSequenceEntry;

                return(new Events.SequenceStart(
                           anchorName,
                           tagName,
                           isImplicit,
                           SequenceStyle.Block,
                           start,
                           GetCurrentToken().End
                           ));
            }
            else
            {
                Scalar scalar = GetCurrentToken() as Scalar;
                if (scalar != null)
                {
                    bool isPlainImplicit  = false;
                    bool isQuotedImplicit = false;
                    if ((scalar.Style == ScalarStyle.Plain && tagName == null) || tagName == Constants.DefaultHandle)
                    {
                        isPlainImplicit = true;
                    }
                    else if (tagName == null)
                    {
                        isQuotedImplicit = true;
                    }

                    state = states.Pop();
                    ParsingEvent evt = new Events.Scalar(anchorName, tagName, scalar.Value, scalar.Style, isPlainImplicit, isQuotedImplicit, start, scalar.End);

                    Skip();
                    return(evt);
                }

                FlowSequenceStart flowSequenceStart = GetCurrentToken() as FlowSequenceStart;
                if (flowSequenceStart != null)
                {
                    state = ParserState.FlowSequenceFirstEntry;
                    return(new Events.SequenceStart(anchorName, tagName, isImplicit, SequenceStyle.Flow, start, flowSequenceStart.End));
                }

                FlowMappingStart flowMappingStart = GetCurrentToken() as FlowMappingStart;
                if (flowMappingStart != null)
                {
                    state = ParserState.FlowMappingFirstKey;
                    return(new Events.MappingStart(anchorName, tagName, isImplicit, MappingStyle.Flow, start, flowMappingStart.End));
                }

                if (isBlock)
                {
                    BlockSequenceStart blockSequenceStart = GetCurrentToken() as BlockSequenceStart;
                    if (blockSequenceStart != null)
                    {
                        state = ParserState.BlockSequenceFirstEntry;
                        return(new Events.SequenceStart(anchorName, tagName, isImplicit, SequenceStyle.Block, start, blockSequenceStart.End));
                    }

                    BlockMappingStart blockMappingStart = GetCurrentToken() as BlockMappingStart;
                    if (blockMappingStart != null)
                    {
                        state = ParserState.BlockMappingFirstKey;
                        return(new Events.MappingStart(anchorName, tagName, isImplicit, MappingStyle.Block, start, GetCurrentToken().End));
                    }
                }

                if (anchorName != null || tag != null)
                {
                    state = states.Pop();
                    return(new Events.Scalar(anchorName, tagName, string.Empty, ScalarStyle.Plain, isImplicit, false, start, GetCurrentToken().End));
                }

                var current = GetCurrentToken();
                throw new SemanticErrorException(current.Start, current.End, "While parsing a node, did not find expected node content.");
            }
        }