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