/// <summary>
        /// Tries to parse Literal Tokens into Literal Nodes.
        /// </summary>
        /// <param name="context">Parser Context.</param>
        /// <param name="lit">Literal Token.</param>
        /// <returns></returns>
        private INode TryParseLiteral(TurtleParserContext context, IToken lit)
        {
            IToken next;
            String dturi;

            switch (lit.TokenType)
            {
            case Token.LITERAL:
            case Token.LONGLITERAL:
                next = context.Tokens.Peek();
                if (next.TokenType == Token.LANGSPEC)
                {
                    // Has a Language Specifier
                    next = context.Tokens.Dequeue();
                    return(context.Handler.CreateLiteralNode(lit.Value, next.Value));
                }
                else if (next.TokenType == Token.DATATYPE)
                {
                    // Has a Datatype
                    next = context.Tokens.Dequeue();
                    try
                    {
                        if (next.Value.StartsWith("<"))
                        {
                            dturi = next.Value.Substring(1, next.Value.Length - 2);
                            return(context.Handler.CreateLiteralNode(lit.Value, UriFactory.Create(Tools.ResolveUri(dturi, context.BaseUri.ToSafeString()))));
                        }
                        else
                        {
                            dturi = Tools.ResolveQName(next.Value, context.Namespaces, context.BaseUri);
                            return(context.Handler.CreateLiteralNode(lit.Value, UriFactory.Create(dturi)));
                        }
                    }
                    catch (RdfException rdfEx)
                    {
                        throw new RdfParseException("Unable to resolve the Datatype '" + next.Value + "' due to the following error:\n" + rdfEx.Message, next, rdfEx);
                    }
                }
                else
                {
                    // Just an untyped Literal
                    return(context.Handler.CreateLiteralNode(lit.Value));
                }

            case Token.LITERALWITHDT:
                LiteralWithDataTypeToken litdt = (LiteralWithDataTypeToken)lit;
                try
                {
                    if (litdt.DataType.StartsWith("<"))
                    {
                        dturi = litdt.DataType.Substring(1, litdt.DataType.Length - 2);
                        return(context.Handler.CreateLiteralNode(litdt.Value, UriFactory.Create(Tools.ResolveUri(dturi, context.BaseUri.ToSafeString()))));
                    }
                    else
                    {
                        dturi = Tools.ResolveQName(litdt.DataType, context.Namespaces, context.BaseUri);
                        return(context.Handler.CreateLiteralNode(litdt.Value, UriFactory.Create(dturi)));
                    }
                }
                catch (RdfException rdfEx)
                {
                    throw new RdfParseException("Unable to resolve the Datatype '" + litdt.DataType + "' due to the following error:\n" + rdfEx.Message, litdt, rdfEx);
                }

            case Token.LITERALWITHLANG:
                LiteralWithLanguageSpecifierToken langlit = (LiteralWithLanguageSpecifierToken)lit;
                return(context.Handler.CreateLiteralNode(langlit.Value, langlit.Language));

            case Token.PLAINLITERAL:
                // Attempt to infer Type
                if (TurtleSpecsHelper.IsValidPlainLiteral(lit.Value, _syntax))
                {
                    if (TurtleSpecsHelper.IsValidDouble(lit.Value))
                    {
                        return(context.Handler.CreateLiteralNode(lit.Value, UriFactory.Create(XmlSpecsHelper.XmlSchemaDataTypeDouble)));
                    }
                    else if (TurtleSpecsHelper.IsValidInteger(lit.Value))
                    {
                        return(context.Handler.CreateLiteralNode(lit.Value, UriFactory.Create(XmlSpecsHelper.XmlSchemaDataTypeInteger)));
                    }
                    else if (TurtleSpecsHelper.IsValidDecimal(lit.Value))
                    {
                        return(context.Handler.CreateLiteralNode(lit.Value, UriFactory.Create(XmlSpecsHelper.XmlSchemaDataTypeDecimal)));
                    }
                    else
                    {
                        return(context.Handler.CreateLiteralNode(lit.Value.ToLower(), UriFactory.Create(XmlSpecsHelper.XmlSchemaDataTypeBoolean)));
                    }
                }
                else
                {
                    throw ParserHelper.Error("The value '" + lit.Value + "' is not valid as a Plain Literal in Turtle", lit);
                }

            default:
                throw ParserHelper.Error("Unexpected Token '" + lit.GetType().ToString() + "' encountered, expected a valid Literal Token to convert to a Node", lit);
            }
        }
Exemple #2
0
        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);
        }