示例#1
0
        /// <summary>
        /// Tries to parse Literal Tokens into Literal Nodes
        /// </summary>
        /// <param name="context">Parser Context</param>
        /// <param name="lit">Literal Token</param>
        /// <returns></returns>
        private INode TryParseLiteral(Notation3ParserContext context, IToken lit)
        {
            IToken next;
            String dturi;

            switch (lit.TokenType)
            {
                case Token.LITERAL:
                case Token.LONGLITERAL:
                    next = context.Tokens.Peek();
                    if (next.TokenType == Token.LANGSPEC)
                    {
                        //Has a Language Specifier
                        next = context.Tokens.Dequeue();
                        return context.Handler.CreateLiteralNode(lit.Value, next.Value);
                    }
                    else if (next.TokenType == Token.HATHAT)
                    {
                        //Discard the ^^
                        next = context.Tokens.Dequeue();

                        //Has a Datatype
                        next = context.Tokens.Dequeue();
                        if (next.TokenType == Token.DATATYPE)
                        {
                            try
                            {
                                if (next.Value.StartsWith("<"))
                                {
                                    dturi = next.Value.Substring(1, next.Value.Length - 2);
                                    return context.Handler.CreateLiteralNode(lit.Value, UriFactory.Create(Tools.ResolveUri(dturi, context.BaseUri.ToSafeString())));
                                }
                                else
                                {
                                    dturi = Tools.ResolveQName(next.Value, context.Namespaces, context.BaseUri);
                                    return context.Handler.CreateLiteralNode(lit.Value, UriFactory.Create(dturi));
                                }
                            }
                            catch (RdfException rdfEx)
                            {
                                throw new RdfParseException("Unable to resolve the Datatype '" + next.Value + "' due to the following error:\n" + rdfEx.Message, next, rdfEx);
                            }
                        }
                        else
                        {
                            throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a Datatype Token after a ^^ datatype specifier", next);
                        }
                    }
                    else
                    {
                        //Just an untyped Literal
                        return context.Handler.CreateLiteralNode(lit.Value);
                    }

                case Token.LITERALWITHDT:
                    LiteralWithDataTypeToken litdt = (LiteralWithDataTypeToken)lit;
                    try
                    {
                        if (litdt.DataType.StartsWith("<"))
                        {
                            dturi = litdt.DataType.Substring(1, litdt.DataType.Length - 2);
                            return context.Handler.CreateLiteralNode(litdt.Value, UriFactory.Create(Tools.ResolveUri(dturi, context.BaseUri.ToSafeString())));
                        }
                        else
                        {
                            dturi = Tools.ResolveQName(litdt.DataType, context.Namespaces, context.BaseUri);
                            return context.Handler.CreateLiteralNode(litdt.Value, UriFactory.Create(dturi));
                        }
                    }
                    catch (RdfException rdfEx)
                    {
                        throw new RdfParseException("Unable to resolve the Datatype '" + litdt.DataType + "' due to the following error:\n" + rdfEx.Message, litdt, rdfEx);
                    }

                case Token.LITERALWITHLANG:
                    LiteralWithLanguageSpecifierToken langlit = (LiteralWithLanguageSpecifierToken)lit;
                    return context.Handler.CreateLiteralNode(langlit.Value, langlit.Language);

                case Token.PLAINLITERAL:
                    //Attempt to infer Type
                    if (TurtleSpecsHelper.IsValidPlainLiteral(lit.Value, TurtleSyntax.Original))
                    {
                        if (TurtleSpecsHelper.IsValidDouble(lit.Value))
                        {
                            return context.Handler.CreateLiteralNode(lit.Value, UriFactory.Create(XmlSpecsHelper.XmlSchemaDataTypeDouble));
                        }
                        else if (TurtleSpecsHelper.IsValidInteger(lit.Value))
                        {
                            return context.Handler.CreateLiteralNode(lit.Value, UriFactory.Create(XmlSpecsHelper.XmlSchemaDataTypeInteger));
                        }
                        else if (TurtleSpecsHelper.IsValidDecimal(lit.Value))
                        {
                            return context.Handler.CreateLiteralNode(lit.Value, UriFactory.Create(XmlSpecsHelper.XmlSchemaDataTypeDecimal));
                        }
                        else
                        {
                            return context.Handler.CreateLiteralNode(lit.Value, UriFactory.Create(XmlSpecsHelper.XmlSchemaDataTypeBoolean));
                        }
                    }
                    else
                    {
                        throw ParserHelper.Error("The value '" + lit.Value + "' is not valid as a Plain Literal in Turtle", lit);
                    }
                default:
                    throw ParserHelper.Error("Unexpected Token '" + lit.GetType().ToString() + "' encountered, expected a valid Literal Token to convert to a Node", lit);
            }
        }
示例#2
0
        /// <summary>
        /// Tries to parse Object lists
        /// </summary>
        /// <param name="context">Parse Context</param>
        /// <param name="subj">Subject of the Triples</param>
        /// <param name="pred">Predicate of the Triples</param>
        /// <param name="bnodeList">Whether this is a Blank Node Object list</param>
        /// <param name="reverse">Indicates whether the asserted triples should have it's subject and object swapped</param>
        private void TryParseObjectList(Notation3ParserContext context, INode subj, INode pred, bool bnodeList, bool reverse)
        {
            IToken objToken, next;
            INode obj = null;

            do
            {
                objToken = context.Tokens.Dequeue();

                if (context.TraceParsing)
                {
                    Console.WriteLine("Attempting to parse an Object List from the Object Token '" + objToken.GetType().ToString() + "'");
                }

                switch (objToken.TokenType)
                {
                    case Token.BLANKNODE:
                        obj = context.Handler.CreateBlankNode();
                        break;

                    case Token.BLANKNODEWITHID:
                        obj = context.Handler.CreateBlankNode(objToken.Value.Substring(2));
                        break;

                    case Token.COMMA:
                        //Discard and continue - set object to null so we know we're expected to complete a triple
                        if (obj != null)
                        {
                            obj = null;
                            continue;
                        }
                        else
                        {
                            throw ParserHelper.Error("Unexpected Comma Triple terminator encountered, expected a valid Object for the current Triple", objToken);
                        }

                    case Token.COMMENT:
                        //Discard and ignore
                        continue;

                    case Token.DOT:
                        if (obj != null)
                        {
                            //OK to return if we've seen a valid Triple
                            return;
                        }
                        else
                        {
                            throw ParserHelper.Error("Unexpected Dot Triple terminator encountered, expected a valid Object for the current Triple", objToken);
                        }

                    case Token.EXCLAMATION:
                    case Token.HAT:
                        //Path
                        pred = this.TryParsePath(context, pred);
                        this.TryParseObjectList(context, subj, pred, bnodeList, reverse);
                        return;

                    case Token.LEFTBRACKET:
                        //Start of a collection so create a new Blank Node to be it's first subject
                        next = context.Tokens.Peek();
                        if (next.TokenType == Token.RIGHTBRACKET)
                        {
                            //Empty Collection => rdf:nil
                            context.Tokens.Dequeue();
                            obj = context.Handler.CreateUriNode(UriFactory.Create(NamespaceMapper.RDF + "nil"));
                        }
                        else
                        {
                            obj = context.Handler.CreateBlankNode();
                            this.TryParseCollection(context, obj);
                        }
                        break;

                    case Token.LEFTCURLYBRACKET:
                        //Start of a Graph Literal
                        next = context.Tokens.Peek();
                        if (next.TokenType == Token.RIGHTCURLYBRACKET)
                        {
                            //An Empty Graph Literal
                            context.Tokens.Dequeue();
                            obj = context.Handler.CreateGraphLiteralNode();
                        }
                        else
                        {
                            obj = this.TryParseGraphLiteral(context);
                        }
                        break;

                    case Token.LEFTSQBRACKET:
                        //Start of a Blank Node collection?
                        next = context.Tokens.Peek();
                        if (next.TokenType == Token.RIGHTSQBRACKET)
                        {
                            //An anonymous Blank Node
                            context.Tokens.Dequeue();
                            obj = context.Handler.CreateBlankNode();
                        }
                        else
                        {
                            //Start of a Blank Node Collection
                            obj = context.Handler.CreateBlankNode();
                            this.TryParsePredicateObjectList(context, obj, true);
                        }
                        break;

                    case Token.LITERAL:
                    case Token.LITERALWITHDT:
                    case Token.LITERALWITHLANG:
                    case Token.LONGLITERAL:
                    case Token.PLAINLITERAL:
                        obj = this.TryParseLiteral(context, objToken);
                        break;

                    case Token.RIGHTCURLYBRACKET:
                        if (context.GraphLiteralMode)
                        {
                            return;
                        }
                        else
                        {
                            throw ParserHelper.Error("Unexpected Right Curly Bracket encountered but not expecting the end of a Graph Literal", objToken);
                        }

                    case Token.RIGHTSQBRACKET:
                        if (bnodeList)
                        {
                            if (obj != null)
                            {
                                //Ok to return if we've seen a Triple
                                return;
                            }
                            else
                            {
                                throw ParserHelper.Error("Unexpected Right Square Bracket encountered, expecting a valid object for the current Blank Node Predicate Object list", objToken);
                            }
                        }
                        else
                        {
                            throw ParserHelper.Error("Unexpected Right Square Bracket encountered but not expecting the end of a Blank Node Predicate Object list", objToken);
                        }

                    case Token.SEMICOLON:
                        if (obj != null)
                        {
                            //Ok to return if we've seen a Triple
                            return;
                        }
                        else
                        {
                            throw ParserHelper.Error("Unexpected Semicolon Triple terminator encountered, expected a valid Object for the current Triple", objToken);
                        }

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

                    case Token.VARIABLE:
                        obj = context.Handler.CreateVariableNode(objToken.Value.Substring(1));
                        break;

                    case Token.EOF:
                        throw ParserHelper.Error("Unexpected end of file while trying to parse an Object list", objToken);

                    default:
                        throw ParserHelper.Error("Unexpected Token '" + objToken.GetType().ToString() + "' encountered while trying to parse an Object list", objToken);
                }

                //Watch out for Paths
                next = context.Tokens.Peek();
                if (next.TokenType == Token.EXCLAMATION || next.TokenType == Token.HAT)
                {
                    context.Tokens.Dequeue();
                    obj = this.TryParsePath(context, obj);
                }

                //Assert the Triple
                if (!reverse)
                {
                    if (!context.Handler.HandleTriple(new Triple(subj, pred, obj, context.VariableContext))) ParserHelper.Stop();
                }
                else
                {
                    //When reversed this means the predicate was Implied By (<=)
                    if (!context.Handler.HandleTriple(new Triple(obj, pred, subj, context.VariableContext))) ParserHelper.Stop();
                }

                //Expect a comma/semicolon/dot terminator if we are to continue
                next = context.Tokens.Peek();
                if (context.GraphLiteralMode)
                {
                    if (next.TokenType != Token.COMMA && next.TokenType != Token.SEMICOLON && next.TokenType != Token.DOT && next.TokenType != Token.RIGHTCURLYBRACKET)
                    {
                        throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered while trying to parse an Object list, expected a comma, semicolon or dot to terminate the current Triple or a } to terminate the Graph Literal", next);
                    }
                }
                else if (bnodeList)
                {
                    //If in a Blank Node list a dot is not permitted but a ] is
                    if (next.TokenType != Token.COMMA && next.TokenType != Token.SEMICOLON && next.TokenType != Token.RIGHTSQBRACKET)
                    {
                        throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered while trying to parse a Blank Node Object List, expected a comma, semicolon or ] to terminate the current Triple/list", next);
                    }
                }
                else if (next.TokenType != Token.COMMA && next.TokenType != Token.SEMICOLON && next.TokenType != Token.DOT)
                {
                    throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered while trying to parse an Object list, expected a comma, semicolon or dot to terminate the current Triple", next);
                }
            } while (true);
        }
示例#3
0
        /// <summary>
        /// Tries to parse forSome quantifiers
        /// </summary>
        /// <param name="context">Parser Context</param>
        private void TryParseForSome(Notation3ParserContext context)
        {
            //We know the Token we've just got off the Queue was a ForSomeQuantifierToken
            //Therefore the next Token(s) should be QNames/URIs leading to a DotToken

            //Create a new Variable Context if one doesn't currently exist
            if (context.VariableContext.Type == VariableContextType.None)
            {
                context.VariableContext = new VariableContext(VariableContextType.Existential);
            }
            else
            {
                context.VariableContext.InnerContext = new VariableContext(VariableContextType.Existential);
            }

            context.Tokens.Dequeue();
            IToken next = context.Tokens.Dequeue();
            while (next.TokenType != Token.DOT)
            {
                //Get Variables
                switch (next.TokenType)
                {
                    case Token.QNAME:
                    case Token.URI:
                        context.VariableContext.AddVariable(ParserHelper.TryResolveUri(context, next));
                        break;

                    default:
                        throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a URI/QName for an Existential Variable as part of a @forSome directive", next);
                }

                next = context.Tokens.Dequeue();

                //May optionally have a COMMA between each QName/URI
                if (next.TokenType == Token.COMMA)
                {
                    next = context.Tokens.Dequeue();
                }
            }

            this.RaiseWarning("Parser does not know how to evaluate forSome Quantifiers");
        }
示例#4
0
        /// <summary>
        /// Tries to parse a Graph Literal
        /// </summary>
        /// <param name="context"></param>
        private INode TryParseGraphLiteral(Notation3ParserContext context)
        {
            context.PushGraph();

            //Watch out for nesting
            //This counter starts as zero since the last right curly bracket will be discarded by the
            //parser when it stops parsing the Graph Literal in one of the other functions
            int nesting = 1;
            IToken next = context.Tokens.Peek();
            while (next.TokenType == Token.LEFTCURLYBRACKET)
            {
                context.Tokens.Dequeue();
                next = context.Tokens.Peek();
                nesting++;
            }

            do
            {
                next = context.Tokens.Peek();
                if (next.TokenType == Token.FORALL)
                {
                    this.TryParseForAll(context);
                }
                else if (next.TokenType == Token.FORSOME)
                {
                    this.TryParseForSome(context);
                }
                else
                {
                    this.TryParseTriples(context);
                }

                //If we've just seen a Right Curly bracket we've been terminated
                if (context.Tokens.LastTokenType == Token.RIGHTCURLYBRACKET)
                {
                    //Decrease the amount of expected nesting
                    nesting--;
                    break;
                }

                next = context.Tokens.Peek();
            } while (next.TokenType != Token.RIGHTCURLYBRACKET);

            IGraph subgraph = context.SubGraph;
            context.PopGraph();

            //Expect the correct number of closing brackets
            while (nesting > 0)
            {
                next = context.Tokens.Dequeue();
                if (next.TokenType != Token.RIGHTCURLYBRACKET)
                {
                    throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a Right Curly Bracket to terminate a Graph Literal", next);
                }
                nesting--;
            }

            return context.Handler.CreateGraphLiteralNode(subgraph);
        }
示例#5
0
        /// <summary>
        /// Tries to parse Collections
        /// </summary>
        /// <param name="context">Parser Context</param>
        /// <param name="firstSubj">Blank Node which is the head of the collection</param>
        private void TryParseCollection(Notation3ParserContext context, INode firstSubj)
        {
            //The opening bracket of the collection will already have been discarded when we get called
            IToken next, temp;
            INode subj = firstSubj;
            INode obj = null, nextSubj;
            INode rdfFirst = context.Handler.CreateUriNode(UriFactory.Create(NamespaceMapper.RDF + "first"));
            INode rdfRest = context.Handler.CreateUriNode(UriFactory.Create(NamespaceMapper.RDF + "rest"));
            INode rdfNil = context.Handler.CreateUriNode(UriFactory.Create(NamespaceMapper.RDF + "nil"));

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

                if (context.TraceParsing)
                {
                    Console.WriteLine("Trying to parse a Collection item from Token '" + next.GetType().ToString() + "'");
                }

                switch (next.TokenType)
                {
                    case Token.BLANKNODE:
                        obj = context.Handler.CreateBlankNode();
                        break;
                    case Token.BLANKNODEWITHID:
                        obj = context.Handler.CreateBlankNode(next.Value.Substring(2));
                        break;
                    case Token.COMMENT:
                        //Discard and continue
                        continue;
                    case Token.LEFTBRACKET:
                        //Nested Collection?
                        temp = context.Tokens.Peek();
                        if (temp.TokenType == Token.RIGHTBRACKET)
                        {
                            //Empty Collection => rdf:nil
                            context.Tokens.Dequeue();
                            obj = rdfNil;
                        }
                        else
                        {
                            //Collection
                            obj = context.Handler.CreateBlankNode();
                            this.TryParseCollection(context, obj);
                        }
                        break;

                    case Token.LEFTCURLYBRACKET:
                        //Graph Literal
                        temp = context.Tokens.Peek();
                        if (temp.TokenType == Token.RIGHTCURLYBRACKET)
                        {
                            //Empty Graph Literal
                            context.Tokens.Dequeue();
                            obj = context.Handler.CreateGraphLiteralNode();
                        }
                        else
                        {
                            //Graph Literal
                            obj = this.TryParseGraphLiteral(context);
                        }
                        break;

                    case Token.LEFTSQBRACKET:
                        //Allowed Blank Node Collections as part of a Collection
                        temp = context.Tokens.Peek();
                        if (temp.TokenType == Token.RIGHTSQBRACKET)
                        {
                            //Anonymous Blank Node
                            context.Tokens.Dequeue();
                            obj = context.Handler.CreateBlankNode();
                        }
                        else
                        {
                            //Blank Node Collection
                            obj = context.Handler.CreateBlankNode();
                            this.TryParsePredicateObjectList(context, obj, true);
                        }
                        break;
                    case Token.LITERAL:
                    case Token.LITERALWITHDT:
                    case Token.LITERALWITHLANG:
                    case Token.LONGLITERAL:
                    case Token.PLAINLITERAL:
                        obj = this.TryParseLiteral(context, next);
                        break;

                    case Token.RIGHTBRACKET:
                        //We might terminate here if someone put a comment before the end of the Collection
                        if (!context.Handler.HandleTriple(new Triple(subj, rdfFirst, obj, context.VariableContext))) ParserHelper.Stop();
                        if (!context.Handler.HandleTriple(new Triple(subj, rdfRest, rdfNil, context.VariableContext))) ParserHelper.Stop();
                        return;

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

                    case Token.VARIABLE:
                        obj = context.Handler.CreateVariableNode(next.Value.Substring(1));
                        break;

                    default:
                        throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered while trying to parse a Collection", next);
                }

                //Watch out for Paths
                next = context.Tokens.Peek();
                if (next.TokenType == Token.EXCLAMATION || next.TokenType == Token.HAT)
                {
                    context.Tokens.Dequeue();
                    obj = this.TryParsePath(context, obj);
                }

                //Assert the relevant Triples
                if (!context.Handler.HandleTriple(new Triple(subj, rdfFirst, obj, context.VariableContext))) ParserHelper.Stop();
                if (context.Tokens.Peek().TokenType == Token.RIGHTBRACKET)
                {
                    //End of the Collection
                    context.Tokens.Dequeue();
                    if (!context.Handler.HandleTriple(new Triple(subj, rdfRest, rdfNil, context.VariableContext))) ParserHelper.Stop();
                    return;
                }
                else
                {
                    //More stuff in the collection
                    nextSubj = context.Handler.CreateBlankNode();
                    if (!context.Handler.HandleTriple(new Triple(subj, rdfRest, nextSubj, context.VariableContext))) ParserHelper.Stop();
                    subj = nextSubj;
                }
            } while (true);
        }
示例#6
0
        /// <summary>
        /// Tries to parse declarations
        /// </summary>
        /// <param name="context">Parse Context</param>
        private void TryParseDirective(Notation3ParserContext context)
        {
            if (context.TraceParsing)
            {
                Console.WriteLine("Attempting to parse a Directive");
            }

            //We expect either a Base Directive/Prefix/Keywords Directive
            IToken directive = context.Tokens.Dequeue();
            if (directive.TokenType == Token.BASEDIRECTIVE)
            {
                //Then expect a Uri for the Base Uri
                IToken u = context.Tokens.Dequeue();
                if (u.TokenType == Token.URI)
                {
                    //Set the Base Uri resolving against the current Base if any
                    Uri baseUri = ((IUriNode)ParserHelper.TryResolveUri(context, u)).Uri;
                    context.BaseUri = baseUri;
                    if (!context.Handler.HandleBaseUri(baseUri)) ParserHelper.Stop();
                }
                else
                {
                    throw ParserHelper.Error("Unexpected Token '" + u.GetType().ToString() + "' encountered, expected a URI after a Base Directive", u);
                }
            }
            else if (directive.TokenType == Token.PREFIXDIRECTIVE)
            {
                //Expect a Prefix then a Uri
                IToken pre = context.Tokens.Dequeue();
                if (pre.TokenType == Token.PREFIX)
                {
                    IToken ns = context.Tokens.Dequeue();
                    if (ns.TokenType == Token.URI)
                    {
                        //Register a Namespace resolving the Namespace Uri against the Base Uri
                        Uri nsUri = ((IUriNode)ParserHelper.TryResolveUri(context, ns)).Uri;
                        String nsPrefix = (pre.Value.Length > 1) ? pre.Value.Substring(0, pre.Value.Length-1) : String.Empty;
                        context.Namespaces.AddNamespace(nsPrefix, nsUri);
                        if (!context.Handler.HandleNamespace(pre.Value.Substring(0, pre.Value.Length - 1), nsUri)) ParserHelper.Stop();
                    }
                    else
                    {
                        throw ParserHelper.Error("Unexpected Token '" + ns.GetType().ToString() + "' encountered, expected a URI after a Prefix Directive", pre);
                    }
                }
                else
                {
                    throw ParserHelper.Error("Unexpected Token '" + pre.GetType().ToString() + "' encountered, expected a Prefix after a Prefix Directive", pre);
                }
            }
            else if (directive.TokenType == Token.KEYWORDDIRECTIVE)
            {
                //Expect zero/more keywords followed by a dot
                context.KeywordsMode = true;

                IToken next = context.Tokens.Dequeue();
                while (next.TokenType != Token.DOT)
                {
                    //Error if not a Keyword Definition
                    if (next.TokenType != Token.KEYWORDDEF)
                    {
                        throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered when a CustomKeywordDefinitionToken was expected", next);
                    }

                    //Add to Keywords List
                    if (!context.Keywords.Contains(next.Value))
                    {
                        context.Keywords.Add(next.Value);
                    }

                    next = context.Tokens.Dequeue();
                }
                return;
            }
            else
            {
                throw ParserHelper.Error("Unexpected Token '" + directive.GetType().ToString() + "' encountered, expected a Base/Prefix/Keywords Directive after an @ symbol", directive);
            }

            //All declarations are terminated with a Dot
            IToken terminator = context.Tokens.Dequeue();
            if (terminator.TokenType != Token.DOT)
            {
                throw ParserHelper.Error("Unexpected Token '" + terminator.GetType().ToString() + "' encountered, expected a Dot Line Terminator to terminate a Prefix/Base Directive", terminator);
            }
        }
示例#7
0
        /// <summary>
        /// Internal method which does the parsing of the input
        /// </summary>
        /// <param name="context">Parser Context</param>
        private void Parse(Notation3ParserContext context)
        {
            try
            {
                context.Handler.StartRdf();
                //Initialise Buffer and start parsing
                context.Tokens.InitialiseBuffer(10);

                IToken next = context.Tokens.Dequeue();
                if (next.TokenType != Token.BOF)
                {
                    throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a BOF Token", next);
                }

                do
                {
                    next = context.Tokens.Peek();

                    switch (next.TokenType)
                    {
                        case Token.BASEDIRECTIVE:
                        case Token.PREFIXDIRECTIVE:
                        case Token.KEYWORDDIRECTIVE:
                            this.TryParseDirective(context);
                            break;

                        case Token.FORALL:
                            this.TryParseForAll(context);
                            break;

                        case Token.FORSOME:
                            this.TryParseForSome(context);
                            break;

                        case Token.COMMENT:
                            //Discard and ignore
                            context.Tokens.Dequeue();
                            break;

                        case Token.BLANKNODE:
                        case Token.BLANKNODEWITHID:
                        case Token.LEFTBRACKET:
                        case Token.LEFTCURLYBRACKET:
                        case Token.LEFTSQBRACKET:
                        case Token.LITERAL:
                        case Token.LITERALWITHDT:
                        case Token.LITERALWITHLANG:
                        case Token.LONGLITERAL:
                        case Token.PLAINLITERAL:
                        case Token.QNAME:
                        case Token.URI:
                            //Valid Subject of a Triple
                            this.TryParseTriples(context);
                            break;

                        case Token.KEYWORDA:
                            //'a' Keyword only valid as Predicate
                            throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, the 'a' Keyword is only valid as a Predicate in Notation 3", next);

                        case Token.EOF:
                            //OK - the loop will now terminate since we've seen the End of File
                            break;

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

                context.Handler.EndRdf(true);
            }
            catch (RdfParsingTerminatedException)
            {
                context.Handler.EndRdf(true);
                //Discard this - it justs means the Handler told us to stop
            }
            catch
            {
                context.Handler.EndRdf(false);
                throw;
            }
        }
示例#8
0
        /// <summary>
        /// Loads RDF using a RDF handler by reading Notation 3 syntax from the given input
        /// </summary>
        /// <param name="handler">RDF Handler to use</param>
        /// <param name="input">Input to read from</param>
        public void Load(IRdfHandler handler, TextReader input)
        {
            if (handler == null) throw new RdfParseException("Cannot read RDF into a null RDF Handler");
            if (input == null) throw new RdfParseException("Cannot read RDF from a null TextReader");

            try
            {
                Notation3ParserContext context = new Notation3ParserContext(handler, new Notation3Tokeniser(input), this._queueMode, this._traceParsing, this._traceTokeniser);
                this.Parse(context);

                input.Close();
            }
            catch
            {
                try
                {
                    input.Close();
                }
                catch
                {
                    //No catch actions, just trying to clean up
                }
                throw;
            }
        }
示例#9
0
        /// <summary>
        /// Tries to parse Triples
        /// </summary>
        /// <param name="context">Parser Context</param>
        private void TryParseTriples(Notation3ParserContext context)
        {
            IToken subjToken = context.Tokens.Dequeue();
            IToken next;
            INode subj;

            if (context.TraceParsing)
            {
                Console.WriteLine("Attempting to parse Triples from the Subject Token '" + subjToken.GetType().ToString() + "'");
            }

            switch (subjToken.TokenType)
            {
                case Token.BLANKNODE:
                    subj = context.Handler.CreateBlankNode();
                    break;

                case Token.BLANKNODEWITHID:
                    subj = context.Handler.CreateBlankNode(subjToken.Value.Substring(2));
                    break;

                case Token.LEFTBRACKET:
                    //Start of a collection so create a new Blank Node to be it's first subject
                    next = context.Tokens.Peek();
                    if (next.TokenType == Token.RIGHTBRACKET)
                    {
                        //An Empty Collection => rdf:nil
                        context.Tokens.Dequeue();
                        subj = context.Handler.CreateUriNode(UriFactory.Create(NamespaceMapper.RDF + "nil"));
                    }
                    else
                    {
                        subj = context.Handler.CreateBlankNode();
                        this.TryParseCollection(context, subj);
                    }
                    break;

                case Token.LEFTCURLYBRACKET:
                    //Start of a Graph Literal
                    next = context.Tokens.Peek();
                    if (next.TokenType == Token.RIGHTCURLYBRACKET)
                    {
                        //An Empty Graph Literal
                        context.Tokens.Dequeue();
                        subj = context.Handler.CreateGraphLiteralNode();
                    }
                    else
                    {
                        subj = this.TryParseGraphLiteral(context);
                    }
                    break;

                case Token.LEFTSQBRACKET:
                    //Start of a Blank Node collection?
                    next = context.Tokens.Peek();
                    if (next.TokenType == Token.RIGHTSQBRACKET)
                    {
                        //An anoynmous Blank Node
                        context.Tokens.Dequeue();
                        subj = context.Handler.CreateBlankNode();
                    }
                    else
                    {
                        //Start of a Blank Node Collection
                        subj = context.Handler.CreateBlankNode();
                        this.TryParsePredicateObjectList(context, subj, true);
                    }
                    break;

                case Token.LITERAL:
                case Token.LITERALWITHDT:
                case Token.LITERALWITHLANG:
                case Token.LONGLITERAL:
                case Token.PLAINLITERAL:
                    //Literal Subjects valid in N3
                    subj = this.TryParseLiteral(context, subjToken);
                    break;

                case Token.QNAME:
                case Token.URI:
                    subj = ParserHelper.TryResolveUri(context, subjToken);
                    break;

                case Token.VARIABLE:
                    subj = context.Handler.CreateVariableNode(subjToken.Value.Substring(1));
                    break;

                default:
                    throw ParserHelper.Error("Unexpected Token '" + subjToken.GetType().ToString() + "' encountered, this Token is not valid as the subject of a Triple", subjToken);
            }

            if (context.Tokens.LastTokenType == Token.RIGHTSQBRACKET || context.Tokens.LastTokenType == Token.RIGHTCURLYBRACKET)
            {
                //Allowed to state a Blank Node collection or a Graph Literal on it's own in N3
                next = context.Tokens.Peek();
                if (next.TokenType == Token.DOT)
                {
                    context.Tokens.Dequeue();
                    return;
                }
            }

            this.TryParsePredicateObjectList(context, subj, false);
        }
示例#10
0
        /// <summary>
        /// Tries to parse Predicate Object lists
        /// </summary>
        /// <param name="context">Parse Context</param>
        /// <param name="subj">Subject of the Triples</param>
        /// <param name="bnodeList">Whether this is a Blank Node Predicate Object list</param>
        private void TryParsePredicateObjectList(Notation3ParserContext context, INode subj, bool bnodeList)
        {
            IToken predToken, next;
            INode pred = null;
            bool reverse = false;

            do
            {
                predToken =  context.Tokens.Dequeue();

                if (context.TraceParsing)
                {
                    Console.WriteLine("Attempting to parse Predicate Object List from the Predicate Token '" + predToken.GetType().ToString() + "'");
                }

                switch (predToken.TokenType)
                {
                    case Token.BLANKNODE:
                        pred = context.Handler.CreateBlankNode();
                        break;

                    case Token.BLANKNODEWITHID:
                        pred = context.Handler.CreateBlankNode(predToken.Value.Substring(2));
                        break;

                    case Token.COMMENT:
                        //Discard and continue
                        continue;

                    case Token.EQUALS:
                        //= Keyword
                        pred = context.Handler.CreateUriNode(UriFactory.Create(SameAsUri));
                        break;

                    case Token.EXCLAMATION:
                    case Token.HAT:
                        //Path
                        subj = this.TryParsePath(context, subj);
                        this.TryParsePredicateObjectList(context, subj, bnodeList);
                        return;

                    case Token.IMPLIEDBY:
                        //<= keyword
                        pred = context.Handler.CreateUriNode(UriFactory.Create(ImpliesUri));
                        reverse = true;
                        break;

                    case Token.IMPLIES:
                        //=> keyword
                        pred = context.Handler.CreateUriNode(UriFactory.Create(ImpliesUri));
                        break;

                    case Token.KEYWORDA:
                        //'a' Keyword
                        pred = context.Handler.CreateUriNode(UriFactory.Create(NamespaceMapper.RDF + "type"));
                        break;

                    case Token.LEFTBRACKET:
                        //Start of a collection so create a new Blank Node to be it's first subject
                        next = context.Tokens.Peek();
                        if (next.TokenType == Token.RIGHTBRACKET)
                        {
                            //An Empty Collection => rdf:nil
                            context.Tokens.Dequeue();
                            pred = context.Handler.CreateUriNode(UriFactory.Create(NamespaceMapper.RDF + "nil"));
                        }
                        else
                        {
                            pred = context.Handler.CreateBlankNode();
                            this.TryParseCollection(context, pred);
                        }
                        break;

                    case Token.LEFTCURLYBRACKET:
                        //Graph Literals not allowed as Predicates
                        throw ParserHelper.Error("Unexpected Left Curly Bracket encountered, Graph Literals are not valid as Predicates in Notation 3", predToken);

                    case Token.LEFTSQBRACKET:
                        //Start of a Blank Node collection?
                        next = context.Tokens.Peek();
                        if (next.TokenType == Token.RIGHTSQBRACKET)
                        {
                            //An anoynmous Blank Node
                            context.Tokens.Dequeue();
                            pred = context.Handler.CreateBlankNode();
                        }
                        else
                        {
                            //Start of a Blank Node Collection
                            pred = context.Handler.CreateBlankNode();
                            this.TryParsePredicateObjectList(context, pred, true);
                        }
                        break;

                    case Token.RIGHTCURLYBRACKET:
                        if (context.GraphLiteralMode)
                        {
                            return;
                        }
                        else
                        {
                            throw ParserHelper.Error("Unexpected Right Curly Bracket encountered but not expecting the end of a Graph Literal", predToken);
                        }

                    case Token.RIGHTSQBRACKET:
                        //If the last token was a semicolon and we're parsing a Blank Node Predicate Object list
                        //then a trailing semicolon is permitted
                        if (bnodeList)
                        {
                            if (context.Tokens.LastTokenType == Token.SEMICOLON)
                            {
                                return;
                            }
                            else
                            {
                                //If Predicate is not null then we've seen at least one valid Triple and this is just the end of the Blank Node Predicate Object list
                                if (pred != null)
                                {
                                    return;
                                }
                                else
                                {
                                    throw ParserHelper.Error("Unexpected Right Square Bracket encountered while trying to parse a Blank Node Predicate Object list, expected a valid Predicate", predToken);
                                }
                            }
                        }
                        else
                        {
                            throw ParserHelper.Error("Unexpected Right Square Bracket encountered while trying to parse a Predicate Object list", predToken);
                        }

                    case Token.QNAME:
                    case Token.URI:
                        pred = ParserHelper.TryResolveUri(context, predToken);
                        break;

                    case Token.VARIABLE:
                        pred = context.Handler.CreateVariableNode(predToken.Value.Substring(1));
                        break;

                    case Token.EOF:
                        throw ParserHelper.Error("Unexpected end of file while trying to parse a Predicate Object list", predToken);

                    default:
                        throw ParserHelper.Error("Unexpected Token '" + predToken.GetType().ToString() + "' encountered while trying to parse a Predicate Object list", predToken);

                }

                this.TryParseObjectList(context, subj, pred, bnodeList, reverse);
                if (context.Tokens.LastTokenType == Token.DOT && !bnodeList) return; //Dot terminates a normal Predicate Object list
                if (context.Tokens.LastTokenType == Token.RIGHTSQBRACKET && bnodeList) return; //Trailing semicolon may terminate a Blank Node Predicate Object list
                if (context.Tokens.LastTokenType == Token.SEMICOLON && context.Tokens.Peek().TokenType == Token.DOT)
                {
                    //Dot terminates a Predicate Object list with a trailing semicolon
                    context.Tokens.Dequeue();
                    return;
                }
                if (context.Tokens.LastTokenType == Token.RIGHTCURLYBRACKET && context.GraphLiteralMode) return; //Right Curly Bracket terminates a Graph Literal
            } while (true);
        }
示例#11
0
        private INode TryParsePath(Notation3ParserContext context, INode firstItem)
        {
            IToken next;
            INode secondItem;
            bool forward = (context.Tokens.LastTokenType == Token.EXCLAMATION);

            //Actual path is represented by a new Blank Node
            INode path = context.Handler.CreateBlankNode();
            INode pathHead = path;

            do
            {
                //Get next thing which should be a Path Item
                next = context.Tokens.Dequeue();
                switch (next.TokenType)
                {
                    case Token.QNAME:
                        secondItem = context.Handler.CreateUriNode(UriFactory.Create(Tools.ResolveQName(next.Value, context.Namespaces, context.BaseUri)));
                        break;
                    case Token.LITERAL:
                    case Token.LONGLITERAL:
                    case Token.LITERALWITHDT:
                    case Token.LITERALWITHLANG:
                        secondItem = this.TryParseLiteral(context, next);
                        break;
                    case Token.URI:
                        secondItem = context.Handler.CreateUriNode(UriFactory.Create(Tools.ResolveUri(next.Value, context.BaseUri.ToSafeString())));
                        break;

                    default:
                        throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, only Literals, QNames and URIs are valid as Path Items", next);
                }

                if (forward)
                {
                    if (!context.Handler.HandleTriple(new Triple(firstItem, secondItem, path, context.VariableContext))) ParserHelper.Stop();
                }
                else
                {
                    if (!context.Handler.HandleTriple(new Triple(path, secondItem, firstItem, context.VariableContext))) ParserHelper.Stop();
                }

                //Does the Path continue?
                next = context.Tokens.Peek();
                if (next.TokenType == Token.EXCLAMATION || next.TokenType == Token.HAT)
                {
                    context.Tokens.Dequeue();
                    firstItem = path;
                    path = context.Handler.CreateBlankNode();
                    forward = (context.Tokens.LastTokenType == Token.EXCLAMATION);
                }
                else
                {
                    return pathHead;
                }
            } while (true);
        }