/* * Globus Toolkit Public License (GTPL) * * Copyright (c) 1999 University of Chicago and The University of * Southern California. All Rights Reserved. * * 1) The "Software", below, refers to the Globus Toolkit (in either * source-code, or binary form and accompanying documentation) and a * "work based on the Software" means a work based on either the * Software, on part of the Software, or on any derivative work of * the Software under copyright law: that is, a work containing all * or a portion of the Software either verbatim or with * modifications. Each licensee is addressed as "you" or "Licensee." * * 2) The University of Southern California and the University of * Chicago as Operator of Argonne National Laboratory are copyright * holders in the Software. The copyright holders and their third * party licensors hereby grant Licensee a royalty-free nonexclusive * license, subject to the limitations stated herein and * U.S. Government license rights. * * 3) A copy or copies of the Software may be given to others, if you * meet the following conditions: * * a) Copies in source code must include the copyright notice and * this license. * * b) Copies in binary form must include the copyright notice and * this license in the documentation and/or other materials * provided with the copy. * * 4) All advertising materials, journal articles and documentation * mentioning features derived from or use of the Software must * display the following acknowledgement: * * "This product includes software developed by and/or derived from * the Globus project (http://www.globus.org/)." * * In the event that the product being advertised includes an intact * Globus distribution (with copyright and license included) then * this clause is waived. * * 5) You are encouraged to package modifications to the Software * separately, as patches to the Software. * * 6) You may make modifications to the Software, however, if you * modify a copy or copies of the Software or any portion of it, * thus forming a work based on the Software, and give a copy or * copies of such work to others, either in source code or binary * form, you must meet the following conditions: * * a) The Software must carry prominent notices stating that you * changed specified portions of the Software. * * b) The Software must display the following acknowledgement: * * "This product includes software developed by and/or derived * from the Globus Project (http://www.globus.org/) to which the * U.S. Government retains certain rights." * * 7) You may incorporate the Software or a modified version of the * Software into a commercial product, if you meet the following * conditions: * * a) The commercial product or accompanying documentation must * display the following acknowledgment: * * "This product includes software developed by and/or derived * from the Globus Project (http://www.globus.org/) to which the * U.S. Government retains a paid-up, nonexclusive, irrevocable * worldwide license to reproduce, prepare derivative works, and * perform publicly and display publicly." * * b) The user of the commercial product must be given the following * notice: * * "[Commercial product] was prepared, in part, as an account of * work sponsored by an agency of the United States Government. * Neither the United States, nor the University of Chicago, nor * University of Southern California, nor any contributors to * the Globus Project or Globus Toolkit nor any of their employees, * makes any warranty express or implied, or assumes any legal * liability or responsibility for the accuracy, completeness, or * usefulness of any information, apparatus, product, or process * disclosed, or represents that its use would not infringe * privately owned rights. * * IN NO EVENT WILL THE UNITED STATES, THE UNIVERSITY OF CHICAGO * OR THE UNIVERSITY OF SOUTHERN CALIFORNIA OR ANY CONTRIBUTORS * TO THE GLOBUS PROJECT OR GLOBUS TOOLKIT BE LIABLE FOR ANY * DAMAGES, INCLUDING DIRECT, INCIDENTAL, SPECIAL, OR CONSEQUENTIAL * DAMAGES RESULTING FROM EXERCISE OF THIS LICENSE AGREEMENT OR * THE USE OF THE [COMMERCIAL PRODUCT]." * * 8) LICENSEE AGREES THAT THE EXPORT OF GOODS AND/OR TECHNICAL DATA * FROM THE UNITED STATES MAY REQUIRE SOME FORM OF EXPORT CONTROL * LICENSE FROM THE U.S. GOVERNMENT AND THAT FAILURE TO OBTAIN SUCH * EXPORT CONTROL LICENSE MAY RESULT IN CRIMINAL LIABILITY UNDER U.S. * LAWS. * * 9) Portions of the Software resulted from work developed under a * U.S. Government contract and are subject to the following license: * the Government is granted for itself and others acting on its * behalf a paid-up, nonexclusive, irrevocable worldwide license in * this computer software to reproduce, prepare derivative works, and * perform publicly and display publicly. * * 10) The Software was prepared, in part, as an account of work * sponsored by an agency of the United States Government. Neither * the United States, nor the University of Chicago, nor The * University of Southern California, nor any contributors to the * Globus Project or Globus Toolkit, nor any of their employees, * makes any warranty express or implied, or assumes any legal * liability or responsibility for the accuracy, completeness, or * usefulness of any information, apparatus, product, or process * disclosed, or represents that its use would not infringe privately * owned rights. * * 11) IN NO EVENT WILL THE UNITED STATES, THE UNIVERSITY OF CHICAGO OR * THE UNIVERSITY OF SOUTHERN CALIFORNIA OR ANY CONTRIBUTORS TO THE * GLOBUS PROJECT OR GLOBUS TOOLKIT BE LIABLE FOR ANY DAMAGES, * INCLUDING DIRECT, INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES * RESULTING FROM EXERCISE OF THIS LICENSE AGREEMENT OR THE USE OF * THE SOFTWARE. * * END OF LICENSE */ package org.griphyn.vdl.annotation; import java.io.Reader; import java.io.IOException; import java.io.LineNumberReader; import org.griphyn.vdl.Chimera; /** * Implements the scanner for reserved words and other tokens that are * generated from the input stream. This class is module-local on * purpose. * * @author Jens-S. Vöckler * @version $Revision$ * */ class QueryScanner { /** * stores the stream from which we are currently scanning. */ private LineNumberReader m_in; /** * captures the look-ahead character; */ private int m_lookAhead; /** * Starts to scan the given stream. */ public QueryScanner( java.io.Reader reader ) throws IOException { this.m_in = new LineNumberReader(reader); this.m_lookAhead = m_in.read(); // skipWhitespace(); } /** * Obtains the current line number in the input stream from the outside. * @return the current line number. */ public int getLineNumber() { return m_in.getLineNumber(); } /** * Skips any white space and comments in the input. This method * stops either at the end of file, or at any non-whitespace * input character. */ private void skipWhitespace() throws IOException { // end of file? if ( m_lookAhead == -1 ) return; // skip over whitespace while ( m_lookAhead != -1 && Character.isWhitespace((char) m_lookAhead) ) m_lookAhead = m_in.read(); // skip over comments until eoln if ( m_lookAhead == '#' ) { m_in.readLine(); m_lookAhead = m_in.read(); skipWhitespace(); // FIXME: reformulate end-recursion into loop } } /** * Checks for the availability of more input. * @return true, if there is more to read, false for EOF. */ public boolean hasMoreTokens() throws IOException { skipWhitespace(); return ( this.m_lookAhead != -1 ); } /** * Obtains the next token from the input stream. * @return an instance conforming to the token interface, or null for eof. * @throws IOException if something went wrong while reading * @throws QueryScannerException if a lexical error was encountered. */ public String nextToken() throws IOException, QueryScannerException { // sanity check skipWhitespace(); if ( m_lookAhead == -1 ) return null; switch ( m_lookAhead ) { case '(': m_lookAhead = m_in.read(); skipWhitespace(); return "("; case ')': m_lookAhead = m_in.read(); skipWhitespace(); return ")"; case '=': m_lookAhead = m_in.read(); skipWhitespace(); return "@EQ"; case '>': m_lookAhead = m_in.read(); if (m_lookAhead == '=') { m_lookAhead = m_in.read(); skipWhitespace(); return "@GE"; } else { return "@GT"; } case '<': m_lookAhead = m_in.read(); if (m_lookAhead == '=') { m_lookAhead = m_in.read(); skipWhitespace(); return "@GE"; } else if (m_lookAhead == '>') { m_lookAhead = m_in.read(); skipWhitespace(); return "@NE"; } else { return "@LT"; } case '!': m_lookAhead = m_in.read(); if (m_lookAhead == '=') { m_lookAhead = m_in.read(); skipWhitespace(); return "@NE"; } else { // '!' alone is not allowed throw new QueryScannerException( m_in, "found character '!' without '='" ); } case '\"': case '\'': int ch = m_lookAhead; // parse a quoted string StringBuffer result = new StringBuffer(16); do { m_lookAhead = m_in.read(); if ( m_lookAhead == -1 || m_lookAhead == '\r' || m_lookAhead == '\n' ) { // eof is an unterminated string throw new QueryScannerException( m_in, "unterminated quoted string" ); } else if ( m_lookAhead == '\\' ) { m_lookAhead = m_in.read(); if ( m_lookAhead == -1 ) throw new QueryScannerException( m_in, "unterminated escape in quoted string" ); else result.append(m_lookAhead); // always add whatever is after the backslash } else if ( m_lookAhead != ch ) { result.append((char) m_lookAhead); } } while ( m_lookAhead != ch ); // skip over final quote m_lookAhead = m_in.read(); skipWhitespace(); return ( "$" + result.toString() ); default: // are we parsing a reserved word or identifier if ( Character.isLetterOrDigit((char) m_lookAhead) || m_lookAhead=='_' || m_lookAhead=='-' || m_lookAhead == '.') { StringBuffer identifier = new StringBuffer(8); identifier.append( (char) m_lookAhead ); m_lookAhead = m_in.read(); while ( m_lookAhead != -1 && ( Character.isLetterOrDigit((char) m_lookAhead) || m_lookAhead=='_' || m_lookAhead=='-' || m_lookAhead == '.' || m_lookAhead=='(' || m_lookAhead==')' ) ) { identifier.append( (char) m_lookAhead ); m_lookAhead = m_in.read(); } // done parsing identifier or reserved word skipWhitespace(); String s = identifier.toString(); if ( s.compareToIgnoreCase("exists") == 0 ) return "@EX"; else if ( s.compareToIgnoreCase("contains") == 0 ) // reserved word return "@CT"; else if ( s.compareToIgnoreCase("like") == 0 ) // reserved word return "@LK"; else if ( s.compareToIgnoreCase("between") == 0 ) // reserved word return "@BT"; else if ( s.compareToIgnoreCase("and") == 0 ) // reserved word return "AND"; else if ( s.compareToIgnoreCase("or") == 0 ) // reserved word return "OR"; else if ( s.compareToIgnoreCase("not") == 0 ) // reserved word return "NOT"; else // is a non-reserved identifier return ("#" + s); } else { // unknown material throw new QueryScannerException( m_in, "unknown character " + (char)m_lookAhead ); } } // switch } }