Пример #1
0
        private void TryParseModifyCommand(SparqlUpdateParserContext context)
        {
            //Firstly we expect the URI that the modifications apply to
            Uri u = this.TryParseIriRef(context, "after a WITH keyword");

            //Now parse the INSERT/DELETE as appropriate
            IToken next = context.Tokens.Dequeue();

            if (next.TokenType == Token.INSERT)
            {
                InsertCommand insertCmd = (InsertCommand)this.TryParseInsertCommand(context, false);
                insertCmd.GraphUri = u;
                context.CommandSet.AddCommand(insertCmd);
            }
            else if (next.TokenType == Token.DELETE)
            {
                SparqlUpdateCommand deleteCmd = this.TryParseDeleteCommand(context, false);
                if (deleteCmd is BaseModificationCommand)
                {
                    ((BaseModificationCommand)deleteCmd).GraphUri = u;
                }
                else
                {
                    throw new RdfParseException("Unexpected Command returned by TryParseDeleteCommand()");
                }
                context.CommandSet.AddCommand(deleteCmd);
            }
            else
            {
                throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected an INSERT/DELETE keyword", next);
            }
        }
Пример #2
0
        private void TryParsePrefixDeclaration(SparqlUpdateParserContext context)
        {
            //Get the next Two Tokens which should be a Prefix and a Uri
            IToken prefix = context.Tokens.Dequeue();
            IToken uri    = context.Tokens.Dequeue();

            if (prefix.TokenType == Token.PREFIX)
            {
                if (uri.TokenType == Token.URI)
                {
                    String baseUri = (context.BaseUri != null) ? context.BaseUri.AbsoluteUri : String.Empty;
                    Uri    u       = UriFactory.Create(Tools.ResolveUri(uri.Value, baseUri));
                    if (prefix.Value.Length == 1)
                    {
                        //Defining prefix for Default Namespace
                        context.NamespaceMap.AddNamespace(String.Empty, u);
                        context.CommandSet.NamespaceMap.AddNamespace(String.Empty, u);
                    }
                    else
                    {
                        //Defining prefix for some other Namespace
                        context.NamespaceMap.AddNamespace(prefix.Value.Substring(0, prefix.Value.Length - 1), u);
                        context.CommandSet.NamespaceMap.AddNamespace(prefix.Value.Substring(0, prefix.Value.Length - 1), u);
                    }
                }
                else
                {
                    throw ParserHelper.Error("Expected a URI Token to follow a Prefix Token to follow the PREFIX Verb in an Update", uri);
                }
            }
            else
            {
                throw ParserHelper.Error("Expected a Prefix Token to follow the PREFIX Verb in an Update", prefix);
            }
        }
Пример #3
0
        internal static INode TryResolveUri(IResultsParserContext context, IToken t)
        {
            switch (t.TokenType)
            {
            case Token.URI:
                try
                {
                    String uri = Tools.ResolveUri(t.Value, String.Empty);
                    return(context.Handler.CreateUriNode(UriFactory.Create(uri)));
                }
#if PORTABLE
                catch (FormatException formatEx)
#else
                catch (UriFormatException formatEx)
#endif
                {
                    throw new RdfParseException("Unable to resolve the URI '" + t.Value + "' due to the following error:\n" + formatEx.Message, t, formatEx);
                }
                catch (RdfException rdfEx)
                {
                    throw new RdfParseException("Unable to resolve the URI '" + t.Value + "' due to the following error:\n" + rdfEx.Message, t, rdfEx);
                }

            default:
                throw ParserHelper.Error("Unexpected Token '" + t.GetType().ToString() + "' encountered, expected a URI/QName Token to resolve into a URI", t);
            }
        }
Пример #4
0
        /// <summary>
        /// Attempts to resolve a QName or URI Token into a URI Node and produces appropriate error messages if this fails
        /// </summary>
        /// <param name="handler">Results Handler</param>
        /// <param name="t">Token to resolve</param>
        /// <returns></returns>
        /// <remarks>
        /// It is <strong>not</strong> recommended to use this overload since an <see cref="IRdfHandler">IRdfHandler</see> cannot resolve QNames
        /// </remarks>
        internal static INode TryResolveUri(ISparqlResultsHandler handler, IToken t)
        {
            switch (t.TokenType)
            {
            case Token.QNAME:
                throw new RdfException("Unable to resolve the QName since a Results Handler does not have a Namespace Map that can be used to resolve QNames");

            case Token.URI:
                try
                {
                    String uri = Tools.ResolveUri(t.Value, String.Empty);
                    return(handler.CreateUriNode(new Uri(uri)));
                }
                catch (UriFormatException formatEx)
                {
                    throw new RdfParseException("Unable to resolve the URI '" + t.Value + "' due to the following error:\n" + formatEx.Message, t, formatEx);
                }
                catch (RdfException rdfEx)
                {
                    throw new RdfParseException("Unable to resolve the URI '" + t.Value + "' due to the following error:\n" + rdfEx.Message, t, rdfEx);
                }

            default:
                throw ParserHelper.Error("Unexpected Token '" + t.GetType().ToString() + "' encountered, expected a URI/QName Token to resolve into a URI", t);
            }
        }
Пример #5
0
        private IToken TryParseObject(ITokenQueue tokens)
        {
            IToken next = tokens.Dequeue();

            switch (next.TokenType)
            {
            case Token.BLANKNODEWITHID:
            case Token.LITERALWITHDT:
            case Token.LITERALWITHLANG:
            case Token.URI:
                //OK
                return(next);

            case Token.LITERAL:
                //Check for Datatype/Language
                IToken temp = tokens.Peek();
                if (temp.TokenType == Token.DATATYPE)
                {
                    tokens.Dequeue();
                    return(new LiteralWithDataTypeToken(next, (DataTypeToken)temp));
                }
                else if (temp.TokenType == Token.LANGSPEC)
                {
                    tokens.Dequeue();
                    return(new LiteralWithLanguageSpecifierToken(next, (LanguageSpecifierToken)temp));
                }
                else
                {
                    return(next);
                }

            default:
                throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a Blank Node/Literal/URI as the Object of a Triple", next);
            }
        }
Пример #6
0
        private void TryParseTriple(IRdfHandler handler, IToken s, IToken p, IToken o, Uri graphUri)
        {
            INode subj, pred, obj;

            switch (s.TokenType)
            {
            case Token.BLANKNODEWITHID:
                subj = handler.CreateBlankNode(s.Value.Substring(2));
                break;

            case Token.URI:
                subj = ParserHelper.TryResolveUri(handler, s);
                break;

            default:
                throw ParserHelper.Error("Unexpected Token '" + s.GetType().ToString() + "' encountered, expected a Blank Node/URI as the Subject of a Triple", s);
            }

            switch (p.TokenType)
            {
            case Token.URI:
                pred = ParserHelper.TryResolveUri(handler, p);
                break;

            default:
                throw ParserHelper.Error("Unexpected Token '" + p.GetType().ToString() + "' encountered, expected a URI as the Predicate of a Triple", p);
            }

            switch (o.TokenType)
            {
            case Token.BLANKNODEWITHID:
                obj = handler.CreateBlankNode(o.Value.Substring(2));
                break;

            case Token.LITERAL:
                obj = handler.CreateLiteralNode(o.Value);
                break;

            case Token.LITERALWITHDT:
                String dtUri = ((LiteralWithDataTypeToken)o).DataType;
                obj = handler.CreateLiteralNode(o.Value, new Uri(dtUri.Substring(1, dtUri.Length - 2)));
                break;

            case Token.LITERALWITHLANG:
                obj = handler.CreateLiteralNode(o.Value, ((LiteralWithLanguageSpecifierToken)o).Language);
                break;

            case Token.URI:
                obj = ParserHelper.TryResolveUri(handler, o);
                break;

            default:
                throw ParserHelper.Error("Unexpected Token '" + o.GetType().ToString() + "' encountered, expected a Blank Node/Literal/URI as the Object of a Triple", o);
            }

            if (!handler.HandleTriple(new Triple(subj, pred, obj, graphUri)))
            {
                ParserHelper.Stop();
            }
        }
Пример #7
0
        private void TryParseCreateCommand(SparqlUpdateParserContext context)
        {
            bool silent = false;

            //May possibly have a SILENT Keyword
            IToken next = context.Tokens.Dequeue();

            if (next.TokenType == Token.SILENT)
            {
                silent = true;
                next   = context.Tokens.Dequeue();
            }

            //Followed by a mandatory GRAPH Keyword
            if (next.TokenType != Token.GRAPH)
            {
                throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a GRAPH Keyword as part of the CREATE command", next);
            }

            //Then MUST have a URI
            Uri           u   = this.TryParseGraphRef(context);
            CreateCommand cmd = new CreateCommand(u, silent);

            context.CommandSet.AddCommand(cmd);
        }
Пример #8
0
        private void TryParseTransferUris(SparqlUpdateParserContext context, out Uri sourceUri, out Uri destUri)
        {
            IToken next = context.Tokens.Dequeue();

            sourceUri = destUri = null;

            //Parse the Source Graph URI
            if (next.TokenType == Token.GRAPH)
            {
                next = context.Tokens.Peek();
                if (next.TokenType == Token.URI || next.TokenType == Token.QNAME)
                {
                    sourceUri = this.TryParseIriRef(context, " to indicate the Source Graph for a Transfer (ADD/COPY/MOVE) command");
                }
                else
                {
                    ParserHelper.Error("Unexpected Token '" + next.GetType().Name + "' encountered, expected a URI/QName after a GRAPH keyword to specify the URI of the Source Graph for a Transfer (ADD/COPY/MOVE) Command", next);
                }
            }
            else if (next.TokenType == Token.DEFAULT)
            {
                sourceUri = null;
            }
            else
            {
                throw ParserHelper.Error("Unexpected Token '" + next.GetType().Name + "' encountered, expected a GRAPH/DEFAULT keyword to indicate the Source Graph for a Transfer (ADD/COPY/MOVE) Command", next);
            }

            //Then get the TO keyword
            next = context.Tokens.Dequeue();
            if (next.TokenType != Token.TO)
            {
                throw ParserHelper.Error("Unexpected Token '" + next.GetType().Name + "' encountered, expected a TO Keyword after the Source Graph specifier", next);
            }

            next = context.Tokens.Dequeue();

            //Parse the Destination Graph URI
            if (next.TokenType == Token.GRAPH)
            {
                next = context.Tokens.Peek();
                if (next.TokenType == Token.URI || next.TokenType == Token.QNAME)
                {
                    destUri = this.TryParseIriRef(context, " to indicate the Destination Graph for a Transfer (ADD/COPY/MOVE) command");
                }
                else
                {
                    ParserHelper.Error("Unexpected Token '" + next.GetType().Name + "' encountered, expected a URI/QName after a GRAPH keyword to specify the URI of the Destination Graph for a Transfer (ADD/COPY/MOVE) Command", next);
                }
            }
            else if (next.TokenType == Token.DEFAULT)
            {
                destUri = null;
            }
            else
            {
                throw ParserHelper.Error("Unexpected Token '" + next.GetType().Name + "' encountered, expected a GRAPH/DEFAULT keyword to indicate the Destination Graph for a Transfer (ADD/COPY/MOVE) Command", next);
            }
        }
Пример #9
0
        private void TryParseHeaderRow(TokenisingResultParserContext context)
        {
            IToken next = context.Tokens.Peek();
            bool   allowEOL = true, expectComma = false;

            while (true)
            {
                next = context.Tokens.Dequeue();
                switch (next.TokenType)
                {
                case Token.EOL:
                    if (allowEOL)
                    {
                        break;
                    }
                    else
                    {
                        throw ParserHelper.Error("Unexpected End of Line, expected a Variable", next);
                    }

                case Token.PLAINLITERAL:
                case Token.LITERAL:
                    if (expectComma)
                    {
                        throw ParserHelper.Error("Unexpected Variable, expected a comma between each Variable", next);
                    }
                    context.Variables.Add(next.Value);
                    if (!context.Handler.HandleVariable(next.Value))
                    {
                        ParserHelper.Stop();
                    }
                    allowEOL    = true;
                    expectComma = true;
                    break;

                case Token.COMMA:
                    expectComma = false;
                    allowEOL    = false;
                    break;

                case Token.EOF:
                    if (!allowEOL)
                    {
                        throw ParserHelper.Error("Unexpected EOF, expected another Variable for the Header Row", next);
                    }
                    break;

                default:
                    throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered", next);
                }

                // Stop when we've hit the End of the Line/File
                if (next.TokenType == Token.EOL || next.TokenType == Token.EOF)
                {
                    break;
                }
            }
        }
Пример #10
0
        private void TryParseDirective(TriGParserContext context)
        {
            //See what type of directive it is
            IToken directive = context.Tokens.Dequeue();

            if (directive.TokenType == Token.BASEDIRECTIVE)
            {
                //Base Directives Invalid in TriG
                throw ParserHelper.Error("The Base Directive is not a valid in TriG", directive);
            }
            else if (directive.TokenType == Token.PREFIXDIRECTIVE)
            {
                //Prefix Directive
                IToken prefix = context.Tokens.Dequeue();
                if (prefix.TokenType == Token.PREFIX)
                {
                    IToken uri = context.Tokens.Dequeue();
                    if (uri.TokenType == Token.URI)
                    {
                        //Ensure the Uri is absolute
                        try
                        {
                            Uri    u   = new Uri(uri.Value, UriKind.Absolute);
                            String pre = (prefix.Value.Equals(":")) ? String.Empty : prefix.Value.Substring(0, prefix.Value.Length - 1);
                            context.Namespaces.AddNamespace(pre, u);
                            if (!context.Handler.HandleNamespace(pre, u))
                            {
                                ParserHelper.Stop();
                            }

                            //Expect a DOT to Terminate
                            IToken dot = context.Tokens.Dequeue();
                            if (dot.TokenType != Token.DOT)
                            {
                                throw ParserHelper.Error("Unexpected Token '" + dot.GetType().ToString() + "' encountered, expected a Dot (Line Terminator) Token to terminate a Prefix Directive", dot);
                            }
                        }
                        catch (UriFormatException)
                        {
                            throw ParserHelper.Error("The URI '" + uri.Value + "' given for the prefix '" + prefix.Value + "' is not a valid Absolute URI", uri);
                        }
                    }
                    else
                    {
                        throw ParserHelper.Error("Unexpected Token '" + prefix.GetType().ToString() + "' encountered, expected a URI Token after a Prefix Token", uri);
                    }
                }
                else
                {
                    throw ParserHelper.Error("Unexpected Token '" + prefix.GetType().ToString() + "' encountered, expected a Prefix Token after a Prefix Directive Token", prefix);
                }
            }
            else
            {
                throw ParserHelper.Error("Unexpected Token '" + directive.GetType().ToString() + "' encountered, expected a Base/Prefix Directive Token", directive);
            }
        }
Пример #11
0
        private IToken TryParsePredicate(ITokenQueue tokens)
        {
            IToken next = tokens.Dequeue();

            switch (next.TokenType)
            {
            case Token.URI:
                //OK
                return(next);

            default:
                throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a URI as the Predicate of a Triple", next);
            }
        }
Пример #12
0
        private IToken TryParseSubject(ITokenQueue tokens)
        {
            IToken next = tokens.Dequeue();

            switch (next.TokenType)
            {
            case Token.BLANKNODEWITHID:
            case Token.URI:
                //OK
                return(next);

            default:
                throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a Blank Node/URI as the Subject of a Triple", next);
            }
        }
Пример #13
0
        private Uri TryParseIriRef(SparqlUpdateParserContext context, String expected)
        {
            IToken next = context.Tokens.Dequeue();

            switch (next.TokenType)
            {
            case Token.URI:
                return(UriFactory.Create(Tools.ResolveUri(next.Value, context.BaseUri.ToSafeString())));

            case Token.QNAME:
                return(UriFactory.Create(Tools.ResolveQName(next.Value, context.NamespaceMap, context.BaseUri)));

            default:
                throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a URI/QName Token " + expected, next);
            }
        }
Пример #14
0
        private void Parse(IRdfHandler handler, ITokenQueue tokens)
        {
            IToken next;
            IToken s, p, o;

            try
            {
                handler.StartRdf();

                //Expect a BOF token at start
                next = tokens.Dequeue();
                if (next.TokenType != Token.BOF)
                {
                    throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a BOF token at the start of the input", next);
                }

                do
                {
                    next = tokens.Peek();
                    if (next.TokenType == Token.EOF)
                    {
                        return;
                    }

                    s = this.TryParseSubject(tokens);
                    p = this.TryParsePredicate(tokens);
                    o = this.TryParseObject(tokens);
                    Uri context = this.TryParseContext(tokens);

                    this.TryParseTriple(handler, s, p, o, context);

                    next = tokens.Peek();
                } while (next.TokenType != Token.EOF);

                handler.EndRdf(true);
            }
            catch (RdfParsingTerminatedException)
            {
                handler.EndRdf(true);
                //Discard this - it justs means the Handler told us to stop
            }
            catch
            {
                handler.EndRdf(false);
                throw;
            }
        }
Пример #15
0
        private void TryParseLoadCommand(SparqlUpdateParserContext context)
        {
            LoadCommand cmd;
            String      baseUri = context.BaseUri.ToSafeString();

            //May optionally have a SILENT keyword
            bool silent = false;

            if (context.Tokens.Peek().TokenType == Token.SILENT)
            {
                silent = true;
                context.Tokens.Dequeue();
            }

            //Expect a URI which is the Source URI
            Uri sourceUri = this.TryParseIriRef(context, "to LOAD data from");

            //Then optionally an INTO GRAPH followed by a Graph URI to assign
            if (context.Tokens.Count > 0)
            {
                IToken next = context.Tokens.Peek();
                if (next.TokenType == Token.INTO)
                {
                    context.Tokens.Dequeue();
                    next = context.Tokens.Dequeue();
                    if (next.TokenType == Token.GRAPH)
                    {
                        Uri destUri = this.TryParseGraphRef(context);
                        cmd = new LoadCommand(sourceUri, destUri, silent);
                    }
                    else
                    {
                        throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a GRAPH keyword after the INTO keyword for a LOAD command", next);
                    }
                }
                else
                {
                    cmd = new LoadCommand(sourceUri, silent);
                }
            }
            else
            {
                cmd = new LoadCommand(sourceUri, silent);
            }
            context.CommandSet.AddCommand(cmd);
        }
Пример #16
0
        private void TryParseBaseDeclaration(SparqlUpdateParserContext context)
        {
            //Get the next Token which should be a Uri Token
            IToken next = context.Tokens.Dequeue();

            if (next.TokenType == Token.URI)
            {
                context.BaseUri                    = UriFactory.Create(next.Value);
                context.CommandSet.BaseUri         = context.BaseUri;
                context.QueryParser.DefaultBaseUri = context.BaseUri;
                context.ExpressionParser.BaseUri   = context.BaseUri;
            }
            else
            {
                throw ParserHelper.Error("Expected a URI Token to follow the BASE Verb in an Update", next);
            }
        }
Пример #17
0
        /// <summary>
        /// Attempts to resolve a QName or URI Token into a URI Node and produces appropriate error messages if this fails
        /// </summary>
        /// <param name="context">Parser Context</param>
        /// <param name="t">Token to resolve</param>
        /// <param name="allowDefaultPrefixFallback">Whether when the default prefix is used but not defined it can fallback to the Base URI</param>
        /// <param name="qnameUnescape">QName unescaping function</param>
        /// <returns></returns>
        public static INode TryResolveUri(IParserContext context, IToken t, bool allowDefaultPrefixFallback, Func <String, String> qnameUnescape)
        {
            switch (t.TokenType)
            {
            case Token.QNAME:
                try
                {
                    return(context.Handler.CreateUriNode(UriFactory.Create(Tools.ResolveQName(qnameUnescape(t.Value), context.Namespaces, context.BaseUri, allowDefaultPrefixFallback))));
                }
#if PORTABLE
                catch (FormatException formatEx)
#else
                catch (UriFormatException formatEx)
#endif
                {
                    throw new RdfParseException("Unable to resolve the QName '" + t.Value + "' due to the following error:\n" + formatEx.Message, t, formatEx);
                }
                catch (RdfException rdfEx)
                {
                    throw new RdfParseException("Unable to resolve the QName '" + t.Value + "' due to the following error:\n" + rdfEx.Message, t, rdfEx);
                }

            case Token.URI:
                try
                {
                    String uri = Tools.ResolveUri(t.Value, context.BaseUri.ToSafeString());
                    return(context.Handler.CreateUriNode(UriFactory.Create(uri)));
                }
#if PORTABLE
                catch (FormatException formatEx)
#else
                catch (UriFormatException formatEx)
#endif
                {
                    throw new RdfParseException("Unable to resolve the URI '" + t.Value + "' due to the following error:\n" + formatEx.Message, t, formatEx);
                }
                catch (RdfException rdfEx)
                {
                    throw new RdfParseException("Unable to resolve the URI '" + t.Value + "' due to the following error:\n" + rdfEx.Message, t, rdfEx);
                }

            default:
                throw ParserHelper.Error("Unexpected Token '" + t.GetType().ToString() + "' encountered, expected a URI/QName Token to resolve into a URI", t);
            }
        }
Пример #18
0
        /// <summary>
        /// Attempts to resolve a QName or URI Token into a URI Node and produces appropriate error messages if this fails
        /// </summary>
        /// <param name="g">Graph</param>
        /// <param name="t">Token to resolve</param>
        /// <returns></returns>
        public static INode TryResolveUri(IGraph g, IToken t)
        {
            switch (t.TokenType)
            {
            case Token.QNAME:
                try
                {
                    return(g.CreateUriNode(t.Value));
                }
#if PORTABLE
                catch (FormatException formatEx)
#else
                catch (UriFormatException formatEx)
#endif
                {
                    throw new RdfParseException("Unable to resolve the QName '" + t.Value + "' due to the following error:\n" + formatEx.Message, t, formatEx);
                }
                catch (RdfException rdfEx)
                {
                    throw new RdfParseException("Unable to resolve the QName '" + t.Value + "' due to the following error:\n" + rdfEx.Message, t, rdfEx);
                }

            case Token.URI:
                try
                {
                    String uri = Tools.ResolveUri(t.Value, g.BaseUri.ToSafeString());
                    return(g.CreateUriNode(UriFactory.Create(uri)));
                }
#if PORTABLE
                catch (FormatException formatEx)
#else
                catch (UriFormatException formatEx)
#endif
                {
                    throw new RdfParseException("Unable to resolve the URI '" + t.Value + "' due to the following error:\n" + formatEx.Message, t, formatEx);
                }
                catch (RdfException rdfEx)
                {
                    throw new RdfParseException("Unable to resolve the URI '" + t.Value + "' due to the following error:\n" + rdfEx.Message, t, rdfEx);
                }

            default:
                throw ParserHelper.Error("Unexpected Token '" + t.GetType().ToString() + "' encountered, expected a URI/QName Token to resolve into a URI", t);
            }
        }
Пример #19
0
        private IEnumerable <KeyValuePair <Uri, bool> > TryParseUsingStatements(SparqlUpdateParserContext context)
        {
            if (context.Tokens.Count > 0)
            {
                String baseUri = (context.BaseUri == null) ? String.Empty : context.BaseUri.AbsoluteUri;
                IToken next    = context.Tokens.Peek();
                bool   named   = false;

                //While we can see USINGs we'll keep returning USING URIs
                do
                {
                    if (context.Tokens.LastTokenType != Token.USING)
                    {
                        context.Tokens.Dequeue();
                    }
                    next = context.Tokens.Peek();

                    if (next.TokenType == Token.NAMED)
                    {
                        context.Tokens.Dequeue();
                        next  = context.Tokens.Peek();
                        named = true;
                    }
                    if (next.TokenType == Token.URI || next.TokenType == Token.QNAME)
                    {
                        //Yield the URI
                        Uri u = this.TryParseIriRef(context, " as part of a USING clause");
                        yield return(new KeyValuePair <Uri, bool>(u, named));
                    }
                    else
                    {
                        throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a URI as part of a USING statement", next);
                    }

                    //Peek at the next thing in case it's a further USING
                    next = context.Tokens.Peek();
                } while (next.TokenType == Token.USING);
            }
            else
            {
                yield break;
            }
        }
Пример #20
0
        private void TryParseModifyCommand(SparqlUpdateParserContext context)
        {
            // Firstly we expect the URI that the modifications apply to
            Uri u = TryParseIriRef(context, "after a WITH keyword");

            // Now parse the INSERT/DELETE as appropriate
            IToken next = context.Tokens.Dequeue();

            if (next.TokenType == Token.INSERT)
            {
                InsertCommand insertCmd = (InsertCommand)TryParseInsertCommand(context, false);
                insertCmd.GraphUri = u;
                context.CommandSet.AddCommand(insertCmd);
            }
            else if (next.TokenType == Token.DELETE)
            {
                SparqlUpdateCommand deleteCmd = TryParseDeleteCommand(context, false);
                if (deleteCmd is DeleteCommand)
                {
                    DeleteCommand delete = ((DeleteCommand)deleteCmd);
                    if (ReferenceEquals(delete.DeletePattern, delete.WherePattern))
                    {
                        throw new RdfParseException("The DELETE WHERE { } shorthand syntax cannot be used in conjunction with a WITH clause");
                    }
                    delete.GraphUri = u;
                }
                else if (deleteCmd is BaseModificationCommand)
                {
                    ((BaseModificationCommand)deleteCmd).GraphUri = u;
                }
                else
                {
                    throw new RdfParseException("Unexpected Command returned by TryParseDeleteCommand()");
                }
                context.CommandSet.AddCommand(deleteCmd);
            }
            else
            {
                throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected an INSERT/DELETE keyword", next);
            }
        }
Пример #21
0
 /// <summary>
 /// Checks whether an attribute is an rdf:nodeID attribute.
 /// </summary>
 /// <param name="attr">Attribute to Test.</param>
 /// <param name="nsMapper">The namespace prefix mappings to use when expanding the namespace prefix of the attribute.</param>
 /// <returns>True if is an rdf:nodeID attribute.</returns>
 /// <remarks>Does some validation on ID value but other validation occurs at other points in the Parsing.</remarks>
 public static bool IsNodeIDAttribute(AttributeEvent attr, INamespaceMapper nsMapper)
 {
     // QName must be rdf:nodeID
     if (nsMapper.HasNamespace(attr.Namespace) && nsMapper.GetNamespaceUri(attr.Namespace).ToString().Equals(NamespaceMapper.RDF) && attr.LocalName.Equals("nodeID"))
     {
         // Must be a valid RDF ID
         if (IsRdfID(attr.Value))
         {
             // OK
             return(true);
         }
         else
         {
             // Invalid RDF ID so Error
             throw ParserHelper.Error("The value '" + attr.Value + "' for rdf:id is not valid, RDF IDs can only be valid NCNames as defined by the W3C XML Namespaces specification", attr);
         }
     }
     else
     {
         return(false);
     }
 }
Пример #22
0
 /// <summary>
 /// Checks whether an attribute is an rdf:nodeID attribute
 /// </summary>
 /// <param name="attr">Attribute to Test</param>
 /// <returns>True if is an rdf:nodeID attribute</returns>
 /// <remarks>Does some validation on ID value but other validation occurs in the <see cref="ValidateID()">ValidateID</see> method which is called at other points in the Parsing</remarks>
 public static bool IsNodeIDAttribute(AttributeEvent attr)
 {
     //QName must be rdf:nodeID
     if (attr.QName.Equals("rdf:nodeID"))
     {
         //Must be a valid RDF ID
         if (IsRdfID(attr.Value))
         {
             //OK
             return(true);
         }
         else
         {
             //Invalid RDF ID so Error
             throw ParserHelper.Error("The value '" + attr.Value + "' for rdf:id is not valid, RDF IDs can only be valid NCNames as defined by the W3C XML Namespaces specification", attr);
         }
     }
     else
     {
         return(false);
     }
 }
Пример #23
0
        /// <summary>
        /// Attempts to resolve a QName or URI Token into a URI Node and produces appropriate error messages if this fails
        /// </summary>
        /// <param name="context">Parser Context</param>
        /// <param name="t">Token to resolve</param>
        /// <returns></returns>
        public static INode TryResolveUri(IStoreParserContext context, IToken t)
        {
            switch (t.TokenType)
            {
            case Token.QNAME:
                try
                {
                    return(context.Handler.CreateUriNode(new Uri(Tools.ResolveQName(t.Value, context.Namespaces, context.BaseUri))));
                }
                catch (UriFormatException formatEx)
                {
                    throw new RdfParseException("Unable to resolve the QName '" + t.Value + "' due to the following error:\n" + formatEx.Message, t, formatEx);
                }
                catch (RdfException rdfEx)
                {
                    throw new RdfParseException("Unable to resolve the QName '" + t.Value + "' due to the following error:\n" + rdfEx.Message, t, rdfEx);
                }

            case Token.URI:
                try
                {
                    String uri = Tools.ResolveUri(t.Value, context.BaseUri.ToSafeString());
                    return(context.Handler.CreateUriNode(new Uri(uri)));
                }
                catch (UriFormatException formatEx)
                {
                    throw new RdfParseException("Unable to resolve the URI '" + t.Value + "' due to the following error:\n" + formatEx.Message, t, formatEx);
                }
                catch (RdfException rdfEx)
                {
                    throw new RdfParseException("Unable to resolve the URI '" + t.Value + "' due to the following error:\n" + rdfEx.Message, t, rdfEx);
                }

            default:
                throw ParserHelper.Error("Unexpected Token '" + t.GetType().ToString() + "' encountered, expected a URI/QName Token to resolve into a URI", t);
            }
        }
Пример #24
0
        private void TryParseDropCommand(SparqlUpdateParserContext context)
        {
            bool silent = false;

            //May possibly have a SILENT Keyword
            IToken next = context.Tokens.Dequeue();

            if (next.TokenType == Token.SILENT)
            {
                silent = true;
                next   = context.Tokens.Dequeue();
            }

            //Then expect a GRAPH followed by a URI or one of the DEFAULT/NAMED/ALL keywords
            if (next.TokenType == Token.GRAPH)
            {
                Uri         u   = this.TryParseGraphRef(context);
                DropCommand cmd = new DropCommand(u, ClearMode.Graph, silent);
                context.CommandSet.AddCommand(cmd);
            }
            else if (next.TokenType == Token.DEFAULT)
            {
                context.CommandSet.AddCommand(new DropCommand(ClearMode.Default, silent));
            }
            else if (next.TokenType == Token.NAMED)
            {
                context.CommandSet.AddCommand(new DropCommand(ClearMode.Named, silent));
            }
            else if (next.TokenType == Token.ALLWORD)
            {
                context.CommandSet.AddCommand(new DropCommand(ClearMode.All, silent));
            }
            else
            {
                throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a GRAPH <URI> to specify the Graph to DROP or one of the DEFAULT/NAMED/ALL keywords", next);
            }
        }
Пример #25
0
        private void TryParseResultRow(TokenisingResultParserContext context)
        {
            IToken next = context.Tokens.Peek();

            if (next.TokenType == Token.EOF)
            {
                context.Tokens.Dequeue();
                return;
            }

            bool         allowEOL = true, expectComma = false;
            int          v      = 0;
            SparqlResult result = new SparqlResult();

            while (true)
            {
                next = context.Tokens.Dequeue();
                switch (next.TokenType)
                {
                case Token.BLANKNODEWITHID:
                    if (expectComma)
                    {
                        throw ParserHelper.Error("Unexpected Blank Node, expected a comma between RDF Terms", next);
                    }
                    if (v >= context.Variables.Count)
                    {
                        throw ParserHelper.Error("Too many RDF Terms, only expecting " + context.Variables.Count + " terms", next);
                    }
                    INode blank = context.Handler.CreateBlankNode(next.Value.Substring(2));
                    result.SetValue(context.Variables[v], blank);
                    v++;
                    allowEOL    = true;
                    expectComma = true;
                    break;

                case Token.LITERAL:
                case Token.PLAINLITERAL:
                    if (expectComma)
                    {
                        throw ParserHelper.Error("Unexpected Blank Node, expected a comma between RDF Terms", next);
                    }
                    if (v >= context.Variables.Count)
                    {
                        throw ParserHelper.Error("Too many RDF Terms, only expecting " + context.Variables.Count + " terms", next);
                    }

                    // Try and guess what kind of term this is
                    String lexicalForm = next.Value;
                    INode  value;
                    if (lexicalForm.StartsWith("http://") || lexicalForm.StartsWith("https://") || lexicalForm.StartsWith("mailto:") || lexicalForm.StartsWith("ftp://"))
                    {
                        try
                        {
                            // Guessing a URI if starts with common URI prefix
                            value = ParserHelper.TryResolveUri(context, next);
                        }
                        catch
                        {
                            // If invalid URI fall back to treating as literal
                            value = context.Handler.CreateLiteralNode(lexicalForm);
                        }
                    }
                    else
                    {
                        value = context.Handler.CreateLiteralNode(lexicalForm);
                    }

                    result.SetValue(context.Variables[v], value);
                    v++;
                    allowEOL    = true;
                    expectComma = true;
                    break;

                case Token.EOL:
                    if (allowEOL)
                    {
                        break;
                    }
                    else
                    {
                        if (v == context.Variables.Count - 1)
                        {
                            // If this is the last expected term then this must be an empty term
                            v++;
                            break;
                        }
                        throw ParserHelper.Error("Unexpected End of Line, expected a RDF Term Token", next);
                    }

                case Token.COMMA:
                    if (!expectComma)
                    {
                        // This is an empty field
                        if (v >= context.Variables.Count)
                        {
                            throw ParserHelper.Error("Too many RDF Terms, only expecting " + context.Variables.Count + " terms", next);
                        }
                        v++;
                    }
                    expectComma = false;
                    allowEOL    = false;
                    break;

                case Token.EOF:
                    if (!allowEOL)
                    {
                        throw ParserHelper.Error("Unexpected EOF, expected another RDF Term for the Result Row", next);
                    }
                    break;

                default:
                    throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered", next);
                }

                // Stop when we've hit the End of the Line/File
                if (next.TokenType == Token.EOL || next.TokenType == Token.EOF)
                {
                    break;
                }
            }

            result.SetVariableOrdering(context.Variables);
            if (!context.Handler.HandleResult(result))
            {
                ParserHelper.Stop();
            }
        }
Пример #26
0
        private void TryParseObjectList(TriGParserContext context, Uri graphUri, INode subj, INode pred)
        {
            bool ok = false;

            do
            {
                //After the first run through we'll need to discard commas here
                if (ok)
                {
                    context.Tokens.Dequeue();
                }

                //Try to get the Object
                IToken obj = context.Tokens.Dequeue();
                IToken next;
                INode  objNode;

                switch (obj.TokenType)
                {
                case Token.COMMENT:
                    //Discard and Continue
                    ok = false;
                    continue;

                case Token.QNAME:
                case Token.URI:
                    objNode = ParserHelper.TryResolveUri(context, obj);
                    break;

                case Token.LITERAL:
                case Token.LONGLITERAL:
                    //Literals

                    //See whether we get a Language Specifier/Data Type next
                    next = context.Tokens.Peek();
                    if (next.TokenType == Token.LANGSPEC)
                    {
                        //Literal with Language Specifier
                        context.Tokens.Dequeue();
                        objNode = context.Handler.CreateLiteralNode(obj.Value, next.Value);
                    }
                    else if (next.TokenType == Token.HATHAT)
                    {
                        //Literal with DataType
                        context.Tokens.Dequeue();
                        //Now expect a QName/Uri Token
                        next = context.Tokens.Dequeue();
                        if (next.TokenType == Token.QNAME || next.TokenType == Token.URI)
                        {
                            Uri dt = UriFactory.Create(Tools.ResolveUriOrQName(next, context.Namespaces, context.BaseUri));
                            objNode = context.Handler.CreateLiteralNode(obj.Value, dt);
                        }
                        else
                        {
                            throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a URI/QName Token to specify a Data Type after a ^^ Token", next);
                        }
                    }
                    else
                    {
                        //Just a string literal
                        objNode = context.Handler.CreateLiteralNode(obj.Value);
                    }
                    break;

                case Token.PLAINLITERAL:
                    //Plain Literals
                    Uri plt = TurtleSpecsHelper.InferPlainLiteralType((PlainLiteralToken)obj, TurtleSyntax.Original);
                    objNode = context.Handler.CreateLiteralNode(obj.Value, plt);
                    break;

                case Token.BLANKNODEWITHID:
                    //Blank Node with ID
                    objNode = context.Handler.CreateBlankNode(obj.Value.Substring(2));
                    break;

                case Token.LEFTSQBRACKET:
                    //Blank Node
                    next = context.Tokens.Peek();
                    if (next.TokenType == Token.RIGHTSQBRACKET)
                    {
                        //Anonymous Blank Node
                        context.Tokens.Dequeue();
                        objNode = context.Handler.CreateBlankNode();
                    }
                    else
                    {
                        //Blank Node Collection
                        objNode = context.Handler.CreateBlankNode();

                        //Do an extra call to TryParsePredicateObjectList to parse the Blank Node Collection
                        this.TryParsePredicateObjectList(context, graphUri, objNode);
                    }
                    break;

                case Token.RIGHTSQBRACKET:
                    //End of Blank Node Collection
                    if (!ok)
                    {
                        throw ParserHelper.Error("Unexpected Token '" + obj.GetType().ToString() + "' encountered before an Object list of a Blank Node Collection was parsed", obj);
                    }
                    return;

                case Token.LEFTBRACKET:
                    //Collection

                    //Check whether an Empty Collection
                    next = context.Tokens.Peek();
                    if (next.TokenType == Token.RIGHTBRACKET)
                    {
                        //Empty Collection
                        context.Tokens.Dequeue();
                        objNode = context.Handler.CreateUriNode(UriFactory.Create(RdfSpecsHelper.RdfListNil));
                    }
                    else
                    {
                        //Collection
                        objNode = context.Handler.CreateBlankNode();
                        this.TryParseCollection(context, graphUri, objNode);
                    }
                    break;

                case Token.EOF:
                    throw ParserHelper.Error("Unexpected End of File while trying to parse Object List", obj);

                case Token.DOT:
                case Token.RIGHTCURLYBRACKET:
                case Token.SEMICOLON:
                    if (!ok)
                    {
                        throw ParserHelper.Error("Unexpected Token '" + obj.GetType().ToString() + "' encountered before an Object list was parsed", obj);
                    }
                    return;

                default:
                    //Unexpected Token
                    throw ParserHelper.Error("Unexpected Token '" + obj.GetType().ToString() + "' encountered, expected a URI/QName/Blank Node as the Object of a Triple", obj);
                }

                ok = true;

                if (!context.Handler.HandleTriple(new Triple(subj, pred, objNode, graphUri)))
                {
                    ParserHelper.Stop();
                }
            } while (context.Tokens.Peek().TokenType == Token.COMMA); //Expect a comma if we are to continue
        }
Пример #27
0
        private Uri TryParseContext(ITokenQueue tokens)
        {
            IToken next = tokens.Dequeue();

            if (next.TokenType == Token.DOT)
            {
                return(null);
            }
            else
            {
                INode context;
                switch (next.TokenType)
                {
                case Token.BLANKNODEWITHID:
                    context = new BlankNode(null, next.Value.Substring(2));
                    break;

                case Token.URI:
                    context = new UriNode(null, new Uri(next.Value));
                    break;

                case Token.LITERAL:
                    //Check for Datatype/Language
                    IToken temp = tokens.Peek();
                    if (temp.TokenType == Token.LANGSPEC)
                    {
                        tokens.Dequeue();
                        context = new LiteralNode(null, next.Value, temp.Value);
                    }
                    else if (temp.TokenType == Token.DATATYPE)
                    {
                        tokens.Dequeue();
                        context = new LiteralNode(null, next.Value, new Uri(temp.Value.Substring(1, temp.Value.Length - 2)));
                    }
                    else
                    {
                        context = new LiteralNode(null, next.Value);
                    }
                    break;

                default:
                    throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a Blank Node/Literal/URI as the Context of the Triple", next);
                }

                //Ensure we then see a . to terminate the Quad
                next = tokens.Dequeue();
                if (next.TokenType != Token.DOT)
                {
                    throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a Dot Token (Line Terminator) to terminate a Triple", next);
                }

                //Finally return the Context URI
                if (context.NodeType == NodeType.Uri)
                {
                    return(((IUriNode)context).Uri);
                }
                else if (context.NodeType == NodeType.Blank)
                {
                    return(new Uri("nquads:bnode:" + context.GetHashCode()));
                }
                else if (context.NodeType == NodeType.Literal)
                {
                    return(new Uri("nquads:literal:" + context.GetHashCode()));
                }
                else
                {
                    throw ParserHelper.Error("Cannot turn a Node of type '" + context.GetType().ToString() + "' into a Context URI for a Triple", next);
                }
            }
        }
Пример #28
0
        private void TryParseCollection(TriGParserContext context, Uri graphUri, INode subj)
        {
            //Create the Nodes we need
            IUriNode rdfFirst, rdfRest, rdfNil;

            rdfFirst = context.Handler.CreateUriNode(UriFactory.Create(RdfSpecsHelper.RdfListFirst));
            rdfRest  = context.Handler.CreateUriNode(UriFactory.Create(RdfSpecsHelper.RdfListRest));
            rdfNil   = context.Handler.CreateUriNode(UriFactory.Create(RdfSpecsHelper.RdfListNil));

            IToken next;
            INode  item, temp;

            item = null;
            do
            {
                next = context.Tokens.Dequeue();

                //Create a Node for this Token
                switch (next.TokenType)
                {
                case Token.COMMENT:
                    //Discard and continue;
                    continue;

                case Token.QNAME:
                case Token.URI:
                    item = ParserHelper.TryResolveUri(context, next);
                    break;

                case Token.LITERAL:
                case Token.LONGLITERAL:

                    break;

                case Token.PLAINLITERAL:
                    Uri plt = TurtleSpecsHelper.InferPlainLiteralType((PlainLiteralToken)next, TurtleSyntax.Original);
                    item = context.Handler.CreateLiteralNode(next.Value, plt);
                    break;

                case Token.LEFTSQBRACKET:
                    //Check whether an anonymous Blank Node or a Blank Node Collection
                    item = context.Handler.CreateBlankNode();

                    next = context.Tokens.Peek();
                    if (next.TokenType == Token.RIGHTSQBRACKET)
                    {
                        //Anonymous Blank Node
                        context.Tokens.Dequeue();
                    }
                    else
                    {
                        //Blank Node Collection
                        this.TryParsePredicateObjectList(context, graphUri, item);
                    }
                    break;

                case Token.LEFTBRACKET:
                    //Check whether an Empty Collection
                    next = context.Tokens.Peek();
                    if (next.TokenType == Token.RIGHTBRACKET)
                    {
                        //Empty Collection
                        context.Tokens.Dequeue();
                        item = context.Handler.CreateUriNode(UriFactory.Create(RdfSpecsHelper.RdfListNil));
                    }
                    else
                    {
                        //Collection
                        item = context.Handler.CreateBlankNode();
                        this.TryParseCollection(context, graphUri, item);
                    }
                    break;

                case Token.EOF:
                    throw ParserHelper.Error("Unexpected End of File while trying to parse a Collection", next);

                default:
                    //Unexpected Token
                    throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a URI/QName/Literal/Blank Node as an item in a Collection", next);
                }

                //Create the subj rdf:first item Triple
                if (!context.Handler.HandleTriple((new Triple(subj, rdfFirst, item, graphUri))))
                {
                    ParserHelper.Stop();
                }

                //Create the rdf:rest Triple
                if (context.Tokens.Peek().TokenType == Token.RIGHTBRACKET)
                {
                    //End of Collection
                    context.Tokens.Dequeue();
                    if (!context.Handler.HandleTriple(new Triple(subj, rdfRest, rdfNil, graphUri)))
                    {
                        ParserHelper.Stop();
                    }
                    return;
                }
                else
                {
                    //Continuing Collection
                    temp = context.Handler.CreateBlankNode();
                    if (!context.Handler.HandleTriple(new Triple(subj, rdfRest, temp, graphUri)))
                    {
                        ParserHelper.Stop();
                    }
                    subj = temp;
                }
            } while (true);
        }
Пример #29
0
        private void TryParseResultRow(TokenisingResultParserContext context)
        {
            IToken next = context.Tokens.Peek();

            if (next.TokenType == Token.EOF)
            {
                context.Tokens.Dequeue();
                return;
            }

            bool         allowEOL = true, expectTab = false;
            int          v      = 0;
            SparqlResult result = new SparqlResult();

            while (true)
            {
                next = context.Tokens.Dequeue();
                switch (next.TokenType)
                {
                case Token.URI:
                    if (expectTab)
                    {
                        throw ParserHelper.Error("Unexpected URI, expected a Tab between RDF Terms", next);
                    }
                    if (v >= context.Variables.Count)
                    {
                        throw ParserHelper.Error("Too many RDF Terms, only expecting " + context.Variables.Count + " terms", next);
                    }
                    INode uri = ParserHelper.TryResolveUri(context, next);
                    result.SetValue(context.Variables[v], uri);
                    v++;
                    allowEOL  = true;
                    expectTab = true;
                    break;

                case Token.BLANKNODEWITHID:
                    if (expectTab)
                    {
                        throw ParserHelper.Error("Unexpected Blank Node, expected a Tab between RDF Terms", next);
                    }
                    if (v >= context.Variables.Count)
                    {
                        throw ParserHelper.Error("Too many RDF Terms, only expecting " + context.Variables.Count + " terms", next);
                    }
                    INode blank = context.Handler.CreateBlankNode(next.Value.Substring(2));
                    result.SetValue(context.Variables[v], blank);
                    v++;
                    allowEOL  = true;
                    expectTab = true;
                    break;

                case Token.LITERAL:
                case Token.LONGLITERAL:
                case Token.PLAINLITERAL:
                    if (expectTab)
                    {
                        throw ParserHelper.Error("Unexpected Blank Node, expected a Tab between RDF Terms", next);
                    }
                    if (v >= context.Variables.Count)
                    {
                        throw ParserHelper.Error("Too many RDF Terms, only expecting " + context.Variables.Count + " terms", next);
                    }
                    INode lit = TryParseLiteral(context, next);
                    result.SetValue(context.Variables[v], lit);
                    v++;
                    allowEOL  = true;
                    expectTab = true;
                    break;

                case Token.EOL:
                    if (allowEOL)
                    {
                        break;
                    }
                    else
                    {
                        if (v == context.Variables.Count - 1)
                        {
                            // If this is the last expected term then this must be an empty term
                            v++;
                            break;
                        }
                        throw ParserHelper.Error("Unexpected End of Line, expected a RDF Term Token", next);
                    }

                case Token.TAB:
                    if (!expectTab)
                    {
                        // This is an empty field
                        if (v >= context.Variables.Count)
                        {
                            throw ParserHelper.Error("Too many RDF Terms, only expecting " + context.Variables.Count + " terms", next);
                        }
                        v++;
                    }
                    expectTab = false;
                    allowEOL  = false;
                    break;

                case Token.EOF:
                    if (!allowEOL)
                    {
                        throw ParserHelper.Error("Unexpected EOF, expected another RDF Term for the Result Row", next);
                    }
                    break;

                default:
                    throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered", next);
                }

                // Stop when we've hit the End of the Line/File
                if (next.TokenType == Token.EOL || next.TokenType == Token.EOF)
                {
                    break;
                }
            }

            if (v < context.Variables.Count)
            {
                throw ParserHelper.Error("Too few RDF Terms, got " + v + " but expected " + context.Variables.Count, next);
            }

            result.SetVariableOrdering(context.Variables);
            if (!context.Handler.HandleResult(result))
            {
                ParserHelper.Stop();
            }
        }
Пример #30
0
        private Uri TryParseContext(IRdfHandler handler, ITokenQueue tokens)
        {
            IToken next = tokens.Dequeue();

            if (next.TokenType == Token.DOT)
            {
                return(null);
            }
            INode context;

            switch (next.TokenType)
            {
            case Token.BLANKNODEWITHID:
                context = handler.CreateBlankNode(next.Value.Substring(2));
                break;

            case Token.URI:
                context = TryParseUri(handler, next.Value);
                break;

            case Token.LITERAL:
                if (this.Syntax != NQuadsSyntax.Original)
                {
                    throw new RdfParseException("Only a Blank Node/URI may be used as the graph name in RDF NQuads 1.1");
                }

                //Check for Datatype/Language
                IToken temp = tokens.Peek();
                switch (temp.TokenType)
                {
                case Token.LANGSPEC:
                    tokens.Dequeue();
                    context = handler.CreateLiteralNode(next.Value, temp.Value);
                    break;

                case Token.DATATYPE:
                    tokens.Dequeue();
                    context = handler.CreateLiteralNode(next.Value, ((IUriNode)TryParseUri(handler, temp.Value.Substring(1, temp.Value.Length - 2))).Uri);
                    break;

                default:
                    context = handler.CreateLiteralNode(next.Value);
                    break;
                }
                break;

            default:
                throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a Blank Node/Literal/URI as the Context of the Triple", next);
            }

            //Ensure we then see a . to terminate the Quad
            next = tokens.Dequeue();
            if (next.TokenType != Token.DOT)
            {
                throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a Dot Token (Line Terminator) to terminate a Triple", next);
            }

            //Finally return the Context URI
            if (context.NodeType == NodeType.Uri)
            {
                return(((IUriNode)context).Uri);
            }
            else if (context.NodeType == NodeType.Blank)
            {
                return(UriFactory.Create("nquads:bnode:" + context.GetHashCode()));
            }
            else if (context.NodeType == NodeType.Literal)
            {
                return(UriFactory.Create("nquads:literal:" + context.GetHashCode()));
            }
            else
            {
                throw ParserHelper.Error("Cannot turn a Node of type '" + context.GetType().ToString() + "' into a Context URI for a Triple", next);
            }
        }