/// <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 Event ParseNode(bool isBlock, bool isIndentlessSequence) { AnchorAlias alias = GetCurrentToken() as AnchorAlias; if (alias != null) { state = states.Pop(); Event 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.YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE; 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(); Event 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.YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE; return(new Events.SequenceStart(anchorName, tagName, isImplicit, SequenceStyle.Flow, start, flowSequenceStart.End)); } FlowMappingStart flowMappingStart = GetCurrentToken() as FlowMappingStart; if (flowMappingStart != null) { state = ParserState.YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE; return(new Events.MappingStart(anchorName, tagName, isImplicit, MappingStyle.Flow, start, flowMappingStart.End)); } if (isBlock) { BlockSequenceStart blockSequenceStart = GetCurrentToken() as BlockSequenceStart; if (blockSequenceStart != null) { state = ParserState.YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE; return(new Events.SequenceStart(anchorName, tagName, isImplicit, SequenceStyle.Block, start, blockSequenceStart.End)); } BlockMappingStart blockMappingStart = GetCurrentToken() as BlockMappingStart; if (blockMappingStart != null) { state = ParserState.YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE; 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."); } }
/// <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) { 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."); } }
private void AnalyzeScalar(Scalar scalar) { var value = scalar.Value; scalarData.value = value; if (value.Length == 0) { if (scalar.Tag == "tag:yaml.org,2002:null") { scalarData.isMultiline = false; scalarData.isFlowPlainAllowed = false; scalarData.isBlockPlainAllowed = true; scalarData.isSingleQuotedAllowed = false; scalarData.isBlockAllowed = false; } else { scalarData.isMultiline = false; scalarData.isFlowPlainAllowed = false; scalarData.isBlockPlainAllowed = false; scalarData.isSingleQuotedAllowed = true; scalarData.isBlockAllowed = false; } return; } var flowIndicators = false; var blockIndicators = false; if (value.StartsWith("---", StringComparison.Ordinal) || value.StartsWith("...", StringComparison.Ordinal)) { flowIndicators = true; blockIndicators = true; } var buffer = new CharacterAnalyzer<StringLookAheadBuffer>(new StringLookAheadBuffer(value)); var preceededByWhitespace = true; var followedByWhitespace = buffer.IsWhiteBreakOrZero(1); var leadingSpace = false; var leadingBreak = false; var trailingSpace = false; var trailingBreak = false; var breakSpace = false; var spaceBreak = false; var previousSpace = false; var previousBreak = false; var lineBreaks = false; var specialCharacters = !ValueIsRepresentableInOutputEncoding(value); var isFirst = true; while (!buffer.EndOfInput) { if (isFirst) { if (buffer.Check(@"#,[]{}&*!|>\""%@`")) { flowIndicators = true; blockIndicators = true; } if (buffer.Check("?:")) { flowIndicators = true; if (followedByWhitespace) blockIndicators = true; } if (buffer.Check('-') && followedByWhitespace) { flowIndicators = true; blockIndicators = true; } } else { if (buffer.Check(",?[]{}")) flowIndicators = true; if (buffer.Check(':')) { flowIndicators = true; if (followedByWhitespace) blockIndicators = true; } if (buffer.Check('#') && preceededByWhitespace) { flowIndicators = true; blockIndicators = true; } } if (!specialCharacters && !buffer.IsPrintable()) { specialCharacters = true; } if (buffer.IsBreak()) { lineBreaks = true; } if (buffer.IsSpace()) { if (isFirst) leadingSpace = true; if (buffer.Buffer.Position >= buffer.Buffer.Length - 1) trailingSpace = true; if (previousBreak) breakSpace = true; previousSpace = true; previousBreak = false; } else if (buffer.IsBreak()) { if (isFirst) leadingBreak = true; if (buffer.Buffer.Position >= buffer.Buffer.Length - 1) trailingBreak = true; if (previousSpace) spaceBreak = true; previousSpace = false; previousBreak = true; } else { previousSpace = false; previousBreak = false; } preceededByWhitespace = buffer.IsWhiteBreakOrZero(); buffer.Skip(1); if (!buffer.EndOfInput) followedByWhitespace = buffer.IsWhiteBreakOrZero(1); isFirst = false; } scalarData.isFlowPlainAllowed = true; scalarData.isBlockPlainAllowed = true; scalarData.isSingleQuotedAllowed = true; scalarData.isBlockAllowed = true; if (leadingSpace || leadingBreak || trailingSpace || trailingBreak) { scalarData.isFlowPlainAllowed = false; scalarData.isBlockPlainAllowed = false; } if (trailingSpace) scalarData.isBlockAllowed = false; if (breakSpace) { scalarData.isFlowPlainAllowed = false; scalarData.isBlockPlainAllowed = false; scalarData.isSingleQuotedAllowed = false; } if (spaceBreak || specialCharacters) { scalarData.isFlowPlainAllowed = false; scalarData.isBlockPlainAllowed = false; scalarData.isSingleQuotedAllowed = false; scalarData.isBlockAllowed = false; } scalarData.isMultiline = lineBreaks; if (lineBreaks) { scalarData.isFlowPlainAllowed = false; scalarData.isBlockPlainAllowed = false; } if (flowIndicators) scalarData.isFlowPlainAllowed = false; if (blockIndicators) scalarData.isBlockPlainAllowed = false; }
void IParsingEventVisitor.Visit(Scalar e) { clonedEvent = new Scalar(null, e.Tag, e.Value, e.Style, e.IsPlainImplicit, e.IsQuotedImplicit, e.Start, e.End); }
private string EmitScalar(Scalar scalar) { return Emit( new SequenceStart(null, null, false, SequenceStyle.Block), scalar, new SequenceEnd() ); }
private ParsingEvent ParseNode(bool isBlock, bool isIndentlessSequence) { YamlDotNet.Core.Tokens.AnchorAlias anchorAlias = GetCurrentToken() as YamlDotNet.Core.Tokens.AnchorAlias; if (anchorAlias != null) { state = states.Pop(); ParsingEvent result = new YamlDotNet.Core.Events.AnchorAlias(anchorAlias.Value, anchorAlias.Start, anchorAlias.End); Skip(); return(result); } Mark start = GetCurrentToken().Start; Anchor anchor = null; YamlDotNet.Core.Tokens.Tag tag = null; while (true) { if (anchor == null && (anchor = (GetCurrentToken() as Anchor)) != null) { Skip(); } else { if (tag != null || (tag = (GetCurrentToken() as YamlDotNet.Core.Tokens.Tag)) == null) { break; } Skip(); } } string text = null; if (tag != null) { if (string.IsNullOrEmpty(tag.Handle)) { text = tag.Suffix; } else { if (!tagDirectives.Contains(tag.Handle)) { throw new SemanticErrorException(tag.Start, tag.End, "While parsing a node, find undefined tag handle."); } text = tagDirectives[tag.Handle].Prefix + tag.Suffix; } } if (string.IsNullOrEmpty(text)) { text = null; } string text2 = (anchor == null) ? null : ((!string.IsNullOrEmpty(anchor.Value)) ? anchor.Value : null); bool flag = string.IsNullOrEmpty(text); if (isIndentlessSequence && GetCurrentToken() is BlockEntry) { state = ParserState.IndentlessSequenceEntry; return(new SequenceStart(text2, text, flag, SequenceStyle.Block, start, GetCurrentToken().End)); } YamlDotNet.Core.Tokens.Scalar scalar = GetCurrentToken() as YamlDotNet.Core.Tokens.Scalar; if (scalar != null) { bool isPlainImplicit = false; bool isQuotedImplicit = false; if ((scalar.Style == ScalarStyle.Plain && text == null) || text == "!") { isPlainImplicit = true; } else if (text == null) { isQuotedImplicit = true; } state = states.Pop(); ParsingEvent result2 = new YamlDotNet.Core.Events.Scalar(text2, text, scalar.Value, scalar.Style, isPlainImplicit, isQuotedImplicit, start, scalar.End); Skip(); return(result2); } FlowSequenceStart flowSequenceStart = GetCurrentToken() as FlowSequenceStart; if (flowSequenceStart != null) { state = ParserState.FlowSequenceFirstEntry; return(new SequenceStart(text2, text, flag, SequenceStyle.Flow, start, flowSequenceStart.End)); } FlowMappingStart flowMappingStart = GetCurrentToken() as FlowMappingStart; if (flowMappingStart != null) { state = ParserState.FlowMappingFirstKey; return(new MappingStart(text2, text, flag, MappingStyle.Flow, start, flowMappingStart.End)); } if (isBlock) { BlockSequenceStart blockSequenceStart = GetCurrentToken() as BlockSequenceStart; if (blockSequenceStart != null) { state = ParserState.BlockSequenceFirstEntry; return(new SequenceStart(text2, text, flag, SequenceStyle.Block, start, blockSequenceStart.End)); } BlockMappingStart blockMappingStart = GetCurrentToken() as BlockMappingStart; if (blockMappingStart != null) { state = ParserState.BlockMappingFirstKey; return(new MappingStart(text2, text, flag, MappingStyle.Block, start, GetCurrentToken().End)); } } if (text2 != null || tag != null) { state = states.Pop(); return(new YamlDotNet.Core.Events.Scalar(text2, text, string.Empty, ScalarStyle.Plain, flag, false, start, GetCurrentToken().End)); } Token token = GetCurrentToken(); throw new SemanticErrorException(token.Start, token.End, "While parsing a node, did not find expected node content."); }
/// <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) { if (GetCurrentToken() is Error errorToken) { throw new SemanticErrorException(errorToken.Start, errorToken.End, errorToken.Value); } var current = GetCurrentToken() ?? throw new SemanticErrorException("Reached the end of the stream while parsing a node"); if (current is AnchorAlias alias) { state = states.Pop(); ParsingEvent evt = new Events.AnchorAlias(alias.Value, alias.Start, alias.End); Skip(); return(evt); } var start = current.Start; string?anchorName = null; string?tagName = null; // The anchor and the tag can be in any order. This loop repeats at most twice. while (true) { if (anchorName == null && current is Anchor anchor) { anchorName = string.IsNullOrEmpty(anchor.Value) ? null : anchor.Value; Skip(); } else if (tagName == null && current is Tag tag) { 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, found undefined tag handle."); } if (string.IsNullOrEmpty(tagName)) { tagName = null; } Skip(); } else if (current is Anchor secondAnchor) { throw new SemanticErrorException(secondAnchor.Start, secondAnchor.End, "While parsing a node, found more than one anchor."); } else if (current is AnchorAlias anchorAlias) { throw new SemanticErrorException(anchorAlias.Start, anchorAlias.End, "While parsing a node, did not find expected token."); } else if (current is Error) { errorToken = (current as Error) !; throw new SemanticErrorException(errorToken.Start, errorToken.End, errorToken.Value); } else { break; } current = GetCurrentToken() ?? throw new SemanticErrorException("Reached the end of the stream while parsing a node"); } var isImplicit = string.IsNullOrEmpty(tagName); if (isIndentlessSequence && GetCurrentToken() is BlockEntry) { state = ParserState.IndentlessSequenceEntry; return(new Events.SequenceStart( anchorName, tagName, isImplicit, SequenceStyle.Block, start, current.End )); } else { if (current is Scalar scalar) { var isPlainImplicit = false; var isQuotedImplicit = false; if ((scalar.Style == ScalarStyle.Plain && tagName == null) || tagName == Constants.DefaultHandle) { isPlainImplicit = true; } else if (tagName == null) { isQuotedImplicit = true; } state = states.Pop(); Skip(); ParsingEvent evt = new Events.Scalar(anchorName, tagName, scalar.Value, scalar.Style, isPlainImplicit, isQuotedImplicit, start, scalar.End); // Read next token to ensure the error case spec test 'CXX2': // "Mapping with anchor on document start line". if (anchorName != null && scanner.MoveNextWithoutConsuming()) { currentToken = scanner.Current; if (currentToken is Error) { errorToken = (currentToken as Error) !; throw new SemanticErrorException(errorToken.Start, errorToken.End, errorToken.Value); } } // Read next token to ensure the error case spec test 'T833': // "Flow mapping missing a separating comma". if (state == ParserState.FlowMappingKey && scanner.MoveNextWithoutConsuming()) { currentToken = scanner.Current; if (currentToken != null && !(currentToken is FlowEntry) && !(currentToken is FlowMappingEnd)) { throw new SemanticErrorException(currentToken.Start, currentToken.End, "While parsing a flow mapping, did not find expected ',' or '}'."); } } return(evt); } if (current is FlowSequenceStart flowSequenceStart) { state = ParserState.FlowSequenceFirstEntry; return(new Events.SequenceStart(anchorName, tagName, isImplicit, SequenceStyle.Flow, start, flowSequenceStart.End)); } if (current is FlowMappingStart flowMappingStart) { state = ParserState.FlowMappingFirstKey; return(new Events.MappingStart(anchorName, tagName, isImplicit, MappingStyle.Flow, start, flowMappingStart.End)); } if (isBlock) { if (current is BlockSequenceStart blockSequenceStart) { state = ParserState.BlockSequenceFirstEntry; return(new Events.SequenceStart(anchorName, tagName, isImplicit, SequenceStyle.Block, start, blockSequenceStart.End)); } if (current is BlockMappingStart blockMappingStart) { state = ParserState.BlockMappingFirstKey; return(new Events.MappingStart(anchorName, tagName, isImplicit, MappingStyle.Block, start, blockMappingStart.End)); } } if (anchorName != null || tagName != null) { state = states.Pop(); return(new Events.Scalar(anchorName, tagName, string.Empty, ScalarStyle.Plain, isImplicit, false, start, current.End)); } throw new SemanticErrorException(current.Start, current.End, "While parsing a node, did not find expected node content."); } }