00001 /* 00002 [The "BSD license"] 00003 Copyright (c) 2005-2009 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 java.util.ArrayList; 00031 import java.util.List; 00032 00046 public abstract class RewriteRuleElementStream { 00050 protected int cursor = 0; 00051 00053 protected Object singleElement; 00054 00056 protected List elements; 00057 00068 protected boolean dirty = false; 00069 00074 protected String elementDescription; 00075 protected TreeAdaptor adaptor; 00076 00077 public RewriteRuleElementStream(TreeAdaptor adaptor, String elementDescription) { 00078 this.elementDescription = elementDescription; 00079 this.adaptor = adaptor; 00080 } 00081 00083 public RewriteRuleElementStream(TreeAdaptor adaptor, 00084 String elementDescription, 00085 Object oneElement) 00086 { 00087 this(adaptor, elementDescription); 00088 add(oneElement); 00089 } 00090 00092 public RewriteRuleElementStream(TreeAdaptor adaptor, 00093 String elementDescription, 00094 List elements) 00095 { 00096 this(adaptor, elementDescription); 00097 this.singleElement = null; 00098 this.elements = elements; 00099 } 00100 00106 public void reset() { 00107 cursor = 0; 00108 dirty = true; 00109 } 00110 00111 public void add(Object el) { 00112 //System.out.println("add '"+elementDescription+"' is "+el); 00113 if ( el==null ) { 00114 return; 00115 } 00116 if ( elements!=null ) { // if in list, just add 00117 elements.add(el); 00118 return; 00119 } 00120 if ( singleElement == null ) { // no elements yet, track w/o list 00121 singleElement = el; 00122 return; 00123 } 00124 // adding 2nd element, move to list 00125 elements = new ArrayList(5); 00126 elements.add(singleElement); 00127 singleElement = null; 00128 elements.add(el); 00129 } 00130 00136 public Object nextTree() { 00137 int n = size(); 00138 if ( dirty || (cursor>=n && n==1) ) { 00139 // if out of elements and size is 1, dup 00140 Object el = _next(); 00141 return dup(el); 00142 } 00143 // test size above then fetch 00144 Object el = _next(); 00145 return el; 00146 } 00147 00154 protected Object _next() { 00155 int n = size(); 00156 if ( n ==0 ) { 00157 throw new RewriteEmptyStreamException(elementDescription); 00158 } 00159 if ( cursor>= n) { // out of elements? 00160 if ( n ==1 ) { // if size is 1, it's ok; return and we'll dup 00161 return toTree(singleElement); 00162 } 00163 // out of elements and size was not 1, so we can't dup 00164 throw new RewriteCardinalityException(elementDescription); 00165 } 00166 // we have elements 00167 if ( singleElement!=null ) { 00168 cursor++; // move cursor even for single element list 00169 return toTree(singleElement); 00170 } 00171 // must have more than one in list, pull from elements 00172 Object o = toTree(elements.get(cursor)); 00173 cursor++; 00174 return o; 00175 } 00176 00182 protected abstract Object dup(Object el); 00183 00187 protected Object toTree(Object el) { 00188 return el; 00189 } 00190 00191 public boolean hasNext() { 00192 return (singleElement != null && cursor < 1) || 00193 (elements!=null && cursor < elements.size()); 00194 } 00195 00196 public int size() { 00197 int n = 0; 00198 if ( singleElement != null ) { 00199 n = 1; 00200 } 00201 if ( elements!=null ) { 00202 return elements.size(); 00203 } 00204 return n; 00205 } 00206 00207 public String getDescription() { 00208 return elementDescription; 00209 } 00210 }
1.5.5