コード例 #1
0
        private string PrintValueNode(Node node)
        {
            if (node is Node <UriOrBlank> refNode)
            {
                return(PrintLinkNode(refNode));
            }

            if (node is Node <Text> textNode)
            {
                var val = textNode.Value;
                return($"\"{ValueEncoder.LiteralEscape(val.Value)}\"" +
                       $"@{val.Language}");
            }

            //only write a node with
            var dataType = node.ValueType.DataType == XMLSchema.String?
                           "" : "^^<" + ValueEncoder.UriEscape(node.ValueType.DataType) + ">";

            if (node.ValueString is null)
            {
                throw new Exception("cannot print node without value string");
            }

            return($"\"{ValueEncoder.LiteralEscape(node.ValueString)}\"{dataType}");
        }
コード例 #2
0
        private string PrintLinkNode(Node <UriOrBlank> node)
        {
            if (node is BlankNode b)
            {
                return(b.Scope == _g.Id ?
                       "_:" + b.Label :
                       throw new BlankNodeScopedToInvalidGraph());
            }

            if (node is UriNode u)
            {
                return($"<{ValueEncoder.UriEscape(u.Uri)}>");
            }

            throw new Exception($"Unknown {nameof(UriOrBlank)} node");
        }
コード例 #3
0
        /// <summary>
        /// Create token by scanning source data.
        /// </summary>
        public static Token NextToken(ReadOnlySpan <char> data)
        {
            if (data.IsEmpty)
            {
                return(Token.Invalid(data));
            }

            if (char.IsWhiteSpace(data[0]))
            {
                return(new Token(
                           NTripleTokenType.Whitespace, data.Slice(0, 1), data.Slice(1)));
            }

            if (data[0] == '.')
            {
                return(new Token(
                           NTripleTokenType.Dot, data.Slice(0, 1), data.Slice(1)));
            }

            int end;

            if (data[0] == '"')
            {
                end = -1;
                var escape = false;
                for (var i = 1; i < data.Length; i++)
                {
                    if (data[i] == '"' && !escape)
                    {
                        end = i; break;
                    }

                    //skip \\
                    if (data[i] == '\\' &&
                        i + 1 < data.Length && data[i + 1] == '\\')
                    {
                        i++; continue;
                    }

                    escape = data[i] == '\\';
                }

                if (end < 0)
                {
                    return(Token.Invalid(data));
                }

                return(new Token(
                           NTripleTokenType.Literal,
                           data.Slice(1, end - 1),
                           data.Slice(end + 1)
                           ));
            }

            if (data[0] == '<')
            {
                end = data.IndexOf(">");
                if (end < 0)
                {
                    return(Token.Invalid(data));
                }

                var val = ValueEncoder.LiteralUnEscape(data.Slice(1, end - 1));
                return(new Token(
                           NTripleTokenType.Uri, val, data.Slice(end + 1)));
            }

            if (data[0] == '#')
            {
                //safe for EOL \r\n or \n

                end = data.IndexOf('\n');
                if (end < 0)
                {
                    end = data.Length;
                }

                var remainder =
                    end == data.Length ?
                    ReadOnlySpan <char> .Empty :
                    data.Slice(end + 1);

                if (data[end - 1] == '\r')
                {
                    end--;
                }

                var value = end == data.Length ?
                            data.Slice(1) : data.Slice(1, end);

                return(new Token(NTripleTokenType.Comment,
                                 value, remainder));
            }

            if (data.StartsWith("_:"))
            {
                end = 2;
                if (end == data.Length || IsInvalidBlankStartChar(data[end]))
                {
                    throw new Exception(
                              "Blank label cannot start with a " +
                              (end == data.Length ? "no-char" : data[end].ToString()));
                }

                for (end = 3; end < data.Length; end++)
                {
                    var ch = data[end];

                    if (!IsValidBlankChar(ch))
                    {
                        end--; break;
                    }
                }

                if (end == data.Length)
                {
                    end--;
                }

                //cannot end on a .
                if (data[end] == '.')
                {
                    end--;
                }

                var rest = end + 1 < data.Length ? data.Slice(end + 1)
                                        : ReadOnlySpan <char> .Empty;

                return(new Token(
                           NTripleTokenType.Blank,
                           data.Slice(2, end - 1), rest));
            }

            if (data[0] == '@')
            {
                end = IndexOfWhitespace(data);
                if (end < 0)
                {
                    return(Token.Invalid(data));
                }

                return(new Token(
                           NTripleTokenType.Language,
                           data.Slice(1, end - 1),
                           data.Slice(end)
                           ));
            }

            if (data.StartsWith("^^<"))
            {
                end = data.IndexOf('>');
                if (end < 0)
                {
                    return(Token.Invalid(data));
                }

                return(new Token(NTripleTokenType.DataType,
                                 data.Slice(3, end - 3),
                                 data.Slice(end + 1)));
            }

            return(Token.Invalid(data));
        }
コード例 #4
0
        /// <summary>
        /// Handle the next <see cref="NTripleTokenizer.Token"/>
        /// </summary>
        public void Next(NTripleTokenizer.Token token)
        {
            if (token.Type == NTripleTokenType.Invalid)
            {
                throw new Exception("Invalid token");
            }

            if (token.Type == NTripleTokenType.Whitespace)
            {
                return;
            }

            if (token.Type == NTripleTokenType.Comment)
            {
                return;
            }

            if (_subject is null)
            {
                if (token.Type == NTripleTokenType.Uri)
                {
                    IsValidUri(token.Value);
                    _subject = _graph.Uri(ValueEncoder.UriUnEscape(token.Value));
                    return;
                }

                if (token.Type == NTripleTokenType.Blank)
                {
                    _subject = _graph.Blank(token.Value);
                    return;
                }
                throw new Exception("Expected uri for subject");
            }

            if (_predicate is null)
            {
                if (token.Type == NTripleTokenType.Uri)
                {
                    IsValidUri(token.Value);
                    _predicate = _graph.Uri(
                        ValueEncoder.UriUnEscape(token.Value));
                    return;
                }

                throw new Exception("Expected uri for predicate");
            }

            if (_object is null)
            {
                if (token.Type == NTripleTokenType.Uri)
                {
                    IsValidUri(token.Value);
                    _object = _graph.Uri(token.Value);
                    return;
                }

                if (token.Type == NTripleTokenType.Blank)
                {
                    _object = _graph.Blank(token.Value);
                    return;
                }

                if (_objectParts is null)
                {
                    if (token.Type != NTripleTokenType.Literal)
                    {
                        throw new Exception("expected literal for object value");
                    }
                    _objectParts = new ObjectParts
                    {
                        Literal = ValueEncoder.LiteralUnEscape(token.Value)
                    };
                    return;
                }

                if (token.Type == NTripleTokenType.Language)
                {
                    IsValidLanguageTag(token.Value);
                    _objectParts.Lang = new string(token.Value);
                    return;
                }

                if (token.Type == NTripleTokenType.DataType)
                {
                    IsValidUri(token.Value);
                    _objectParts.ValueType = new string(token.Value);
                    return;
                }
            }

            if (token.Type != NTripleTokenType.Dot)
            {
                throw new Exception("Expected dot to end triple.");
            }

            if (_object is null && _objectParts != null)
            {
                _object = _graph.NewNode(_objectParts.Literal,
                                         ValueEncoder.UriUnEscape(_objectParts.ValueType),
                                         _objectParts.Lang);
            }

            if (_object is null)
            {
                throw new Exception("Expected object to be created");
            }

            _graph.Assert(_subject, _predicate, _object);

            //reset for next triple.
            _subject     = null;
            _predicate   = null;
            _object      = null;
            _objectParts = null;
        }