/// <summary> /// Initializes a new instance of the <see cref="DocumentStart"/> class. /// </summary> /// <param name="version">The version.</param> /// <param name="tags">The tags.</param> /// <param name="isImplicit">Indicates whether the event is implicit.</param> /// <param name="start">The start position of the event.</param> /// <param name="end">The end position of the event.</param> public DocumentStart(VersionDirective version, TagDirectiveCollection tags, bool isImplicit, Mark start, Mark end) : base(start, end) { this.version = version; this.tags = tags; this.isImplicit = isImplicit; }
private static void AddDefaultTagDirectives(TagDirectiveCollection directives) { foreach(var directive in Constants.DefaultTagDirectives) { if (!directives.Contains(directive)) { directives.Add(directive); } } }
/// <summary> /// Parse directives. /// </summary> private VersionDirective ProcessDirectives(TagDirectiveCollection tags) { VersionDirective version = null; bool hasOwnDirectives = false; while (true) { VersionDirective currentVersion; TagDirective tag; if ((currentVersion = GetCurrentToken() as VersionDirective) != null) { if (version != null) { throw new SemanticErrorException(currentVersion.Start, currentVersion.End, "Found duplicate %YAML directive."); } if (currentVersion.Version.Major != Constants.MajorVersion || currentVersion.Version.Minor != Constants.MinorVersion) { throw new SemanticErrorException(currentVersion.Start, currentVersion.End, "Found incompatible YAML document."); } version = currentVersion; hasOwnDirectives = true; } else if ((tag = GetCurrentToken() as TagDirective) != null) { if (tags.Contains(tag.Handle)) { throw new SemanticErrorException(tag.Start, tag.End, "Found duplicate %TAG directive."); } tags.Add(tag); hasOwnDirectives = true; } else { break; } Skip(); } AddTagDirectives(tags, Constants.DefaultTagDirectives); if (hasOwnDirectives) { tagDirectives.Clear(); } AddTagDirectives(tagDirectives, tags); return version; }
/// <summary> /// Parse the productions: /// implicit_document ::= block_node DOCUMENT-END* /// * /// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* /// ************************* /// </summary> private ParsingEvent ParseDocumentStart(bool isImplicit) { // Parse extra document end indicators. if (!isImplicit) { while (GetCurrentToken() is DocumentEnd) { Skip(); } } // Parse an isImplicit document. if (isImplicit && !(GetCurrentToken() is VersionDirective || GetCurrentToken() is TagDirective || GetCurrentToken() is DocumentStart || GetCurrentToken() is StreamEnd)) { var directives = new TagDirectiveCollection(); ProcessDirectives(directives); states.Push(ParserState.DocumentEnd); state = ParserState.BlockNode; return new Events.DocumentStart(null, directives, true, GetCurrentToken().Start, GetCurrentToken().End); } // Parse an explicit document. else if (!(GetCurrentToken() is StreamEnd)) { Mark start = GetCurrentToken().Start; var directives = new TagDirectiveCollection(); var versionDirective = ProcessDirectives(directives); var current = GetCurrentToken(); if (!(current is DocumentStart)) { throw new SemanticErrorException(current.Start, current.End, "Did not find expected <document start>."); } states.Push(ParserState.DocumentEnd); state = ParserState.DocumentContent; ParsingEvent evt = new Events.DocumentStart(versionDirective, directives, false, start, current.End); Skip(); return evt; } // Parse the stream end. else { state = ParserState.StreamEnd; ParsingEvent evt = new Events.StreamEnd(GetCurrentToken().Start, GetCurrentToken().End); // Do not call skip here because that would throw an exception if (scanner.MoveNextWithoutConsuming()) { throw new InvalidOperationException("The scanner should contain no more tokens."); } return evt; } }
private static void AddTagDirectives(TagDirectiveCollection directives, IEnumerable<TagDirective> source) { foreach (var directive in source) { if (!directives.Contains(directive)) { directives.Add(directive); } } }
/// <summary> /// Initializes a new instance of the <see cref="DocumentStart"/> class. /// </summary> /// <param name="version">The version.</param> /// <param name="tags">The tags.</param> /// <param name="isImplicit">Indicates whether the event is implicit.</param> public DocumentStart(VersionDirective version, TagDirectiveCollection tags, bool isImplicit) : this(version, tags, isImplicit, Mark.Empty, Mark.Empty) { }
// ReSharper restore UnusedParameter.Local private void AppendTagDirectiveTo(TagDirective value, bool allowDuplicates, TagDirectiveCollection tagDirectives) { if (tagDirectives.Contains(value)) { if (!allowDuplicates) { throw new YamlException("Duplicate %TAG directive."); } } else { tagDirectives.Add(value); } }
private TagDirectiveCollection NonDefaultTagsAmong(IEnumerable<TagDirective> tagCollection) { var directives = new TagDirectiveCollection(); if (tagCollection == null) return directives; foreach (var tagDirective in tagCollection) { AppendTagDirectiveTo(tagDirective, false, directives); } foreach (var tagDirective in Constants.DefaultTagDirectives) { directives.Remove(tagDirective); } return directives; }
/// <summary> /// Parse the productions: /// implicit_document ::= block_node DOCUMENT-END* /// * /// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* /// ************************* /// </summary> private Event ParseDocumentStart(bool isImplicit) { // Parse extra document end indicators. if (!isImplicit) { while (GetCurrentToken() is DocumentEnd) { Skip(); } } // Parse an isImplicit document. if (isImplicit && !(GetCurrentToken() is VersionDirective || GetCurrentToken() is TagDirective || GetCurrentToken() is DocumentStart || GetCurrentToken() is StreamEnd)) { TagDirectiveCollection directives = new TagDirectiveCollection(); ProcessDirectives(directives); states.Push(ParserState.YAML_PARSE_DOCUMENT_END_STATE); state = ParserState.YAML_PARSE_BLOCK_NODE_STATE; return new Events.DocumentStart(null, directives, true, GetCurrentToken().Start, GetCurrentToken().End); } // Parse an explicit document. else if (!(GetCurrentToken() is StreamEnd)) { Mark start = GetCurrentToken().Start; TagDirectiveCollection directives = new TagDirectiveCollection(); VersionDirective versionDirective = ProcessDirectives(directives); var current = GetCurrentToken(); if (!(current is DocumentStart)) { throw new SemanticErrorException(current.Start, current.End, "Did not find expected <document start>."); } states.Push(ParserState.YAML_PARSE_DOCUMENT_END_STATE); state = ParserState.YAML_PARSE_DOCUMENT_CONTENT_STATE; Event evt = new Events.DocumentStart(versionDirective, directives, false, start, current.End); Skip(); return evt; } // Parse the stream end. else { state = ParserState.YAML_PARSE_END_STATE; Event evt = new Events.StreamEnd(GetCurrentToken().Start, GetCurrentToken().End); // Do not call skip here because that would throw an exception if (scanner.InternalMoveNext()) { throw new InvalidOperationException("The scanner should contain no more tokens."); } return evt; } }