00001 /* 00002 [The "BSD licence"] 00003 Copyright (c) 2005-2008 Terence Parr 00004 All rights reserved. 00005 00006 Redistribution and use in source and binary forms, with or without 00007 modification, are permitted provided that the following conditions 00008 are met: 00009 1. Redistributions of source code must retain the above copyright 00010 notice, this list of conditions and the following disclaimer. 00011 2. Redistributions in binary form must reproduce the above copyright 00012 notice, this list of conditions and the following disclaimer in the 00013 documentation and/or other materials provided with the distribution. 00014 3. The name of the author may not be used to endorse or promote products 00015 derived from this software without specific prior written permission. 00016 00017 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 00018 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00019 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 00020 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 00021 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 00022 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00023 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00024 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00025 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 00026 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00027 */ 00028 package org.antlr.runtime.tree; 00029 00030 import org.antlr.runtime.Token; 00031 import org.antlr.runtime.CommonToken; 00032 00033 import java.util.List; 00034 import java.util.ArrayList; 00035 00049 public abstract class RewriteRuleElementStream { 00053 protected int cursor = 0; 00054 00056 protected Object singleElement; 00057 00059 protected List elements; 00060 00069 protected boolean dirty = false; 00070 00075 protected String elementDescription; 00076 protected TreeAdaptor adaptor; 00077 00078 public RewriteRuleElementStream(TreeAdaptor adaptor, String elementDescription) { 00079 this.elementDescription = elementDescription; 00080 this.adaptor = adaptor; 00081 } 00082 00084 public RewriteRuleElementStream(TreeAdaptor adaptor, 00085 String elementDescription, 00086 Object oneElement) 00087 { 00088 this(adaptor, elementDescription); 00089 add(oneElement); 00090 } 00091 00093 public RewriteRuleElementStream(TreeAdaptor adaptor, 00094 String elementDescription, 00095 List elements) 00096 { 00097 this(adaptor, elementDescription); 00098 this.singleElement = null; 00099 this.elements = elements; 00100 } 00101 00107 public void reset() { 00108 cursor = 0; 00109 dirty = true; 00110 } 00111 00112 public void add(Object el) { 00113 //System.out.println("add '"+elementDescription+"' is "+el); 00114 if ( el==null ) { 00115 return; 00116 } 00117 if ( elements!=null ) { // if in list, just add 00118 elements.add(el); 00119 return; 00120 } 00121 if ( singleElement == null ) { // no elements yet, track w/o list 00122 singleElement = el; 00123 return; 00124 } 00125 // adding 2nd element, move to list 00126 elements = new ArrayList(5); 00127 elements.add(singleElement); 00128 singleElement = null; 00129 elements.add(el); 00130 } 00131 00137 public Object nextTree() { 00138 int n = size(); 00139 if ( dirty || (cursor>=n && n==1) ) { 00140 // if out of elements and size is 1, dup 00141 Object el = _next(); 00142 return dup(el); 00143 } 00144 // test size above then fetch 00145 Object el = _next(); 00146 return el; 00147 } 00148 00155 protected Object _next() { 00156 int n = size(); 00157 if ( n ==0 ) { 00158 throw new RewriteEmptyStreamException(elementDescription); 00159 } 00160 if ( cursor>= n) { // out of elements? 00161 if ( n ==1 ) { // if size is 1, it's ok; return and we'll dup 00162 return toTree(singleElement); 00163 } 00164 // out of elements and size was not 1, so we can't dup 00165 throw new RewriteCardinalityException(elementDescription); 00166 } 00167 // we have elements 00168 if ( singleElement!=null ) { 00169 cursor++; // move cursor even for single element list 00170 return toTree(singleElement); 00171 } 00172 // must have more than one in list, pull from elements 00173 Object o = toTree(elements.get(cursor)); 00174 cursor++; 00175 return o; 00176 } 00177 00183 protected abstract Object dup(Object el); 00184 00188 protected Object toTree(Object el) { 00189 return el; 00190 } 00191 00192 public boolean hasNext() { 00193 return (singleElement != null && cursor < 1) || 00194 (elements!=null && cursor < elements.size()); 00195 } 00196 00197 public int size() { 00198 int n = 0; 00199 if ( singleElement != null ) { 00200 n = 1; 00201 } 00202 if ( elements!=null ) { 00203 return elements.size(); 00204 } 00205 return n; 00206 } 00207 00208 public String getDescription() { 00209 return elementDescription; 00210 } 00211 }
1.5.5