serql.jj
来自「这是外国一个开源推理机」· JJ 代码 · 共 1,680 行 · 第 1/3 页
JJ
1,680 行
/* Sesame - Storage and Querying architecture for RDF and RDF Schema * Copyright (C) 2001-2005 Aduna * * Contact: * Aduna * Prinses Julianaplein 14 b * 3817 CS Amersfoort * The Netherlands * tel. +33 (0)33 465 99 87 * fax. +33 (0)33 465 99 87 * * http://aduna.biz/ * http://www.openrdf.org/ * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//* * SeRQL parser file for JavaCC, a Java Compiler Compiler. JavaCC can be * downloaded from https://javacc.dev.java.net/ */options { STATIC=false; IGNORE_CASE=true; UNICODE_INPUT=true;}PARSER_BEGIN(SerqlParser)package org.openrdf.sesame.query.serql.parser;import java.util.ArrayList;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Set;import org.openrdf.util.xml.XmlDatatypeUtil;import org.openrdf.vocabulary.OWL;import org.openrdf.vocabulary.RDF;import org.openrdf.vocabulary.RDFS;import org.openrdf.vocabulary.XmlSchema;import org.openrdf.model.BNode;import org.openrdf.model.Literal;import org.openrdf.model.URI;import org.openrdf.model.impl.BNodeImpl;import org.openrdf.model.impl.LiteralImpl;import org.openrdf.model.impl.URIImpl;import org.openrdf.rio.ntriples.NTriplesUtil;import org.openrdf.sesame.query.GraphQuery;import org.openrdf.sesame.query.TableQuery;import org.openrdf.sesame.sail.query.And;import org.openrdf.sesame.sail.query.BooleanConstant;import org.openrdf.sesame.sail.query.BooleanExpr;import org.openrdf.sesame.sail.query.ConstructQuery;import org.openrdf.sesame.sail.query.CompareAll;import org.openrdf.sesame.sail.query.CompareAny;import org.openrdf.sesame.sail.query.Datatype;import org.openrdf.sesame.sail.query.Exists;import org.openrdf.sesame.sail.query.GraphPattern;import org.openrdf.sesame.sail.query.In;import org.openrdf.sesame.sail.query.Intersect;import org.openrdf.sesame.sail.query.IsBNode;import org.openrdf.sesame.sail.query.IsLiteral;import org.openrdf.sesame.sail.query.IsResource;import org.openrdf.sesame.sail.query.IsURI;import org.openrdf.sesame.sail.query.Label;import org.openrdf.sesame.sail.query.Lang;import org.openrdf.sesame.sail.query.Like;import org.openrdf.sesame.sail.query.LiteralExpr;import org.openrdf.sesame.sail.query.LocalName;import org.openrdf.sesame.sail.query.Minus;import org.openrdf.sesame.sail.query.Namespace;import org.openrdf.sesame.sail.query.Not;import org.openrdf.sesame.sail.query.Null;import org.openrdf.sesame.sail.query.Or;import org.openrdf.sesame.sail.query.ProjectionElem;import org.openrdf.sesame.sail.query.Query;import org.openrdf.sesame.sail.query.ResourceExpr;import org.openrdf.sesame.sail.query.SelectQuery;import org.openrdf.sesame.sail.query.StringConstant;import org.openrdf.sesame.sail.query.Union;import org.openrdf.sesame.sail.query.ValueCompare;import org.openrdf.sesame.sail.query.ValueExpr;import org.openrdf.sesame.sail.query.Var;public class SerqlParser {/*-------------------------------+| Constants |+-------------------------------*/ public static final String SERQL_NS = "http://www.openrdf.org/schema/serql#"; public static final URI SERQL_DIRECTSUBCLASSOF = new URIImpl(SERQL_NS + "directSubClassOf"); public static final URI SERQL_DIRECTSUBPROPERTYOF = new URIImpl(SERQL_NS + "directSubPropertyOf"); public static final URI SERQL_DIRECTTYPE = new URIImpl(SERQL_NS + "directType"); public static final URI XSD_INTEGER = new URIImpl(XmlSchema.INTEGER); public static final URI XSD_DECIMAL = new URIImpl(XmlSchema.DECIMAL); static final Var RDF_TYPE_VAR = new Var("_rdfType", URIImpl.RDF_TYPE); static final Var RDF_STATEMENT_VAR = new Var("_rdfStatement", URIImpl.RDF_STATEMENT); static final Var RDF_SUBJECT_VAR = new Var("_rdfSubject", URIImpl.RDF_SUBJECT); static final Var RDF_PREDICATE_VAR = new Var("_rdfPredicate", URIImpl.RDF_PREDICATE); static final Var RDF_OBJECT_VAR = new Var("_rdfObject", URIImpl.RDF_OBJECT);/*-------------------------------+| Variables |+-------------------------------*/ /** * Mapping of prefix to namespace. **/ protected Map _namespaces = new HashMap(16); /** * List of shared variables. Named variables are shared; multiple * occurrences of the name of one variable in a query represent * the same variable. **/ protected List _sharedVars = new ArrayList(16); /** * List of shared variables that have not been bound. All newly created * shared variables are first inserted in this list, and are removed * again when they are bound. After parsing the query, this list should * be empty. **/ protected List _unboundVars = new ArrayList(16); protected VarTreeNode _currentTreeNode = new VarTreeNode(); /** * Anonymous variable identifier. **/ protected int _varNo = 0;/*-------------------------------+| Methods |+-------------------------------*/ static class VarTreeNode { private VarTreeNode _parent; private List _variables; private List _children; public VarTreeNode() { _variables = new ArrayList(8); _children = new ArrayList(4); } public void addVariable(Var var) { _variables.add(var); } public void addChild(VarTreeNode child) { _children.add(child); child.setParent(this); } public void setParent(VarTreeNode parent) { _parent = parent; } public List getVariables() { return _variables; } public boolean containsVar(Var var) { return _variables.contains(var); } public List getChildren() { return _children; } public VarTreeNode getParent() { return _parent; } public boolean isRoot() { return _parent == null; } public String toString() { StringBuffer result = new StringBuffer(32); result.append("("); for (int i = 0; i < _variables.size(); i++) { Var var = (Var)_variables.get(i); result.append(var.getName()); result.append(" "); } result.append(")"); return result.toString(); } /* * Returns a list of variables that this node shares with its * sibling nodes. The list is empty if the node does not share any * vars with its siblings. */ public List getSharedWithSiblings() { if (isRoot()) { // by definition, the root node has no siblings. return new ArrayList(0); } List allVars = new ArrayList(_variables); List siblings = _parent.getChildren(); int siblingCount = siblings.size(); for (int i = 0; i < siblingCount; i++) { VarTreeNode sibling = (VarTreeNode)siblings.get(i); if (! this.equals(sibling)) { allVars.addAll(sibling.getVariables()); } } List result = new ArrayList(); int varCount = allVars.size(); for (int i = 0; i < varCount; i++) { Var var = (Var)allVars.get(i); int occurrences = 0; for (int j = 0; j < siblingCount; j++) { VarTreeNode sibling = (VarTreeNode)siblings.get(j); if (sibling.containsVar(var)) { occurrences++; } } if (occurrences > 1) { result.add(var); } } return result; } } protected void _checkUnboundVars() throws ParseException { if (!_unboundVars.isEmpty()) { String msg = "Unbound variable(s): "; for (int i = 0; i < _unboundVars.size(); i++) { Var var = (Var)_unboundVars.get(i); if (i > 0) { msg += ", "; } msg += var.getName(); } throw new ParseException(msg); } } protected void _checkVariableScoping() throws ParseException { while (!_currentTreeNode.isRoot()) { _currentTreeNode = _currentTreeNode.getParent(); } // enter the recursion with the tree root as current node. _checkVariableScoping(_currentTreeNode); } protected void _checkVariableScoping(VarTreeNode current) throws ParseException { List children = current.getChildren(); if (children.size() > 0) { for (int i = 0; i < children.size(); i++) { VarTreeNode child = (VarTreeNode)children.get(i); _checkVariableScoping(child); } } else { // leaf node VarTreeNode parent = current.getParent(); if (parent != null) { List sharedVars = current.getSharedWithSiblings(); int sharedCount = sharedVars.size(); for (int i = 0; i < sharedCount; i++) { Var sharedVar = (Var)sharedVars.get(i); if (! parent.containsVar(sharedVar)) { throw new ParseException("Shared variable " + sharedVar.getName() + " not bound in parent path expression."); } } } } } /** * Adds a mapping from the specified prefix to the specified * namespace. The specified prefix must already be mapped to some * (other) namespace. * * @return true if the mapping has been added, false otherwise. * @exception ParseException If the specified prefix is already * mapped to some (other) namespace. **/ protected void _setNamespacePrefix(String prefix, String namespace) throws ParseException { if (_namespaces.containsKey(prefix)) { // Prefix already defined, report this error. throw new ParseException("Prefix \"" + prefix + "\" already in use."); } _namespaces.put(prefix, namespace); } /** * Gets the namespace that is mapped to the supplied prefix. **/ protected String _getNamespace(String prefix) { String result = (String)_namespaces.get(prefix); // rdf, rdfs, xsd, owl and serql are default // namespace when not defined explicitly. if (result == null) { if ("rdf".equals(prefix)) { result = RDF.NAMESPACE; } else if ("rdfs".equals(prefix)) { result = RDFS.NAMESPACE; } else if ("xsd".equals(prefix)) { result = XmlSchema.NAMESPACE; } else if ("owl".equals(prefix)) { result = OWL.NAMESPACE; } else if ("serql".equals(prefix)) { result = SERQL_NS; } } return result; } /** * Returns the shared instance of Var that is associated with the * specified variable name. A new shared variable will be created * whenever this method is called with a new variable name. **/ protected Var _getSharedVar(String varName) { Var var; // Search for a variable with the supplied name in _sharedVars Iterator i = _sharedVars.iterator(); while (i.hasNext()) { var = (Var)i.next(); if (var.getName().equals(varName)) { // Variable found _currentTreeNode.addVariable(var); return var; } } // Variable does not exist; create one and add it to a number of lists var = new Var(varName); _sharedVars.add(var); _unboundVars.add(var); _currentTreeNode.addVariable(var); return var; } /** * Creates a new anonymous variable and returns it. **/ protected Var _createAnonymousVar() { Var result = new Var("_" + _varNo++); result.setAnonymous(true); return result; } /** * Parses a string representating of full or abbreviated URI and * creates a URI object from it. **/ protected URI _parseURI(String uri) throws ParseException { if (uri.startsWith("<")) { return _parseFullURI(uri); } else { return _parseQName(uri); } } /** * Parses a string representing a full URI (i.e. * <tt><http://foo/bar></tt>) and creates a URI * object for it. **/ protected URI _parseFullURI(String uri) throws ParseException { // Full URI starts with "<" and ends with ">", remove these characters. return new URIImpl( uri.substring(1, uri.length() - 1) ); } /** * Parses a string representing an abbreviated URI (i.e. * <tt>rdf:type</tt>) and creates a URI object for it. **/ protected URI _parseQName(String uri) throws ParseException { // QNames have the form PREFIX:LNAME, substitute the PREFIX // with an actual namespace. int colonIdx = uri.indexOf(":"); String prefix = uri.substring(0, colonIdx); String localName = uri.substring(colonIdx + 1); String namespace = _getNamespace(prefix); if (namespace == null) { throw new ParseException("Prefix \"" + prefix + "\" not defined."); } return new URIImpl(namespace + localName); } /** * Parses a string representing a blank node URI (i.e. <tt>_:node1</tt>) and * creates a BNode object for it. **/ protected BNode _parseBNode(String bnode) throws ParseException { return new BNodeImpl( bnode.substring(2) ); } /** * Parses a new Literal from the supplied String. **/ protected Literal _parseLiteral(String literal) throws ParseException { // Find string separation points int endLabelIdx = _findEndOfLabel(literal); int startLangIdx = literal.indexOf("@", endLabelIdx); int startDtIdx = literal.indexOf("^^", Math.max(endLabelIdx, startLangIdx)); // Get label String label = literal.substring(1, endLabelIdx); label = NTriplesUtil.unescapeString(label); if (startLangIdx != -1) { // Get language String language = literal.substring(startLangIdx + 1); return new LiteralImpl(label, language); } else if (startDtIdx != -1) { // Get datatype String dtString = literal.substring(startDtIdx + 2); URI datatype = _parseURI(dtString); // Normalize label when datatype is XML Schema built-in if (XmlDatatypeUtil.isBuiltInDatatype(datatype.getURI())) { try { label = XmlDatatypeUtil.normalize(label, datatype.getURI()); } catch (IllegalArgumentException e) { throw new ParseException(e.getMessage()); } } return new LiteralImpl(label, datatype); } else { return new LiteralImpl(label); } } /** * Finds the end of the label in a literal string. This method * takes into account that characters can be escaped using * backslashes. * * @return The index of the double quote ending the label. **/ private int _findEndOfLabel(String literal) throws ParseException { // First character of literal is guaranteed to be a double // quote, start search at second character. boolean previousWasBackslash = false; for (int i = 1; i < literal.length(); i++) { char c = literal.charAt(i); if (c == '"' && !previousWasBackslash) { return i; } else if (c == '\\' && !previousWasBackslash) { // start of escape previousWasBackslash = true; } else if (previousWasBackslash) { // c was escaped previousWasBackslash = false; } } throw new ParseException("Could not find end of literal label"); } /** * Creates a new ParseException with the supplied current and * expected tokens. See ParseException for details. **/ protected ParseException _createParseException( Token currentTokenVal, String[] tokenImage) { // Append "<EOF>" in front of the supplied String array. // ParseException.getMessage expects "<EOF>" as the first String // in the String array. int length = tokenImage.length;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?