001: /*
002: * Globus Toolkit Public License (GTPL)
003: *
004: * Copyright (c) 1999 University of Chicago and The University of
005: * Southern California. All Rights Reserved.
006: *
007: * 1) The "Software", below, refers to the Globus Toolkit (in either
008: * source-code, or binary form and accompanying documentation) and a
009: * "work based on the Software" means a work based on either the
010: * Software, on part of the Software, or on any derivative work of
011: * the Software under copyright law: that is, a work containing all
012: * or a portion of the Software either verbatim or with
013: * modifications. Each licensee is addressed as "you" or "Licensee."
014: *
015: * 2) The University of Southern California and the University of
016: * Chicago as Operator of Argonne National Laboratory are copyright
017: * holders in the Software. The copyright holders and their third
018: * party licensors hereby grant Licensee a royalty-free nonexclusive
019: * license, subject to the limitations stated herein and
020: * U.S. Government license rights.
021: *
022: * 3) A copy or copies of the Software may be given to others, if you
023: * meet the following conditions:
024: *
025: * a) Copies in source code must include the copyright notice and
026: * this license.
027: *
028: * b) Copies in binary form must include the copyright notice and
029: * this license in the documentation and/or other materials
030: * provided with the copy.
031: *
032: * 4) All advertising materials, journal articles and documentation
033: * mentioning features derived from or use of the Software must
034: * display the following acknowledgement:
035: *
036: * "This product includes software developed by and/or derived from
037: * the Globus project (http://www.globus.org/)."
038: *
039: * In the event that the product being advertised includes an intact
040: * Globus distribution (with copyright and license included) then
041: * this clause is waived.
042: *
043: * 5) You are encouraged to package modifications to the Software
044: * separately, as patches to the Software.
045: *
046: * 6) You may make modifications to the Software, however, if you
047: * modify a copy or copies of the Software or any portion of it,
048: * thus forming a work based on the Software, and give a copy or
049: * copies of such work to others, either in source code or binary
050: * form, you must meet the following conditions:
051: *
052: * a) The Software must carry prominent notices stating that you
053: * changed specified portions of the Software.
054: *
055: * b) The Software must display the following acknowledgement:
056: *
057: * "This product includes software developed by and/or derived
058: * from the Globus Project (http://www.globus.org/) to which the
059: * U.S. Government retains certain rights."
060: *
061: * 7) You may incorporate the Software or a modified version of the
062: * Software into a commercial product, if you meet the following
063: * conditions:
064: *
065: * a) The commercial product or accompanying documentation must
066: * display the following acknowledgment:
067: *
068: * "This product includes software developed by and/or derived
069: * from the Globus Project (http://www.globus.org/) to which the
070: * U.S. Government retains a paid-up, nonexclusive, irrevocable
071: * worldwide license to reproduce, prepare derivative works, and
072: * perform publicly and display publicly."
073: *
074: * b) The user of the commercial product must be given the following
075: * notice:
076: *
077: * "[Commercial product] was prepared, in part, as an account of
078: * work sponsored by an agency of the United States Government.
079: * Neither the United States, nor the University of Chicago, nor
080: * University of Southern California, nor any contributors to
081: * the Globus Project or Globus Toolkit nor any of their employees,
082: * makes any warranty express or implied, or assumes any legal
083: * liability or responsibility for the accuracy, completeness, or
084: * usefulness of any information, apparatus, product, or process
085: * disclosed, or represents that its use would not infringe
086: * privately owned rights.
087: *
088: * IN NO EVENT WILL THE UNITED STATES, THE UNIVERSITY OF CHICAGO
089: * OR THE UNIVERSITY OF SOUTHERN CALIFORNIA OR ANY CONTRIBUTORS
090: * TO THE GLOBUS PROJECT OR GLOBUS TOOLKIT BE LIABLE FOR ANY
091: * DAMAGES, INCLUDING DIRECT, INCIDENTAL, SPECIAL, OR CONSEQUENTIAL
092: * DAMAGES RESULTING FROM EXERCISE OF THIS LICENSE AGREEMENT OR
093: * THE USE OF THE [COMMERCIAL PRODUCT]."
094: *
095: * 8) LICENSEE AGREES THAT THE EXPORT OF GOODS AND/OR TECHNICAL DATA
096: * FROM THE UNITED STATES MAY REQUIRE SOME FORM OF EXPORT CONTROL
097: * LICENSE FROM THE U.S. GOVERNMENT AND THAT FAILURE TO OBTAIN SUCH
098: * EXPORT CONTROL LICENSE MAY RESULT IN CRIMINAL LIABILITY UNDER U.S.
099: * LAWS.
100: *
101: * 9) Portions of the Software resulted from work developed under a
102: * U.S. Government contract and are subject to the following license:
103: * the Government is granted for itself and others acting on its
104: * behalf a paid-up, nonexclusive, irrevocable worldwide license in
105: * this computer software to reproduce, prepare derivative works, and
106: * perform publicly and display publicly.
107: *
108: * 10) The Software was prepared, in part, as an account of work
109: * sponsored by an agency of the United States Government. Neither
110: * the United States, nor the University of Chicago, nor The
111: * University of Southern California, nor any contributors to the
112: * Globus Project or Globus Toolkit, nor any of their employees,
113: * makes any warranty express or implied, or assumes any legal
114: * liability or responsibility for the accuracy, completeness, or
115: * usefulness of any information, apparatus, product, or process
116: * disclosed, or represents that its use would not infringe privately
117: * owned rights.
118: *
119: * 11) IN NO EVENT WILL THE UNITED STATES, THE UNIVERSITY OF CHICAGO OR
120: * THE UNIVERSITY OF SOUTHERN CALIFORNIA OR ANY CONTRIBUTORS TO THE
121: * GLOBUS PROJECT OR GLOBUS TOOLKIT BE LIABLE FOR ANY DAMAGES,
122: * INCLUDING DIRECT, INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES
123: * RESULTING FROM EXERCISE OF THIS LICENSE AGREEMENT OR THE USE OF
124: * THE SOFTWARE.
125: *
126: * END OF LICENSE
127: */
128: package org.griphyn.vdl.annotation;
129:
130: import java.io.Reader;
131: import java.io.IOException;
132: import java.io.LineNumberReader;
133: import org.griphyn.vdl.Chimera;
134:
135: /**
136: * Implements the scanner for reserved words and other tokens that are
137: * generated from the input stream. This class is module-local on
138: * purpose.
139: *
140: * @author Jens-S. Vöckler
141: * @version $Revision: 50 $
142: *
143: */
144: class QueryScanner {
145: /**
146: * stores the stream from which we are currently scanning.
147: */
148: private LineNumberReader m_in;
149:
150: /**
151: * captures the look-ahead character;
152: */
153: private int m_lookAhead;
154:
155: /**
156: * Starts to scan the given stream.
157: */
158: public QueryScanner(java.io.Reader reader) throws IOException {
159: this .m_in = new LineNumberReader(reader);
160: this .m_lookAhead = m_in.read();
161: // skipWhitespace();
162: }
163:
164: /**
165: * Obtains the current line number in the input stream from the outside.
166: * @return the current line number.
167: */
168: public int getLineNumber() {
169: return m_in.getLineNumber();
170: }
171:
172: /**
173: * Skips any white space and comments in the input. This method
174: * stops either at the end of file, or at any non-whitespace
175: * input character.
176: */
177: private void skipWhitespace() throws IOException {
178: // end of file?
179: if (m_lookAhead == -1)
180: return;
181:
182: // skip over whitespace
183: while (m_lookAhead != -1
184: && Character.isWhitespace((char) m_lookAhead))
185: m_lookAhead = m_in.read();
186:
187: // skip over comments until eoln
188: if (m_lookAhead == '#') {
189: m_in.readLine();
190: m_lookAhead = m_in.read();
191: skipWhitespace(); // FIXME: reformulate end-recursion into loop
192: }
193: }
194:
195: /**
196: * Checks for the availability of more input.
197: * @return true, if there is more to read, false for EOF.
198: */
199: public boolean hasMoreTokens() throws IOException {
200: skipWhitespace();
201: return (this .m_lookAhead != -1);
202: }
203:
204: /**
205: * Obtains the next token from the input stream.
206: * @return an instance conforming to the token interface, or null for eof.
207: * @throws IOException if something went wrong while reading
208: * @throws QueryScannerException if a lexical error was encountered.
209: */
210: public String nextToken() throws IOException, QueryScannerException {
211: // sanity check
212: skipWhitespace();
213: if (m_lookAhead == -1)
214: return null;
215:
216: switch (m_lookAhead) {
217: case '(':
218: m_lookAhead = m_in.read();
219: skipWhitespace();
220: return "(";
221:
222: case ')':
223: m_lookAhead = m_in.read();
224: skipWhitespace();
225: return ")";
226:
227: case '=':
228: m_lookAhead = m_in.read();
229: skipWhitespace();
230: return "@EQ";
231:
232: case '>':
233: m_lookAhead = m_in.read();
234: if (m_lookAhead == '=') {
235: m_lookAhead = m_in.read();
236: skipWhitespace();
237: return "@GE";
238: } else {
239: return "@GT";
240: }
241:
242: case '<':
243: m_lookAhead = m_in.read();
244: if (m_lookAhead == '=') {
245: m_lookAhead = m_in.read();
246: skipWhitespace();
247: return "@GE";
248: } else if (m_lookAhead == '>') {
249: m_lookAhead = m_in.read();
250: skipWhitespace();
251: return "@NE";
252: } else {
253: return "@LT";
254: }
255:
256: case '!':
257: m_lookAhead = m_in.read();
258: if (m_lookAhead == '=') {
259: m_lookAhead = m_in.read();
260: skipWhitespace();
261: return "@NE";
262: } else {
263: // '!' alone is not allowed
264: throw new QueryScannerException(m_in,
265: "found character '!' without '='");
266: }
267:
268: case '\"':
269: case '\'':
270: int ch = m_lookAhead;
271: // parse a quoted string
272: StringBuffer result = new StringBuffer(16);
273:
274: do {
275: m_lookAhead = m_in.read();
276: if (m_lookAhead == -1 || m_lookAhead == '\r'
277: || m_lookAhead == '\n') {
278: // eof is an unterminated string
279: throw new QueryScannerException(m_in,
280: "unterminated quoted string");
281: } else if (m_lookAhead == '\\') {
282: m_lookAhead = m_in.read();
283: if (m_lookAhead == -1)
284: throw new QueryScannerException(m_in,
285: "unterminated escape in quoted string");
286: else
287: result.append(m_lookAhead); // always add whatever is after the backslash
288: } else if (m_lookAhead != ch) {
289: result.append((char) m_lookAhead);
290: }
291: } while (m_lookAhead != ch);
292:
293: // skip over final quote
294: m_lookAhead = m_in.read();
295: skipWhitespace();
296: return ("$" + result.toString());
297:
298: default:
299: // are we parsing a reserved word or identifier
300: if (Character.isLetterOrDigit((char) m_lookAhead)
301: || m_lookAhead == '_' || m_lookAhead == '-'
302: || m_lookAhead == '.') {
303: StringBuffer identifier = new StringBuffer(8);
304: identifier.append((char) m_lookAhead);
305: m_lookAhead = m_in.read();
306: while (m_lookAhead != -1
307: && (Character
308: .isLetterOrDigit((char) m_lookAhead)
309: || m_lookAhead == '_'
310: || m_lookAhead == '-'
311: || m_lookAhead == '.'
312: || m_lookAhead == '(' || m_lookAhead == ')')) {
313: identifier.append((char) m_lookAhead);
314: m_lookAhead = m_in.read();
315: }
316:
317: // done parsing identifier or reserved word
318: skipWhitespace();
319: String s = identifier.toString();
320: if (s.compareToIgnoreCase("exists") == 0)
321: return "@EX";
322: else if (s.compareToIgnoreCase("contains") == 0)
323: // reserved word
324: return "@CT";
325: else if (s.compareToIgnoreCase("like") == 0)
326: // reserved word
327: return "@LK";
328: else if (s.compareToIgnoreCase("between") == 0)
329: // reserved word
330: return "@BT";
331: else if (s.compareToIgnoreCase("and") == 0)
332: // reserved word
333: return "AND";
334: else if (s.compareToIgnoreCase("or") == 0)
335: // reserved word
336: return "OR";
337: else if (s.compareToIgnoreCase("not") == 0)
338: // reserved word
339: return "NOT";
340: else
341: // is a non-reserved identifier
342: return ("#" + s);
343:
344: } else {
345: // unknown material
346: throw new QueryScannerException(m_in,
347: "unknown character " + (char) m_lookAhead);
348: }
349: } // switch
350: }
351: }
|