Пример #1
0
        private ISparqlExpression TryParseBuiltInCall(Queue<IToken> tokens)
        {
            IToken next = tokens.Dequeue();
            bool comma = false, first = true;
            List<ISparqlExpression> args;
            ISparqlExpression strExpr;

            switch (next.TokenType)
            {
                case Token.ABS:
                    return new AbsFunction(this.TryParseBrackettedExpression(tokens));
                case Token.BNODE:
                    return new BNodeFunction(this.TryParseBrackettedExpression(tokens));                

                case Token.BOUND:
                    //Expect a Left Bracket, Variable and then a Right Bracket
                    next = tokens.Dequeue();
                    if (next.TokenType == Token.LEFTBRACKET)
                    {
                        next = tokens.Dequeue();
                        if (next.TokenType == Token.VARIABLE)
                        {
                            VariableExpressionTerm varExpr = new VariableExpressionTerm(next.Value);
                            next = tokens.Dequeue();
                            if (next.TokenType == Token.RIGHTBRACKET)
                            {
                                return new BoundFunction(varExpr);
                            }
                            else
                            {
                                throw Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, a Right Bracket to end a BOUND function call was expected",next);
                            }
                        }
                        else
                        {
                            throw Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, a Variable Token for a BOUND function call was expected", next);
                        }
                    }
                    else
                    {
                        throw Error("Unexpected Token '" + next.GetType().ToString() + "' encountered, a Left Bracket to start a BOUND function call was expected", next);
                    }

                case Token.CEIL:
                    return new CeilFunction(this.TryParseBrackettedExpression(tokens));

                case Token.COALESCE:
                    //Get as many argument expressions as we can
                    args = new List<ISparqlExpression>();
                    do
                    {
                        args.Add(this.TryParseBrackettedExpression(tokens, first, out comma));
                        first = false;
                    } while (comma);

                    return new CoalesceFunction(args);

                case Token.CONCAT:
                    //Get as many argument expressions as we can
                    args = new List<ISparqlExpression>();
                    do
                    {
                        args.Add(this.TryParseBrackettedExpression(tokens, first, out comma));
                        first = false;
                    } while (comma);

                    return new ConcatFunction(args);

                case Token.CONTAINS:
                    return new ContainsFunction(this.TryParseBrackettedExpression(tokens), this.TryParseBrackettedExpression(tokens, false));
                case Token.DATATYPEFUNC:
                    return new DataTypeFunction(this.TryParseBrackettedExpression(tokens));
                case Token.DAY:
                    return new DayFunction(this.TryParseBrackettedExpression(tokens));
                case Token.ENCODEFORURI:
                    return new EncodeForUriFunction(this.TryParseBrackettedExpression(tokens));
                case Token.FLOOR:
                    return new FloorFunction(this.TryParseBrackettedExpression(tokens));
                case Token.HOURS:
                    return new HoursFunction(this.TryParseBrackettedExpression(tokens));
                case Token.IF:
                    return new IfElseFunction(this.TryParseBrackettedExpression(tokens, true, out comma), this.TryParseBrackettedExpression(tokens, false, out comma), this.TryParseBrackettedExpression(tokens, false, out comma));
                case Token.IRI:
                case Token.URIFUNC:
                    return new IriFunction(this.TryParseBrackettedExpression(tokens));
                case Token.ISBLANK:
                    return new IsBlankFunction(this.TryParseBrackettedExpression(tokens));
                case Token.ISIRI:
                    return new IsIriFunction(this.TryParseBrackettedExpression(tokens));
                case Token.ISLITERAL:
                    return new IsLiteralFunction(this.TryParseBrackettedExpression(tokens));
                case Token.ISNUMERIC:
                    return new IsNumericFunction(this.TryParseBrackettedExpression(tokens));
                case Token.ISURI:
                    return new IsUriFunction(this.TryParseBrackettedExpression(tokens));
                case Token.LANG:
                    return new LangFunction(this.TryParseBrackettedExpression(tokens));
                case Token.LANGMATCHES:
                    return new LangMatchesFunction(this.TryParseBrackettedExpression(tokens), this.TryParseBrackettedExpression(tokens, false));
                case Token.LCASE:
                    return new LCaseFunction(this.TryParseBrackettedExpression(tokens));
                case Token.MD5:
                    return new MD5HashFunction(this.TryParseBrackettedExpression(tokens));
                case Token.MINUTES:
                    return new MinutesFunction(this.TryParseBrackettedExpression(tokens));
                case Token.MONTH:
                    return new MonthFunction(this.TryParseBrackettedExpression(tokens));

                case Token.NOW:
                    //Expect a () after the Keyword Token
                    next = tokens.Dequeue();
                    if (next.TokenType != Token.LEFTBRACKET) throw Error("Expected a Left Bracket after a NOW keyword to call the NOW() function", next);
                    next = tokens.Dequeue();
                    if (next.TokenType != Token.RIGHTBRACKET) throw Error("Expected a Right Bracket after NOW( since the NOW() function does not take any arguments", next);
                    return new NowFunction();

                case Token.RAND:
                    //Expect a () after the Keyword Token
                    next = tokens.Dequeue();
                    if (next.TokenType != Token.LEFTBRACKET) throw Error("Expected a Left Bracket after a RAND keyword to call the RAND() function", next);
                    next = tokens.Dequeue();
                    if (next.TokenType != Token.RIGHTBRACKET) throw Error("Expected a Right Bracket after RAND( since the RAND() function does not take any arguments", next);
                    return new RandFunction();

                case Token.REGEX:
                    return this.TryParseRegexExpression(tokens);
                case Token.REPLACE:
                    //REPLACE may have 3/4 arguments
                    strExpr = this.TryParseBrackettedExpression(tokens);
                    ISparqlExpression patternExpr = this.TryParseBrackettedExpression(tokens, false);
                    ISparqlExpression replaceExpr = this.TryParseBrackettedExpression(tokens, false, out comma);
                    if (comma)
                    {
                        ISparqlExpression opsExpr = this.TryParseBrackettedExpression(tokens, false);
                        return new ReplaceFunction(strExpr, patternExpr, replaceExpr, opsExpr);
                    }
                    else
                    {
                        return new ReplaceFunction(strExpr, patternExpr, replaceExpr);
                    }
                case Token.ROUND:
                    return new RoundFunction(this.TryParseBrackettedExpression(tokens));
                case Token.SAMETERM:
                    return new SameTermFunction(this.TryParseBrackettedExpression(tokens), this.TryParseBrackettedExpression(tokens, false));
                case Token.SECONDS:
                    return new SecondsFunction(this.TryParseBrackettedExpression(tokens));
                case Token.SHA1:
                    return new Sha1HashFunction(this.TryParseBrackettedExpression(tokens));
                case Token.SHA224:
                    return new Sha224HashFunction(this.TryParseBrackettedExpression(tokens));
                case Token.SHA256:
                    return new Sha256HashFunction(this.TryParseBrackettedExpression(tokens));
                case Token.SHA384:
                    return new Sha384HashFunction(this.TryParseBrackettedExpression(tokens));
                case Token.SHA512:
                    return new Sha512HashFunction(this.TryParseBrackettedExpression(tokens));
                case Token.STR:
                    return new StrFunction(this.TryParseBrackettedExpression(tokens));
                case Token.STRAFTER:
                    return new StrAfterFunction(this.TryParseBrackettedExpression(tokens), this.TryParseBrackettedExpression(tokens, false));
                case Token.STRBEFORE:
                    return new StrBeforeFunction(this.TryParseBrackettedExpression(tokens), this.TryParseBrackettedExpression(tokens, false));
                case Token.STRDT:
                    return new StrDtFunction(this.TryParseBrackettedExpression(tokens), this.TryParseBrackettedExpression(tokens, false));
                case Token.STRENDS:
                    return new StrEndsFunction(this.TryParseBrackettedExpression(tokens), this.TryParseBrackettedExpression(tokens, false));
                case Token.STRLANG:
                    return new StrLangFunction(this.TryParseBrackettedExpression(tokens), this.TryParseBrackettedExpression(tokens, false));
                case Token.STRLEN:
                    return new StrLenFunction(this.TryParseBrackettedExpression(tokens));
                case Token.STRSTARTS:
                    return new StrStartsFunction(this.TryParseBrackettedExpression(tokens), this.TryParseBrackettedExpression(tokens, false));

                case Token.SUBSTR:
                    //SUBSTR may have 2/3 arguments
                    strExpr = this.TryParseBrackettedExpression(tokens);
                    ISparqlExpression startExpr = this.TryParseBrackettedExpression(tokens, false, out comma);
                    if (comma)
                    {
                        ISparqlExpression lengthExpr = this.TryParseBrackettedExpression(tokens, false);
                        return new SubStrFunction(strExpr, startExpr, lengthExpr);
                    }
                    else
                    {
                        return new SubStrFunction(strExpr, startExpr);
                    }

                case Token.TIMEZONE:
                    return new TimezoneFunction(this.TryParseBrackettedExpression(tokens));
                case Token.TZ:
                    return new TZFunction(this.TryParseBrackettedExpression(tokens));
                case Token.UCASE:
                    return new UCaseFunction(this.TryParseBrackettedExpression(tokens));
                case Token.YEAR:
                    return new YearFunction(this.TryParseBrackettedExpression(tokens));

                case Token.EXISTS:
                case Token.NOTEXISTS:
                    if (this._syntax == SparqlQuerySyntax.Sparql_1_0) throw new RdfParseException("EXISTS/NOT EXISTS clauses are not supported in SPARQL 1.0");
                    if (this._parser == null) throw new RdfParseException("Unable to parse an EXISTS/NOT EXISTS as there is no Query Parser to call into");

                    //Gather Tokens for the Pattern
                    NonTokenisedTokenQueue temptokens = new NonTokenisedTokenQueue();
                    int openbrackets = 0;
                    bool mustExist = (next.TokenType == Token.EXISTS);
                    do
                    {
                        if (tokens.Count == 0) throw new RdfParseException("Unexpected end of Tokens while trying to parse an EXISTS/NOT EXISTS function");

                        next = tokens.Dequeue();
                        if (next.TokenType == Token.LEFTCURLYBRACKET)
                        {
                            openbrackets++;
                        }
                        else if (next.TokenType == Token.RIGHTCURLYBRACKET)
                        {
                            openbrackets--;
                        }
                        temptokens.Enqueue(next);
                    } while (openbrackets > 0);

                    //Call back into the Query Parser to try and Parse the Graph Pattern for the Function
                    SparqlQueryParserContext tempcontext = new SparqlQueryParserContext(temptokens);
                    tempcontext.Query.NamespaceMap.Import(this._nsmapper);
                    tempcontext.Query.BaseUri = this._baseUri;
                    return new ExistsFunction(this._parser.TryParseGraphPattern(tempcontext, true), mustExist);

                default:
                    throw Error("Unexpected Token '" + next.GetType().ToString() + "' encountered while trying to parse a Built-in Function call", next);
            }
        }
Пример #2
0
        private void TryParseSubquery(SparqlQueryParserContext context, GraphPattern p)
        {
            if (context.SyntaxMode == SparqlQuerySyntax.Sparql_1_0) throw new RdfParseException("Sub-queries are not supported in SPARQL 1.0");

            //We're going to make a temporary Token Queue which we will populate and then
            //use to create a new SPARQL Query Parser Context
            NonTokenisedTokenQueue tokens = new NonTokenisedTokenQueue();

            //Assume we've already seen a SELECT
            tokens.Enqueue(new BOFToken());
            tokens.Enqueue(new SelectKeywordToken(1, 1));

            //Now collect Tokens until we hit the closing Right Bracket
            int openBrackets = 1;
            IToken next;
            do
            {
                next = context.Tokens.Peek();

                if (next.TokenType == Token.LEFTCURLYBRACKET)
                {
                    openBrackets++;
                }
                else if (next.TokenType == Token.RIGHTCURLYBRACKET)
                {
                    openBrackets--;
                }
                else if (next.TokenType == Token.EOF)
                {
                    throw ParserHelper.Error("Unexpected End of File encountered while trying to gather Tokens to parse a Sub-Query from", next);
                }

                if (openBrackets > 0)
                {
                    tokens.Enqueue(context.Tokens.Dequeue());
                }
            } while (openBrackets > 0);

            tokens.Enqueue(new EOFToken(0, 0));

            //Create a Sub-query Parser Context
            SparqlQueryParserContext subcontext = new SparqlQueryParserContext(context, tokens);
            subcontext.Query.NamespaceMap.Import(context.Query.NamespaceMap);
            SparqlQuery subquery = this.ParseInternal(subcontext);
            foreach (SparqlVariable var in subquery.Variables)
            {
                if (var.IsResultVariable) context.Query.AddVariable("?" + var.Name, false);
            }
            SubQueryPattern subqueryPattern = new SubQueryPattern(subquery);
            p.AddTriplePattern(subqueryPattern);
        }