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; }
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); } }