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; 00029 00030 import java.util.ArrayList; 00031 import java.util.List; 00032 00037 public class ANTLRStringStream implements CharStream { 00039 protected char[] data; 00040 00042 protected int n; 00043 00045 protected int p=0; 00046 00048 protected int line = 1; 00049 00051 protected int charPositionInLine = 0; 00052 00054 protected int markDepth = 0; 00055 00061 protected List markers; 00062 00064 protected int lastMarker; 00065 00067 public String name; 00068 00069 public ANTLRStringStream() { 00070 } 00071 00073 public ANTLRStringStream(String input) { 00074 this(); 00075 this.data = input.toCharArray(); 00076 this.n = input.length(); 00077 } 00078 00080 public ANTLRStringStream(char[] data, int numberOfActualCharsInArray) { 00081 this(); 00082 this.data = data; 00083 this.n = numberOfActualCharsInArray; 00084 } 00085 00090 public void reset() { 00091 p = 0; 00092 line = 1; 00093 charPositionInLine = 0; 00094 markDepth = 0; 00095 } 00096 00097 public void consume() { 00098 //System.out.println("prev p="+p+", c="+(char)data[p]); 00099 if ( p < n ) { 00100 charPositionInLine++; 00101 if ( data[p]=='\n' ) { 00102 /* 00103 System.out.println("newline char found on line: "+line+ 00104 "@ pos="+charPositionInLine); 00105 */ 00106 line++; 00107 charPositionInLine=0; 00108 } 00109 p++; 00110 //System.out.println("p moves to "+p+" (c='"+(char)data[p]+"')"); 00111 } 00112 } 00113 00114 public int LA(int i) { 00115 if ( i==0 ) { 00116 return 0; // undefined 00117 } 00118 if ( i<0 ) { 00119 i++; // e.g., translate LA(-1) to use offset i=0; then data[p+0-1] 00120 if ( (p+i-1) < 0 ) { 00121 return CharStream.EOF; // invalid; no char before first char 00122 } 00123 } 00124 00125 if ( (p+i-1) >= n ) { 00126 //System.out.println("char LA("+i+")=EOF; p="+p); 00127 return CharStream.EOF; 00128 } 00129 //System.out.println("char LA("+i+")="+(char)data[p+i-1]+"; p="+p); 00130 //System.out.println("LA("+i+"); p="+p+" n="+n+" data.length="+data.length); 00131 return data[p+i-1]; 00132 } 00133 00134 public int LT(int i) { 00135 return LA(i); 00136 } 00137 00142 public int index() { 00143 return p; 00144 } 00145 00146 public int size() { 00147 return n; 00148 } 00149 00150 public int mark() { 00151 if ( markers==null ) { 00152 markers = new ArrayList(); 00153 markers.add(null); // depth 0 means no backtracking, leave blank 00154 } 00155 markDepth++; 00156 CharStreamState state = null; 00157 if ( markDepth>=markers.size() ) { 00158 state = new CharStreamState(); 00159 markers.add(state); 00160 } 00161 else { 00162 state = (CharStreamState)markers.get(markDepth); 00163 } 00164 state.p = p; 00165 state.line = line; 00166 state.charPositionInLine = charPositionInLine; 00167 lastMarker = markDepth; 00168 return markDepth; 00169 } 00170 00171 public void rewind(int m) { 00172 CharStreamState state = (CharStreamState)markers.get(m); 00173 // restore stream state 00174 seek(state.p); 00175 line = state.line; 00176 charPositionInLine = state.charPositionInLine; 00177 release(m); 00178 } 00179 00180 public void rewind() { 00181 rewind(lastMarker); 00182 } 00183 00184 public void release(int marker) { 00185 // unwind any other markers made after m and release m 00186 markDepth = marker; 00187 // release this marker 00188 markDepth--; 00189 } 00190 00194 public void seek(int index) { 00195 if ( index<=p ) { 00196 p = index; // just jump; don't update stream state (line, ...) 00197 return; 00198 } 00199 // seek forward, consume until p hits index 00200 while ( p<index ) { 00201 consume(); 00202 } 00203 } 00204 00205 public String substring(int start, int stop) { 00206 return new String(data,start,stop-start+1); 00207 } 00208 00209 public int getLine() { 00210 return line; 00211 } 00212 00213 public int getCharPositionInLine() { 00214 return charPositionInLine; 00215 } 00216 00217 public void setLine(int line) { 00218 this.line = line; 00219 } 00220 00221 public void setCharPositionInLine(int pos) { 00222 this.charPositionInLine = pos; 00223 } 00224 00225 public String getSourceName() { 00226 return name; 00227 } 00228 }
1.5.5