예제 #1
0
        private void TryParseBindAssignment(SparqlQueryParserContext context, GraphPattern p)
        {
            if (context.SyntaxMode == SparqlQuerySyntax.Sparql_1_0) throw new RdfParseException("BIND assignment is not supported in SPARQL 1.0");

            //First need to discard opening (
            IToken next = context.Tokens.Dequeue();
            if (next.TokenType != Token.LEFTBRACKET) throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a ( to start a BIND assignment after a BIND keyword", next);

            //Expect a bracketted expression terminated by an AS
            ISparqlExpression expr = this.TryParseExpression(context, false, true);
            if (context.Tokens.LastTokenType != Token.AS)
            {
                throw ParserHelper.Error("A BIND assignment did not end with an AS ?var as expected, BIND assignment must be of the general form BIND(expr AS ?var)", next);
            }

            //Ensure there is a Variable after the AS
            next = context.Tokens.Dequeue();
            if (next.TokenType == Token.VARIABLE)
            {
                BindPattern bind = new BindPattern(next.Value.Substring(1), expr);

                //Check that the Variable has not already been used
                if (context.Query.RootGraphPattern != null && context.Query.RootGraphPattern.Variables.Contains(bind.VariableName))
                {
                    throw ParserHelper.Error("A BIND assignment is attempting to bind to the variable ?" + bind.VariableName + " but this variable is already in use in the query", next);
                }
                else if (p.Variables.Contains(bind.VariableName))
                {
                    throw ParserHelper.Error("A BIND assignment is attempting to bind to the variable ?" + bind.VariableName + " but this variable is already in use earlier in the Graph pattern", next);
                }

                if (Options.QueryOptimisation)
                {
                    p.AddAssignment(bind);
                }
                else
                {
                    //When Optimisation is turned off we'll just stick the BIND in the Triples Pattern where it occurs
                    //since we're not going to do any Triple Pattern ordering, Assignment or FILTER placement
                    p.AddTriplePattern(bind);
                    //In this case the BIND must break the BGP since using AddTriplePattern will not do it automatically
                    p.BreakBGP();
                }

                //Ensure the BIND assignment is terminated with a )
                next = context.Tokens.Dequeue();
                if (next.TokenType != Token.RIGHTBRACKET) throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a ) to terminate a BIND assignment", next);
            }
            else
            {
                throw ParserHelper.Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, expected a Variable after the AS in a BIND assignment", next);
            }
        }