private ParsingEvent ParseNode(bool isBlock, bool isIndentlessSequence)
{
var 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;
var 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
{
var 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;
}
var flowSequenceStart = GetCurrentToken() as FlowSequenceStart;
if (flowSequenceStart != null)
{
state = ParserState.FlowSequenceFirstEntry;
return new Events.SequenceStart(anchorName, tagName, isImplicit, SequenceStyle.Flow, start, flowSequenceStart.End);
}
var flowMappingStart = GetCurrentToken() as FlowMappingStart;
if (flowMappingStart != null)
{
state = ParserState.FlowMappingFirstKey;
return new Events.MappingStart(anchorName, tagName, isImplicit, MappingStyle.Flow, start, flowMappingStart.End);
}
if (isBlock)
{
var blockSequenceStart = GetCurrentToken() as BlockSequenceStart;
if (blockSequenceStart != null)
{
state = ParserState.BlockSequenceFirstEntry;
return new Events.SequenceStart(anchorName, tagName, isImplicit, SequenceStyle.Block, start, blockSequenceStart.End);
}
var 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.");
}
}