001: /*
002: * <copyright>
003: *
004: * Copyright 1997-2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026:
027: package org.cougaar.lib.contract.lang.parser;
028:
029: import java.io.*;
030: import java.util.*;
031:
032: import org.cougaar.lib.contract.lang.*;
033:
034: /**
035: * A <code>TreeVisitor</code> that buffers the visits to an array and
036: * creates a <code>VisitTokenizer</code>.
037: */
038: public class BufferedVisitor implements TreeVisitor {
039:
040: protected static final int DEFAULT_SIZE = 11;
041:
042: protected boolean verbose = DEFAULT_VERBOSE;
043:
044: protected int ntokens;
045: protected int[] tokens;
046: protected int nwords;
047: protected String[] words;
048:
049: public BufferedVisitor() {
050: }
051:
052: public final boolean isVerbose() {
053: return verbose;
054: }
055:
056: public final void setVerbose(boolean verbose) {
057: this .verbose = verbose;
058: }
059:
060: public final void initialize() {
061: initialize(DEFAULT_SIZE);
062: }
063:
064: protected final void initialize(int size) {
065: // create tokens array
066: if ((tokens == null) || (tokens.length < size)) {
067: tokens = new int[size];
068: } else {
069: // keep array, ignore tail tokens
070: }
071: // create words array
072: if ((words == null) || (words.length < size)) {
073: words = new String[size];
074: } else {
075: // keep array, GC Strings
076: for (int i = (VisitTokenizer.TT_CONSTANT + 1); i < nwords; i++) {
077: // memset!
078: words[i] = null;
079: }
080: }
081: ntokens = 0;
082: nwords = VisitTokenizer.TT_CONSTANT + 1;
083: }
084:
085: private final void ensureTokenSlot() {
086: // based on ArrayList
087: int oldCapacity = tokens.length;
088: if ((ntokens + 1) >= oldCapacity) {
089: int[] oldData = tokens;
090: int newCapacity = (oldCapacity * 3) / 2 + 1;
091: tokens = new int[newCapacity];
092: System.arraycopy(oldData, 0, tokens, 0, ntokens);
093: }
094: }
095:
096: private final void addToken(int tok) {
097: ensureTokenSlot();
098: tokens[ntokens] = tok;
099: ntokens++;
100: }
101:
102: private void ensureWordSlot() {
103: // based on ArrayList
104: int oldCapacity = words.length;
105: if ((nwords + 1) >= oldCapacity) {
106: String[] oldData = words;
107: int newCapacity = (oldCapacity * 3) / 2 + 1;
108: words = new String[newCapacity];
109: System.arraycopy(oldData, 0, words, 0, nwords);
110: }
111: }
112:
113: /** add END token <tt>VisitTokenizer.TT_END</tt> */
114: public final void visitEnd() {
115: addToken(VisitTokenizer.TT_END);
116: }
117:
118: public final void visitWord(String word) {
119: ensureWordSlot();
120: words[nwords] = word;
121: addToken(nwords);
122: nwords++;
123: }
124:
125: public final void visitConstant(String type, String value) {
126: ensureWordSlot();
127: words[nwords] = type;
128: addToken(-(nwords));
129: nwords++;
130: ensureWordSlot();
131: words[nwords] = value;
132: nwords++;
133: }
134:
135: /** Short for <tt>visitConstant("java.lang.String", value)</tt>. */
136: public final void visitConstant(String value) {
137: visitConstant(null, value);
138: }
139:
140: public final void visitEndOfTree() {
141: addToken(VisitTokenizer.TT_END_OF_TREE);
142: }
143:
144: public VisitTokenizer getVisitTokenizer() {
145: return new VisitTokenizer() {
146:
147: protected int cursor;
148: protected String word; // also used as consttype
149: protected String constval;
150:
151: protected int markCursor;
152:
153: public void rewind() {
154: cursor = 0;
155: }
156:
157: public void mark() {
158: markCursor = cursor;
159: }
160:
161: public void reset() {
162: cursor = markCursor;
163: }
164:
165: public int nextToken() {
166: int tok = getToken();
167: if (tok != VisitTokenizer.TT_END_OF_TREE) {
168: cursor++;
169: }
170: return tok;
171: }
172:
173: public int previousToken() {
174: int tok = getToken();
175: cursor--;
176: return tok;
177: }
178:
179: public String getWord() {
180: return word;
181: }
182:
183: public String getConstantType() {
184: return word; // reused as consttype
185: }
186:
187: public String getConstantValue() {
188: return constval;
189: }
190:
191: private int getToken() {
192: int tok = tokens[cursor];
193: switch (tok) {
194: case VisitTokenizer.TT_END:
195: // END
196: return VisitTokenizer.TT_END;
197: case VisitTokenizer.TT_END_OF_TREE:
198: // END_OF_TREE
199: return VisitTokenizer.TT_END_OF_TREE;
200: default:
201: if (tok > VisitTokenizer.TT_CONSTANT) {
202: word = words[tok];
203: return VisitTokenizer.TT_WORD;
204: } else if (tok < 0) {
205: int i = -tok;
206: word = words[i]; // reused as consttype
207: constval = words[i + 1];
208: return VisitTokenizer.TT_CONSTANT;
209: } else {
210: // not possible?
211: throw new RuntimeException(
212: "Illegal Parse State!: " + tok);
213: }
214: }
215: }
216: };
217: }
218: }
|