1	package antlr;
2	
3	/**
4	 * <b>SOFTWARE RIGHTS</b>
5	 * <p>
6	 * ANTLR 2.5.0 MageLang Institute, 1998
7	 * <p>
8	 * We reserve no legal rights to the ANTLR--it is fully in the
9	 * public domain. An individual or company may do whatever
10	 * they wish with source code distributed with ANTLR or the
11	 * code generated by ANTLR, including the incorporation of
12	 * ANTLR, or its output, into commerical software.
13	 * <p>
14	 * We encourage users to develop software with ANTLR. However,
15	 * we do ask that credit is given to us for developing
16	 * ANTLR. By "credit", we mean that if you use ANTLR or
17	 * incorporate any source code into one of your programs
18	 * (commercial product, research project, or otherwise) that
19	 * you acknowledge this fact somewhere in the documentation,
20	 * research report, etc... If you like ANTLR and have
21	 * developed a nice tool with the output, please mention that
22	 * you developed it using ANTLR. In addition, we ask that the
23	 * headers remain intact in our source code. As long as these
24	 * guidelines are kept, we expect to continue enhancing this
25	 * system and expect to make other tools available as they are
26	 * completed.
27	 * <p>
28	 * The ANTLR gang:
29	 * @version ANTLR 2.5.0 MageLang Institute, 1998
30	 * @author Terence Parr, <a href=http://www.MageLang.com>MageLang Institute</a>
31	 * @author <br>John Lilley, <a href=http://www.Empathy.com>Empathy Software</a>
32	 */
33	import java.util.Hashtable;
34	import antlr.collections.impl.BitSet;
35	import java.io.IOException;
36	
37	public abstract class CharScanner implements Tokenizer {
38		static final char NO_CHAR = 0;
39		public static final char EOF_CHAR = (char)-1;
40		protected int line = 1;						// current line number
41		protected ANTLRStringBuffer text;			// text of current token
42		protected boolean saveConsumedInput = true;	// does consume() save characters?
43		protected Class tokenObjectClass;			// what kind of tokens to create?
44		protected int guessing = 0;
45		protected boolean caseSensitive = true;
46		protected boolean caseSensitiveLiterals = true;
47		protected Hashtable literals;				// set by subclass
48		
49		protected Token _returnToken = null;		// used to return tokens w/o using return val.
50	
51		// Hash string used so we don't new one every time to check literals table
52		protected ANTLRHashString hashString;
53	
54		// Input chars
55		InputBuffer input;
56	
57		/** Used during filter mode to indicate that path is desired.
58		 *  A subsequent scan error will report an error as usual if acceptPath=true;
59		 */
60		protected boolean commitToPath = false;
61	
62	public CharScanner(InputBuffer cb) { // SAS: use generic buffer
63		text = new ANTLRStringBuffer();
64		hashString = new ANTLRHashString(this);
65		setTokenObjectClass("antlr.CommonToken");
66		input = cb;
67	}
68	public void append(char c) {
69		if ( saveConsumedInput ) {
70			text.append(c);
71		}	
72	}
73	public void append(String s) {
74		if ( saveConsumedInput ) {
75			text.append(s);
76		}	
77	}
78		public void commit() {
79			input.commit();
80		}
81	public void consume() throws IOException {
82		if (guessing == 0) {
83			if (caseSensitive) {
84				append(LA(1));
85			} else {
86				// use input.LA(), not LA(), to get original case
87				// CharScanner.LA() would toLower it.
88				append(input.LA(1));
89			}
90		}
91		input.consume();
92	}
93		/** Consume chars until one matches the given char */
94		public void consumeUntil(int c) throws IOException {
95			while (LA(1) != EOF_CHAR && LA(1) != c)
96			{
97				consume();
98			}
99		}
100		/** Consume chars until one matches the given set */
101		public void consumeUntil(BitSet set) throws IOException {
102			while (LA(1) != EOF_CHAR && !set.member(LA(1))) {
103				consume();
104			}
105		}
106		public boolean getCaseSensitive() { return caseSensitive; }
107		public final boolean getCaseSensitiveLiterals() { return caseSensitiveLiterals; }
108		public boolean getCommitToPath() { return commitToPath; }
109		public InputBuffer getInputBuffer() {
110			return input;
111		}
112		public int getLine() { return line; }
113		// return a copy of the current text buffer
114		public String getText() {
115			return text.toString();
116		}
117		public Token getTokenObject() {
118			return _returnToken;
119		}
120	public char LA(int i) throws IOException {
121		if (caseSensitive) {
122			return input.LA(i);
123		} else {
124			return toLower(input.LA(i));
125		}
126	}
127		protected Token makeToken(int t) {
128			try {
129				Token tok = (Token)tokenObjectClass.newInstance();
130				tok.setType(t);
131				// tok.setText(getText()); done in generated lexer now
132				tok.setLine(line);
133				return tok;
134			}
135			catch (InstantiationException ie) {
136				panic("can't instantiate a Token");
137			}
138			catch (IllegalAccessException iae) {
139				panic("Token class is not accessible");
140			}
141			return Token.badToken;
142		}
143		public int mark() {
144			return input.mark();
145		}
146		public void match(char c) throws ScannerException, IOException {
147			if ( LA(1) != c ) {
148				throw new ScannerException("mismatched char: '" + LA(1) + "' expected '"+c+"'", line);
149			}
150			consume();
151		}
152		public void match(BitSet b) throws ScannerException, IOException {
153			if ( !b.member(LA(1)) ) {
154				throw new ScannerException("mismatched char: '" + LA(1) + "'", line);
155			} else {
156				consume();
157			}
158		}
159		public void match(String s) throws ScannerException, IOException {
160			int len = s.length();
161			for (int i=0; i<len; i++) {
162				if ( LA(1) != s.charAt(i) ) {
163					throw new ScannerException("mismatched char: '" + LA(1) + "'", line);
164				}
165				consume();
166			}
167		}
168		public void matchNot(char c) throws ScannerException, IOException {
169			if ( LA(1) == c ) {
170				throw new ScannerException("mismatched char: '"+ LA(1) + "'", line);
171			}
172			consume();
173		}
174		public void matchRange(char c1, char c2) throws ScannerException, IOException {
175			if ( LA(1) < c1 || LA(1) > c2 ) throw new ScannerException("char out of range: '" + LA(1) + "'", line);
176			consume();
177		}
178		public void newline() { line++; }
179		public void panic() {
180			System.err.println("CharScanner: panic");
181			System.exit(1);
182		}
183		public void panic(String s) {
184			System.err.println("CharScanner; panic: "+s);
185			System.exit(1);
186		}
187		/** Report exception errors caught in nextToken() */
188		public void reportError(ScannerException e) {
189			System.err.println("Scanner exception: " + e);
190		}
191		/** Parser error-reporting function can be overridden in subclass */
192		public void reportError(String s) {
193			System.err.println("Error: " + s);
194		}
195		/** Parser warning-reporting function can be overridden in subclass */
196		public void reportWarning(String s) {
197			System.out.println("Warning: " + s);
198		}
199		public void resetText() {
200			text.setLength(0);
201		}
202		public void rewind(int pos) {
203			input.rewind(pos);
204		}
205		public void setCaseSensitive(boolean t) { caseSensitive = t; }
206		public void setCommitToPath(boolean commit) { commitToPath = commit; }
207		public void setLine(int line) { this.line = line; }
208		public void setText(String s) {
209			resetText();
210			text.append(s);
211		}
212		public void setTokenObjectClass(String cl) {
213			try {
214				tokenObjectClass = Class.forName(cl);
215			}
216			catch (ClassNotFoundException ce) {
217				panic("ClassNotFoundException: "+cl);
218			}
219		}
220		// Test the token text against the literals table
221		// Override this method to perform a different literals test
222		public int testLiteralsTable(int ttype) {
223			hashString.setBuffer(text.getBuffer(), text.length());
224			Integer literalsIndex = (Integer)literals.get(hashString);
225			if (literalsIndex != null) {
226				ttype = literalsIndex.intValue();
227			}
228			return ttype;
229		}
230		// Override this method to get more specific case handling
231		public char toLower(char c) {
232			return Character.toLowerCase(c);
233		}
234		public void traceIn(String rname) throws IOException {
235			System.out.println("enter lexer "+rname+"; c==" + LA(1));
236		}
237		public void traceOut(String rname) throws IOException {
238			System.out.println("exit lexer "+rname+"; c=='" + LA(1));
239		}
240	}
241