⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rule.java

📁 Jena推理机
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
                return token;
            }
        }
                
        /**
         * Return a trace of the recently seen tokens, for use
         * in error reporting
         */
        public String recentTokens() {
            StringBuffer trace = new StringBuffer();
            for (int i = priorTokens.size()-1; i >= 0; i--) {
                trace.append(priorTokens.get(i));
                trace.append(" ");
            }
            return trace.toString();
        }
        
        /**
         * Peek ahead one token.
         */
        String peekToken() {
            if (lookahead == null) {
                lookahead = nextToken();
            }
            return lookahead;
        }
        
        /**
         * Push back a previously fetched token. Only depth 1 supported.
         */
        void pushback(String token) {
            lookahead = token;
        }
        
        /**
         * Returns true if token is an skippable separator
         */
        boolean isSeparator(String token) {
            if (token.length() == 1) {
                char c = token.charAt(0);
                return (c == ',' || Character.isWhitespace(c));
            }
            return false;
        }
        
        /**
         * Returns true if token is a syntax element ()[]
         */
        boolean isSyntax(String token) {
            if (token.length() == 1) {
                char c = token.charAt(0);
                return (c == '(' || c == ')' || c == '[' || c == ']');
            }
            return false;
        }
        
        /**
         * Find the variable index for the given variable name
         * and return a Node_RuleVariable with that index.
         */
        Node_RuleVariable getNodeVar(String name) {
            Node_RuleVariable node = (Node_RuleVariable)varMap.get(name);
            if (node == null) {
                node = new Node_RuleVariable(name, varMap.size());
                varMap.put(name, node);
            }
            return node;
        }
        
        /**
         * Translate a token to a node.
         */
        Node parseNode(String token) {
            if (token.startsWith("?")) {
                return getNodeVar(token);
                // Dropped support for anon wildcards until the implementation is better resolved
            } else if (token.equals("*") || token.equals("_")) {
                throw new ParserException("Wildcard variables no longer supported", this);
////                return Node_RuleVariable.ANY;
//                return Node_RuleVariable.WILD;
            } else if (token.indexOf(':') != -1) {
                String exp = prefixMapping.expandPrefix(token); // Local map first
                exp = PrintUtil.expandQname(exp);  // Retain global map for backward compatibility
                if (exp == token) {
                    // No expansion was possible
                    String prefix = token.substring(0, token.indexOf(':'));
                    if (prefix.equals("http") || prefix.equals("urn") 
                     || prefix.equals("ftp") || prefix.equals("mailto")) {
                        // assume it is all OK and fall through
                    } else {
                        // Likely to be a typo in a qname or failure to register
                        throw new ParserException("Unrecognized qname prefix (" + prefix + ") in rule", this);
                    }
                }
                return Node.createURI(exp);
            } else if (peekToken().equals("(")) {
                Functor f = new Functor(token, parseNodeList(), BuiltinRegistry.theRegistry);
                return Functor.makeFunctorNode( f );
            } else if (token.equals("'") || token.equals("\"")) {
                // A plain literal
                String lit = nextToken();
                // Skip the trailing quote
                nextToken();
                // Check for an explicit datatype
                if (peekToken().startsWith("^^")) {
                    String dtURI = nextToken().substring(2);
                    if (dtURI.indexOf(':') != -1) {
                        // Thanks to Steve Cranefield for pointing out the need for prefix expansion here
                        String exp = prefixMapping.expandPrefix(dtURI); // Local map first
                        exp = PrintUtil.expandQname(exp);  // Retain global map for backward compatibility
                        if (exp == dtURI) {
                            // No expansion was possible
                            String prefix = dtURI.substring(0, dtURI.indexOf(':'));
                            if (prefix.equals("http") || prefix.equals("urn") 
                             || prefix.equals("ftp") || prefix.equals("mailto")) {
                                // assume it is all OK and fall through
                            } else {
                                // Likely to be a typo in a qname or failure to register
                                throw new ParserException("Unrecognized qname prefix (" + prefix + ") in rule", this);
                            }
                        } else {
                            dtURI = exp;
                        }
                    } 
                    RDFDatatype dt = TypeMapper.getInstance().getSafeTypeByName(dtURI);
                    return Node.createLiteral(lit, "", dt);
                } else {
                    return Node.createLiteral(lit, "", false);
                }                
            } else  if ( Character.isDigit(token.charAt(0)) || 
                         (token.charAt(0) == '-' && token.length() > 1 && Character.isDigit(token.charAt(1))) ) {
                // A number literal
               return parseNumber(token);
            } else {
                // A  uri
                return Node.createURI(token);
            }
        }
        
        /**
         * Turn a possible numeric token into typed literal else a plain literal
         * @return the constructed literal node
         */
        Node parseNumber(String lit) {
            if ( Character.isDigit(lit.charAt(0)) || 
                (lit.charAt(0) == '-' && lit.length() > 1 && Character.isDigit(lit.charAt(1))) ) {
                if (lit.indexOf(".") != -1) {
                    // Float?
                    if (XSDDatatype.XSDfloat.isValid(lit)) {
                        return Node.createLiteral(lit, "", XSDDatatype.XSDfloat);
                    }
                } else {
                    // Int?
                    if (XSDDatatype.XSDint.isValid(lit)) {
                        return Node.createLiteral(lit, "", XSDDatatype.XSDint);
                    }
                }
            }
            // Default is a plain literal
            return Node.createLiteral(lit, "", false);
        }
        
        /**
         * Parse a list of nodes delimited by parentheses
         */
        List parseNodeList() {
            String token = nextToken();
            if (!token.equals("(")) {
                throw new ParserException("Expected '(' at start of clause, found " + token, this);
            }
            token = nextToken();
            List nodeList = new ArrayList();
            while (!isSyntax(token)) {
                nodeList.add(parseNode(token));
                token = nextToken();
            }
            if (!token.equals(")")) {
                throw new ParserException("Expected ')' at end of clause, found " + token, this);
            }
            return nodeList;
        }
        
        /**
         * Parse a clause, could be a triple pattern, a rule or a functor
         */
        Object parseClause() {
            String token = peekToken();
            if (token.equals("(")) {
                List nodes = parseNodeList();
                if (nodes.size() != 3) {
                    throw new ParserException("Triple with " + nodes.size() + " nodes!", this);
                }
                if (Functor.isFunctor((Node)nodes.get(0))) {
                    throw new ParserException("Functors not allowed in subject position of pattern", this);
                }
                if (Functor.isFunctor((Node)nodes.get(1))) {
                    throw new ParserException("Functors not allowed in predicate position of pattern", this);
                }
                return new TriplePattern((Node)nodes.get(0), (Node)nodes.get(1), (Node)nodes.get(2));
            } else if (token.equals("[")) {
                nextToken();
                return doParseRule(true);
            } else {
                String name = nextToken();
                List args = parseNodeList();
                Functor clause = new Functor(name, args, BuiltinRegistry.theRegistry);
                if (clause.getImplementor() == null) {
                    // Not a fatal error becase later processing can add this
                    // implementation to the registry
                    logger.warn("Rule references unimplemented functor: " + name);
                }
                return clause;
            }
        }
        
        
        /**
         * Parse a rule, terminated by a "]" or "." character.
         */
        public Rule parseRule() {
            return doParseRule(false);
        }
        
        /**
         * Parse a rule, terminated by a "]" or "." character.
         * @param retainVarMap set to true to ccause the existing varMap to be left in place, which
         * is required for nested rules.
         */
        private Rule doParseRule(boolean retainVarMap) {
            try {
                // Skip initial '[' if present
                if (peekToken().equals("[")) {
                    nextToken();
                }
                // Check for optional name
                String name = null;
                String token = peekToken();
                if (token.endsWith(":")) {
                    name = token.substring(0, token.length()-1);
                    nextToken();
                }
                // Start rule parsing with empty variable table
                if (!retainVarMap) varMap = new HashMap();
                // Body
                List body = new ArrayList();
                token = peekToken();
                while ( !(token.equals("->") || token.equals("<-")) ) {
                    body.add(parseClause());
                    token = peekToken();
                }
                boolean backwardRule = token.equals("<-");
                List head = new ArrayList();
                token = nextToken();   // skip -> token
                token = peekToken();
                while ( !(token.equals(".") || token.equals("]")) ) {
                    head.add(parseClause());
                    token = peekToken();
                } 
                nextToken();        // consume the terminating token
                Rule r = null;
                if (backwardRule) {
                    r =  new Rule(name, body, head);
                } else {
                    r = new Rule(name, head, body);
                }
                r.numVars = varMap.keySet().size();
                r.isBackward = backwardRule;
                return r;
            } catch (NoSuchElementException e) {
                throw new ParserException("Malformed rule", this);
            }
        }

    }
   
    /** Equality override */
    public boolean equals(Object o) {
        // Pass 1 - just check basic shape
        if (! (o instanceof Rule) ) return false;
        Rule other = (Rule) o;
        if (other.head.length != head.length) return false;
        if (other.body.length != body.length) return false;
        // Pass 2 - check clause by clause matching
        for (int i = 0; i < body.length; i++) {
            if (! ((ClauseEntry)body[i]).sameAs((ClauseEntry)other.body[i]) ) return false;
        }
        for (int i = 0; i < head.length; i++) {
            if (! ((ClauseEntry)head[i]).sameAs((ClauseEntry)other.head[i]) ) return false;
        }
        return true;
    }
        
    /** hash function override */
    public int hashCode() {
        int hash = 0;
        for (int i = 0; i < body.length; i++) {
            hash = (hash << 1) ^ body[i].hashCode();
        }
        for (int i = 0; i < head.length; i++) {
            hash = (hash << 1) ^ head[i].hashCode();
        }
        return hash;
    }
    
    /**
     * Compare clause entries, taking into account variable indices.
     * The equality function ignores differences between variables.
     */
    public boolean sameAs(Object o) {
        return equals(o);
    }
    
//=======================================================================
// Other supporting inner classes

    /**
     * Inner class. Exception raised if there is a problem
     * during rule parsing.
     */
    public static class ParserException extends JenaException {
        
        /** constructor */
        public ParserException(String message, Parser parser) {
            super(constructMessage(message, parser));
        }
        
        /**
         * Extract context trace from prior tokens stack
         */
        private static String constructMessage(String baseMessage, Parser parser) {
            StringBuffer message = new StringBuffer();
            message.append(baseMessage);
            message.append("\nAt '");
            message.append(parser.recentTokens());
            message.append("'");
            return message.toString();
        }
        
    }
    
}

/*
    (c) Copyright 2003, 2004, 2005, 2006, 2007 Hewlett-Packard Development Company, LP
    All rights reserved.

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions
    are met:

    1. Redistributions of source code must retain the above copyright
       notice, this list of conditions and the following disclaimer.

    2. Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimer in the
       documentation and/or other materials provided with the distribution.

    3. The name of the author may not be used to endorse or promote products
       derived from this software without specific prior written permission.

    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
    NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -