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>&lt;http://foo/bar&gt;</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 + -
显示快捷键?