Ejemplo n.º 1
0
        private ISparqlExpression TryParseNumericLiteral(IToken literal, Queue<IToken> tokens)
        {
            switch (literal.TokenType)
            {
                case Token.PLAINLITERAL:
                    //Use Regular Expressions to see what type it is
                    if (SparqlSpecsHelper.IsInteger(literal.Value))
                    {
                        return new NumericExpressionTerm(Int32.Parse(literal.Value));
                    }
                    else if (SparqlSpecsHelper.IsDecimal(literal.Value))
                    {
                        return new NumericExpressionTerm(Decimal.Parse(literal.Value));
                    }
                    else if (SparqlSpecsHelper.IsDouble(literal.Value))
                    {
                        return new NumericExpressionTerm(Double.Parse(literal.Value));
                    }
                    else
                    {
                        throw Error("The Plain Literal '" + literal.Value + "' is not a valid Integer, Decimal or Double", literal);
                    }
                    
                case Token.LITERALWITHDT:
                    //Get the Data Type Uri
                    String dt = ((LiteralWithDataTypeToken)literal).DataType;
                    String dtUri;
                    if (dt.StartsWith("<"))
                    {
                        String baseUri = (this._baseUri == null) ? String.Empty : this._baseUri.ToString();
                        dtUri = Tools.ResolveUri(dt.Substring(1, dt.Length - 2), baseUri);
                    }
                    else
                    {
                        dtUri = Tools.ResolveQName(dt, this._nsmapper, this._baseUri);
                    }

                    //Return a Numeric Expression Term if it's an Integer/Decimal/Double
                    if (XmlSpecsHelper.XmlSchemaDataTypeInteger.Equals(dtUri) && SparqlSpecsHelper.IsInteger(literal.Value))
                    {
                        return new NumericExpressionTerm(Int32.Parse(literal.Value));
                    }
                    else if (XmlSpecsHelper.XmlSchemaDataTypeDecimal.Equals(dtUri) && SparqlSpecsHelper.IsDecimal(literal.Value))
                    {
                        return new NumericExpressionTerm(Decimal.Parse(literal.Value));
                    }
                    else if (XmlSpecsHelper.XmlSchemaDataTypeFloat.Equals(dtUri) && SparqlSpecsHelper.IsFloat(literal.Value))
                    {
                        return new NumericExpressionTerm(Single.Parse(literal.Value));
                    }
                    else if (XmlSpecsHelper.XmlSchemaDataTypeDouble.Equals(dtUri) && SparqlSpecsHelper.IsDouble(literal.Value))
                    {
                        return new NumericExpressionTerm(Double.Parse(literal.Value));
                    }
                    else
                    {
                        throw Error("The Literal '" + literal.Value + "' with Datatype URI '" + dtUri + "' is not a valid Integer, Decimal or Double", literal);
                    }
                    
                case Token.LITERAL:
                    //Check if there's a Datatype following the Literal
                    if (tokens.Count > 0)
                    {
                        IToken next = tokens.Peek();
                        if (next.TokenType == Token.HATHAT)
                        {
                            tokens.Dequeue();
                            //Should now see a DataTypeToken
                            DataTypeToken datatype = (DataTypeToken)tokens.Dequeue();
                            LiteralWithDataTypeToken dtlit = new LiteralWithDataTypeToken(literal, datatype);

                            //Self-recurse to save replicating code
                            return this.TryParseNumericLiteral(dtlit, tokens);
                        }
                        else
                        {
                            //Use Regex to see if it's a Integer/Decimal/Double
                            if (SparqlSpecsHelper.IsInteger(literal.Value))
                            {
                                return new NumericExpressionTerm(Int32.Parse(literal.Value));
                            }
                            else if (SparqlSpecsHelper.IsDecimal(literal.Value))
                            {
                                return new NumericExpressionTerm(Decimal.Parse(literal.Value));
                            }
                            else if (SparqlSpecsHelper.IsDouble(literal.Value))
                            {
                                return new NumericExpressionTerm(Double.Parse(literal.Value));
                            }
                            else
                            {
                                //Otherwise treat as a Node Expression
                                throw Error("The Literal '" + literal.Value + "' is not a valid Integer, Decimal or Double", literal);
                            }
                        }
                    }
                    else
                    {
                        //Use Regular Expressions to see what type it is
                        if (SparqlSpecsHelper.IsInteger(literal.Value))
                        {
                            return new NumericExpressionTerm(Int32.Parse(literal.Value));
                        }
                        else if (SparqlSpecsHelper.IsDecimal(literal.Value))
                        {
                            return new NumericExpressionTerm(Decimal.Parse(literal.Value));
                        }
                        else if (SparqlSpecsHelper.IsDouble(literal.Value))
                        {
                            return new NumericExpressionTerm(Double.Parse(literal.Value));
                        }
                        else
                        {
                            throw Error("The Literal '" + literal.Value + "' is not a valid Integer, Decimal or Double", literal);
                        }
                    }

                default:
                    throw Error("Unexpected Token '" + literal.GetType().ToString() + "' encountered while trying to parse a Numeric Literal", literal);
            }
        }
Ejemplo n.º 2
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;
        }
Ejemplo n.º 3
0
        private ISparqlExpression TryParseRdfLiteral(Queue<IToken> tokens)
        {
            //First Token will be the String value of this RDF Literal
            IToken str = tokens.Dequeue();

            //Might have a Language Specifier/DataType afterwards
            if (tokens.Count > 0)
            {
                IToken next = tokens.Peek();
                if (next.TokenType == Token.LANGSPEC)
                {
                    tokens.Dequeue();
                    return new NodeExpressionTerm(new LiteralNode(null, str.Value, next.Value));
                }
                else if (next.TokenType == Token.HATHAT)
                {
                    tokens.Dequeue();

                    //Should be a DataTypeToken afterwards
                    next = tokens.Dequeue();
                    LiteralWithDataTypeToken dtlit = new LiteralWithDataTypeToken(str, (DataTypeToken)next); ;
                    Uri u;

                    if (next.Value.StartsWith("<"))
                    {
                        u = new Uri(next.Value.Substring(1, next.Value.Length - 2));
                    }
                    else
                    {
                        //Resolve the QName
                        u = new Uri(Tools.ResolveQName(next.Value, this._nsmapper, this._baseUri));
                    }

                    if (SparqlSpecsHelper.GetNumericTypeFromDataTypeUri(u) != SparqlNumericType.NaN)
                    {
                        //Should be a Number
                        return this.TryParseNumericLiteral(dtlit, tokens);
                    }
                    else if (XmlSpecsHelper.XmlSchemaDataTypeBoolean.Equals(u.ToString()))
                    {
                        //Appears to be a Boolean
                        return new BooleanExpressionTerm(Boolean.Parse(dtlit.Value));
                    }
                    else
                    {
                        //Just a datatyped Literal Node
                        return new NodeExpressionTerm(new LiteralNode(null, str.Value, u));
                    }
                }
                else
                {
                    return new NodeExpressionTerm(new LiteralNode(null, str.Value));
                }
            }
            else
            {
                return new NodeExpressionTerm(new LiteralNode(null, str.Value));
            }

        }
Ejemplo n.º 4
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);
            }
        }