private string CheckUri(string uri) { string error = Entity.ValidateUri(uri); if (error != null) { OnWarning("The URI <" + uri + "> is not valid: " + error); } return(uri); }
private Resource ReadResource2(ParseContext context, bool allowDirective, out bool reverse, out bool forgetBNode) { reverse = false; forgetBNode = false; Location loc = context.Location; object tok = ReadToken(context.source, context); if (tok is Literal) { return((Literal)tok); } string str = (string)tok; if (str == "") { return(null); } // Directives if (str == "@prefix") { if (allowDirective) { return(PrefixResource); } else { OnError("The directive '" + str + "' is not allowed here", loc); } } if (str == "@keywords") { if (allowDirective) { return(KeywordsResource); } else { OnError("The directive '" + str + "' is not allowed here", loc); } } if (str == "@base") { if (allowDirective) { return(BaseResource); } else { OnError("The directive '" + str + "' is not allowed here", loc); } } // @ Keywords if (context.UsingKeywords && context.Keywords.Contains(str)) { str = "@" + str; } if (!context.UsingKeywords && (str == "a" || str == "has" || str == "is")) { str = "@" + str; } // Standard Keywords // TODO: Turn these off with @keywords if (str == "@a") { return(entRDFTYPE); } if (str == "=") { return(entDAMLEQUIV); } if (str == "=>") { return(entLOGIMPLIES); } if (str == "<=") { reverse = true; return(entLOGIMPLIES); } if (str == "=:>") // SPECIAL EXTENSION! { return(entGRAPHCONTAINS); } if (str == "@has") // ignore this token { return(ReadResource2(context, false, out reverse, out forgetBNode)); } if (str == "@is") { // Reverse predicate bool reversetemp; Resource pred = ReadResource2(context, false, out reversetemp, out forgetBNode); reverse = true; string of = ReadToken(context.source, context) as string; if (of == null) { OnError("End of stream while expecting 'of'", loc); } if (of == "@of" || (!context.UsingKeywords && of == "of") || (context.UsingKeywords && context.Keywords.Contains("of") && of == "of")) { return(pred); } OnError("Expecting token 'of' but found '" + of + "'", loc); return(null); // unreachable } if (str.StartsWith("@")) { OnError("The " + str + " directive is not supported", loc); } // URI if (str.StartsWith("<") && str.EndsWith(">")) { string uri = GetAbsoluteUri(BaseUri, str.Substring(1, str.Length - 2)); string urierror = Entity.ValidateUri(uri); if (urierror != null) { OnWarning(urierror, loc); } return(GetResource(context, uri)); } // VARIABLE if (str[0] == '?') { string name = str.Substring(1); Entity varb = (Entity)context.variables[name]; if (varb == null) { varb = new Variable(name); AddVariable((Variable)varb); context.variables[name] = varb; } return(varb); } // QNAME if (str.IndexOf(":") != -1) { return(ResolveQName(str, context, loc)); } // ANONYMOUS if (str == "[") { Entity ret = new BNode(); ReadWhitespace(context.source); if (context.source.Peek() != ']') { char bracket = ReadPredicates(ret, context); if (bracket == '.') { bracket = ReadPunc(context.source); } if (bracket != ']') { OnError("Expected a close bracket but found '" + bracket + "'", loc); } } else { context.source.Read(); } forgetBNode = true; return(ret); } // LIST if (str == "(") { // A list Entity head = null, ent = null; while (true) { bool rev2, fb2; Resource res = ReadResource(context, false, out rev2, out fb2); if (res == null) { break; } if (ent == null) { ent = new BNode(); head = ent; } else { Entity sub = new BNode(); Add(context.store, new Statement(ent, entRDFREST, sub, context.meta), loc); ent = sub; } Add(context.store, new Statement(ent, entRDFFIRST, res, context.meta), loc); if (fb2) { DoForget(res, context); } } if (head == null) // No list items. { head = entRDFNIL; // according to Turtle spec } else { Add(context.store, new Statement(ent, entRDFREST, entRDFNIL, context.meta), loc); } return(head); } if (str == ")") { return(null); // Should I use a more precise end-of-list return value? } // FORMULA if (str == "{") { // ParseContext is a struct, so this gives us a clone. ParseContext newcontext = context; // The formula is denoted by a blank node, unless we set // the override meta flag above. if (context.overrideMeta == null) { newcontext.meta = new BNode(); } else { newcontext.meta = context.overrideMeta; } // According to the spec, _:xxx anonymous nodes are // local to the formula. But ?$variables (which aren't // mentioned in the spec) are treated as global names. newcontext.anonymous = new Hashtable(); while (NextPunc(context.source) != '}' && ReadStatement(newcontext)) { } ReadWhitespace(context.source); if (context.source.Peek() == '}') { context.source.Read(); } return(newcontext.meta); } // NUMERIC LITERAL // In Turtle, numbers are restricted to [0-9]+, and are datatyped xsd:integer. double numval; #if !SILVERLIGHT if (double.TryParse(str, System.Globalization.NumberStyles.Any, null, out numval)) { #else bool ok = true; numval = 0; try { numval = double.Parse(str); } catch (Exception) { ok = false; } if (ok) { #endif if (numval >= long.MinValue && numval <= long.MaxValue && numval == (double)(long)numval) { return(new Literal(((long)numval).ToString(), null, NS.XMLSCHEMA + "integer")); } else { return(new Literal(numval.ToString(), null, NS.XMLSCHEMA + "double")); } } //BOOLEAN LITERAL if (str == "true" || str == "false") { return(new Literal(str, null, NS.XMLSCHEMA + "boolean")); } // If @keywords is used, alphanumerics that aren't keywords // are local names in the default namespace. if (context.UsingKeywords && char.IsLetter(str[0])) { if (BaseUri == null) { OnError("The document contains an unqualified name but no BaseUri was specified: \"" + str + "\"", loc); } return(GetResource(context, BaseUri + str)); } // NOTHING MATCHED OnError("Invalid token: " + str, loc); return(null); }