/// <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."); } }
void IParsingEventVisitor.Visit(AnchorAlias e) { clonedEvent = new AnchorAlias(e.Value, e.Start, e.End); }