예제 #1
0
        public Triple GetNextTriple()
        {
            if (this._eof) throw new RdfParseException("Cannot continue parsing when the End of File has already been reached");

            IToken next;
            IToken s, p, o;
            Triple t;

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

            //Parse Subject
            next = this._tokens.Dequeue();
            switch (next.TokenType)
            {
                case Token.BLANKNODEWITHID:
                case Token.URI:
                    //OK
                    s = next;
                    break;
                default:
                    throw Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a Blank Node/URI as the Subject of a Triple", next);
            }

            //Parse Predicate
            next = this._tokens.Dequeue();
            switch (next.TokenType)
            {
                case Token.URI:
                    //OK
                    p = next;
                    break;
                default:
                    throw Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a URI as the Predicate of a Triple", next);
            }

            //Parse Object
            next = this._tokens.Dequeue();
            switch (next.TokenType)
            {
                case Token.BLANKNODEWITHID:
                case Token.LITERALWITHDT:
                case Token.LITERALWITHLANG:
                case Token.URI:
                    //OK
                    o = next;
                    break;
                case Token.LITERAL:
                    //Check for Datatype/Language
                    IToken temp = this._tokens.Peek();
                    if (temp.TokenType == Token.DATATYPE)
                    {
                        this._tokens.Dequeue();
                        o = new LiteralWithDataTypeToken(next, (DataTypeToken)temp);
                    }
                    else if (temp.TokenType == Token.LANGSPEC)
                    {
                        this._tokens.Dequeue();
                        o = new LiteralWithLanguageSpecifierToken(next, (LanguageSpecifierToken)temp);
                    }
                    else
                    {
                        o = next;
                    }
                    break;
                default:
                    throw Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a Blank Node/Literal/URI as the Object of a Triple", next);
            }

            next = this._tokens.Dequeue();
            if (next.TokenType == Token.DOT)
            {
                //Terminates a Triple and there is no Context given for the Triple so this
                //Triple is in the Default Graph
                IGraph def = this._factory[null];
                t = this.CreateTriple(s, p, o, def);
            }
            else
            {
                //Parse Context
                INode context;
                switch (next.TokenType)
                {
                    case Token.BLANKNODEWITHID:
                        context = this._g.CreateBlankNode(next.Value.Substring(2));
                        break;
                    case Token.URI:
                        context = this._g.CreateUriNode(new Uri(next.Value));
                        break;
                    case Token.LITERAL:
                        //Check for Datatype/Language
                        IToken temp = this._tokens.Peek();
                        if (temp.TokenType == Token.LANGSPEC)
                        {
                            this._tokens.Dequeue();
                            context = this._g.CreateLiteralNode(next.Value, temp.Value);
                        }
                        else if (temp.TokenType == Token.DATATYPE)
                        {
                            this._tokens.Dequeue();
                            context = this._g.CreateLiteralNode(next.Value, new Uri(temp.Value.Substring(1, temp.Value.Length - 2)));
                        }
                        else
                        {
                            context = this._g.CreateLiteralNode(next.Value);
                        }
                        break;
                    default:
                        throw Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a Blank Node/Literal/URI as the Context of the Triple", next);
                }

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

                IGraph g = this._factory[contextUri];
                t = this.CreateTriple(s, p, o, g);

                next = this._tokens.Dequeue();
                while (next.TokenType == Token.COMMENT)
                {
                    next = this._tokens.Dequeue();
                }
                if (next.TokenType != Token.DOT)
                {
                    throw Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a Dot Token (Line Terminator) to terminate a Triple", next);
                }
            }

            //Check for EOF
            next = this._tokens.Peek();
            if (next.TokenType == Token.EOF)
            {
                this._tokens.Dequeue();
                this._eof = true;
            }

            return t;
        }
예제 #2
0
        private void TryParseBindingsClause(SparqlQueryParserContext context)
        {
            //First expect one/more variables
            IToken next = context.Tokens.Peek();
            List<String> vars = new List<String>();
            while (next.TokenType == Token.VARIABLE)
            {
                vars.Add(next.Value.Substring(1));
                context.Tokens.Dequeue();
                next = context.Tokens.Peek();
            }
            if (vars.Count == 0)
            {
                //If No Variables then expect an empty BINDINGS { }
                next = context.Tokens.Peek();
                if (next.TokenType != Token.LEFTCURLYBRACKET)
                {
                    throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected either one/more Variable Tokens or the empty set { } after a BINDINGS keyword", next);
                }
            }

            //Then expect a Left Curly Bracket
            if (next.TokenType == Token.LEFTCURLYBRACKET)
            {
                context.Tokens.Dequeue();
                BindingsPattern bindings = new BindingsPattern(vars);

                //Each Binding tuple must start with a (
                next = context.Tokens.Peek();
                while (next.TokenType == Token.LEFTBRACKET)
                {
                    //Discard the ( and peek the next token
                    context.Tokens.Dequeue();
                    next = context.Tokens.Peek();

                    //Expect a sequence of values in the tuple
                    List<PatternItem> values = new List<PatternItem>();
                    while (next.TokenType != Token.RIGHTBRACKET)
                    {
                        next = context.Tokens.Dequeue();

                        //Get the value
                        switch (next.TokenType)
                        {
                            case Token.URI:
                            case Token.QNAME:
                            case Token.LITERALWITHDT:
                            case Token.LITERALWITHLANG:
                            case Token.PLAINLITERAL:
                                values.Add(this.TryCreatePatternItem(context, next));
                                break;

                            case Token.LONGLITERAL:
                            case Token.LITERAL:
                                //Need to check for subsequent datatype or language declaration
                                IToken lit = next;
                                next = context.Tokens.Peek();
                                if (next.TokenType == Token.HATHAT)
                                {
                                    context.Tokens.Dequeue();
                                    next = context.Tokens.Dequeue();
                                    if (next.TokenType == Token.DATATYPE)
                                    {
                                        LiteralWithDataTypeToken dtlit = new LiteralWithDataTypeToken(lit, (DataTypeToken)next);
                                        values.Add(this.TryCreatePatternItem(context, dtlit));
                                    }
                                    else
                                    {
                                        throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a Datatype Token to specify the datatype for a Literal", next);
                                    }
                                }
                                else if (next.TokenType == Token.LANGSPEC)
                                {
                                    context.Tokens.Dequeue();
                                    LiteralWithLanguageSpecifierToken langlit = new LiteralWithLanguageSpecifierToken(lit, (LanguageSpecifierToken)next);
                                    values.Add(this.TryCreatePatternItem(context, langlit));
                                }
                                else
                                {
                                    values.Add(this.TryCreatePatternItem(context, lit));
                                }
                                break;

                            case Token.UNDEF:
                                //UNDEF indicates an unbound variable which equates to a null
                                values.Add(null);
                                break;

                            default:
                                throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a Token for a URI/Literal or an UNDEF keyword as part of a tuple in a BINDINGS clause", next);
                        }

                        next = context.Tokens.Peek();
                    }

                    if (vars.Count != values.Count)
                    {
                        throw new RdfParseException("Invalid tuple in the BINDINGS clause, each Binding should contain " + vars.Count + " values but got a tuple containing " + values.Count + " values");
                    }

                    //Generate a representation of this possible solution and add it to our Bindings object
                    bindings.AddTuple(new BindingTuple(vars, values));

                    //Discard the ) and peek the next token
                    context.Tokens.Dequeue();
                    next = context.Tokens.Peek();
                }

                //Set the Query's BINDINGS clause
                context.Query.Bindings = bindings;

                //Finally we need to see a Right Curly Bracket
                if (next.TokenType != Token.RIGHTCURLYBRACKET)
                {
                    throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a Right Curly Bracket to terminate the BINDINGS clause", next);
                }
                context.Tokens.Dequeue();
            }
            else
            {
                throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a Left Curly Bracket after the list of variables as part of a BINDINGS clause", next);
            }
        }