view src/plparser/PropertyListCharTokenizer.java @ 10:0d74081c1309

Char loop tokenizer worked.
author one
date Thu, 02 Sep 2010 10:52:44 +0900
parents 29e309b2f624
children 79d492bce828
line wrap: on
line source

package plparser;

import java.io.FileNotFoundException;
import java.io.InputStream;
import java.nio.CharBuffer;

public class PropertyListCharTokenizer<T> extends PropertyListScanner<T>
implements PLScanner<T> {

	public PropertyListCharTokenizer(Dictionary<T> dict) {
		super(dict);
	}

	public PropertyListCharTokenizer(
			PLScanner<T>s,
			Dictionary<T> dict, Token<T> nullToken) {
		super(dict);
		this.prev = s;
		this.nullToken = nullToken;
	}

	public char ch;

	@Override
	public Token<T> nextToken() {
		nextToken = nullToken;
		if (cb==null) return nextToken;
		while(true) {
			if (!hasRemaining()) return nextToken;
			while(Character.isSpaceChar(ch)) {
				if (!hasRemaining()) return nextToken;
				ch = nextChar(); 
			}
			CharBuffer w = CharBuffer.allocate(BufferSize);
			if (Character.isJavaIdentifierStart(ch)) {
				w.put(ch);
				while(hasRemaining()&&Character.isJavaIdentifierPart((ch=nextChar()))) {
					w.put(ch);
				}
				return lookupDict(w);
			} else if (Character.isDigit(ch)) { // should handle more complex case
				w.put(ch);
				while(hasRemaining()&&Character.isDigit((ch=nextChar()))) {
					w.put(ch);
				}
				return nextToken = new Token<T>(w.flip().toString(),TokenID.NUMBER);
			} 
			switch(ch) {
			case '/':
				w.put(ch); 	
				if (!hasRemaining()) return new Token<T>(w.flip().toString(),TokenID.Any);
				ch = nextChar();
				if (ch=='/') {
					while(hasRemaining() && (ch=nextChar())!='\n');
					if (!hasRemaining())return nullToken;
					ch = nextChar();
					continue;
				}
				if (ch=='*') {
					while(hasRemaining() && !((ch=nextChar())=='*'&&(ch=nextChar())=='/'));
					if (!hasRemaining())return nullToken;
					ch = nextChar();
					continue;
				}
				return new Token<T>(w.flip().toString(),TokenID.Any);
			case '\'':   // should handle '\'' case
			case '"':				
				char d = ch;
				while(hasRemaining() && (ch=nextChar())!=d) w.put(ch);
				if (!hasRemaining())return nullToken; // non terminate string
				ch = nextChar();
				Token<T> t = lookupDict(w);
				if (t.type!=TokenID.VARIABLE) {
					t = new Token<T>(t.name,TokenID.VARIABLE);
				}
				return nextToken = t;
			case '{': case '}': case '(': case ')': case '=': case ',': case ';': 
				w.put(ch); 	
				nextToken = lookupDict(w);
				if (!hasRemaining())return nextToken; 
				ch = nextChar();
				return nextToken;
			default:
				ch = nextChar();
				continue;
			}
		}
	}

	private Token<T> lookupDict(CharBuffer w) {
		Token<T> t;
		String s = w.flip().toString();
		if ((t = dict.get(s))==null) {
			dict.put(s, t = new Token<T>(s,TokenID.Any));
		}
		return nextToken = t;
	}

	private char nextChar() {
		if (!cb.hasRemaining()) extendInput();
		char ch = cb.get();
		if (ch=='\n') lineno++;
		return ch;
	}


	@Override
	public PLScanner<T> pushScannerFile(InputStream newfile, String prompt) {
		return new PropertyListCharTokenizer<T>(this,dict,nullToken).setFile(newfile,prompt);
	}

	@Override
	public PLScanner<T> pushScanner(String exp) {
		return new PropertyListCharTokenizer<T>(this,dict,nullToken).set(exp);
	}

	@Override
	public PLScanner<T> pushScannerFile(String newfile)
	throws FileNotFoundException {
		return new PropertyListCharTokenizer<T>(this,dict,nullToken).setFile(newfile);
	}
}