// Translated by Nina
// This source code is under public domain

package net.morilib.nina;
import java.util.ArrayList;
import java.util.List;

public  class DoubleQuoteTokenizer   {

	static class TokenException extends RuntimeException {
	}

	static abstract class Engine {

	abstract int step(java.io.Reader __rd,
			int  $c) throws java.io.IOException;

	abstract boolean accepted();

	abstract boolean execaction(int  $c);

	abstract boolean isend();

	}

	static class Continuation {

		private int STATE;
		private java.util.Stack<Integer> __sts =
				new java.util.Stack<Integer>();
		private java.util.Stack<Engine> __stk =
				new java.util.Stack<Engine>();

		Continuation(int s, java.util.Stack<Integer> sts,
				java.util.Stack<Engine> stk) {
			STATE = s;
			__sts = new java.util.Stack<Integer>();
			__stk = new java.util.Stack<Engine>();
			__sts.addAll(sts);
			__stk.addAll(stk);
		}

	}

	static final int INITIAL = 0;

	private int STATE;
	private java.util.Stack<Integer> __sts =
			new java.util.Stack<Integer>();
	private java.util.Stack<Engine> __stk =
			new java.util.Stack<Engine>();

	private int unread = -1;
	private int gotoSymbol = -1;
	private int[] __backtrack = null;
	private int __backtrack_ptr = -1;
	private int __backtrack_len = -1;
	private int __backtrack_wptr = -1;
	private int __backtrack_sym = -1;
	private int[] __backtrack_state = null;
	private int[] __backtrack_wsym = null;
	private int[] __backtrack_ptrs = null;
	private Continuation[] __backtrack_cont = null;
	private int __backtrack_sptr = -1;
	private boolean __backtrack_flg = false;
	private int __lookahead_state;
	private int[] __lookahead = null;
	private int __lookahead_ptr = -1;
	private int[] __lookaheadw = null;
	private int __lookaheadw_ptr = -1;
	private boolean __lookahead_ok = true;

public static class Elems {

	private String string, lookahead, regex;
	private boolean invertLookahead;

	private Elems(String s, String l, String r, boolean j) {
		string = s;
		lookahead = l;
		regex = r;
		invertLookahead = j;
	}

	public String getString() {
		return string;
	}

	public String getLookahead() {
		return lookahead;
	}

	public String getRegex() {
		return regex;
	}

	public boolean isInvertLookahead() {
		return invertLookahead;
	}

}

private boolean invl = false;
private StringBuffer buf = new StringBuffer();
private StringBuffer lok = null;
private List<Elems> list = new ArrayList<Elems>();
private String regex;

private void _adds() {
	if(invl && lok.length() == 0) {
		invl = false;
		lok.append('!');
	}

	if(buf.length() > 0) {
		list.add(new Elems(buf.toString(),
				(lok != null && regex == null) ? lok.toString() : null,
				regex, invl));
		buf = new StringBuffer();
		lok = null;
		invl = false;
	}
}

public static List<Elems> parse(String s) {
	DoubleQuoteTokenizer a = new DoubleQuoteTokenizer();

	try {
		a.parse(new java.io.StringReader(s));
		a._adds();
		return a.list;
	} catch(java.io.IOException e) {
		throw new RuntimeException(e);
	}
}


	private int _read(java.io.Reader rd) throws java.io.IOException {
		int c;

		if(__backtrack_sym >= 0) {
			c = __backtrack_sym;
			__backtrack_sym = -1;
		} else if(gotoSymbol >= 0) {
			c = gotoSymbol;
			gotoSymbol = -1;
		} else if(unread >= 0) {
			c = unread;
			unread = -1;
		} else if(__lookahead_ptr >= 0) {
			if(__lookahead_ptr < __lookahead.length) {
				c = __lookahead[__lookahead_ptr++];
			} else {
				__lookahead = null;
				__lookahead_ptr = -1;
				c = _read(rd);
			}
		} else if(__backtrack_ptr >= 0) {
			if(__backtrack_ptr < __backtrack_len) {
				c = __backtrack[__backtrack_ptr++];
			} else {
				__backtrack = null;
				__backtrack_ptr = __backtrack_wptr = -1;
				c = _read(rd);
			}
		} else if((c = rd.read()) >= 0) {
			__write_backtrack(c);
		}
		return c;
	}

	private void UNGET(int c) {
		unread = c;
	}

	private void __write_backtrack(int c) {
		int[] a;

		if(__backtrack_wptr < 0) {
			// do nothing
		} else if(__backtrack_wptr < __backtrack.length) {
			__backtrack[__backtrack_wptr++] = c;
		} else {
			a = new int[__backtrack.length * 2];
			System.arraycopy(__backtrack, 0, a, 0,
					__backtrack.length);
			__backtrack = a;
			__backtrack[__backtrack_wptr++] = c;
		}
	}

	private boolean BACKTRACK(int c) {
		if(__backtrack_wptr >= 0) {
			__backtrack_len = __backtrack_wptr;
			__backtrack_wptr = -1;
			__backtrack_sptr--;
			STATE = __backtrack_state[__backtrack_sptr];
			__backtrack_ptr = __backtrack_ptrs[__backtrack_sptr];
			__backtrack_sym = __backtrack_wsym[__backtrack_sptr];
			SETCC(__backtrack_cont[__backtrack_sptr]);
			return true;
		} else {
			return false;
		}
	}

	private void LOOKAHEAD(int c) {
		int[] a;

		if(__lookaheadw == null) {
			__lookahead_state = STATE;
			__lookaheadw = new int[72];
			__lookaheadw_ptr = 0;
			__lookaheadw[__lookaheadw_ptr++] = c;
		} else if(__lookaheadw_ptr < __lookaheadw.length) {
			__lookaheadw[__lookaheadw_ptr++] = c;
		} else {
			a = new int[__lookaheadw.length * 2];
			System.arraycopy(__lookaheadw, 0, a, 0,
					__lookaheadw.length);
			__lookaheadw = a;
			__lookaheadw[__lookaheadw_ptr++] = c;
		}
	}

	private void __copy_lookahead(int p) {
		int[] a;

		if(__lookahead == null) {
			a = new int[__lookaheadw_ptr];
		} else if(__lookaheadw_ptr < __lookahead.length) {
			a = __lookahead;
		} else {
			a = new int[__lookaheadw_ptr];
		}
		System.arraycopy(__lookaheadw, 0, a, 0, __lookaheadw_ptr);
		__lookahead = a;
		__lookahead_ptr = p;
		__lookaheadw = null;
		__lookaheadw_ptr = -1;
	}

	private void LOOKAHEAD_RB() {
		__copy_lookahead(0);
		STATE = __lookahead_state;
		__lookahead_ok = false;
	}

	private void SETCC(Continuation c) {
		STATE = c.STATE;
		__sts = new java.util.Stack<Integer>();
		__stk = new java.util.Stack<Engine>();
		__sts.addAll(c.__sts);
		__stk.addAll(c.__stk);
	}


	private int doubleQuoteTokenizer_step(java.io.Reader __rd,
			int  $c) throws java.io.IOException {
		boolean __g = __lookahead_ok;

		__lookahead_ok = true;
		switch(STATE) {
		case 0:
			if(__g && $c == '\\') {
				STATE = 1;
				return 1;
			} else {
				STATE = 2;
				return 1;
			}
		case 2:
			if(__g && $c == '/') {
				STATE = 3;
				return 1;
			} else if(__g && $c == '\\') {
				STATE = 1;
				return 1;
			} else if(__g && $c == '|') {
				STATE = 4;
				return 1;
			} else {
				STATE = 2;
				return 1;
			}
		case 4:
			STATE = 2;
			return 1;
		case 3:
			if(__g && $c == '!') {
				STATE = 5;
				return 1;
			} else if(__g && $c == '\\') {
				STATE = 6;
				return 1;
			} else if(__g && $c == '`') {
				STATE = 7;
				return 1;
			} else {
				STATE = 8;
				return 1;
			}
		case 8:
			if(__g && $c == '\\') {
				STATE = 6;
				return 1;
			} else if(__g && $c == '|') {
				STATE = 4;
				return 1;
			} else {
				STATE = 8;
				return 1;
			}
		case 7:
			if(__g && $c == '`') {
				STATE = 9;
				return 1;
			} else {
				STATE = 7;
				return 1;
			}
		case 9:
			lok.append('`');  regex = null;
			STATE = 7;
			return 1;
		case 6:
			if(__g && $c == '|') {
				STATE = 8;
				return 1;
			} else {
				lok.append('\\');
				STATE = 8;
				return 1;
			}
		case 5:
			STATE = 8;
			return 1;
		case 1:
			if(__g && $c == '/') {
				STATE = 2;
				return 1;
			} else if(__g && $c == '|') {
				STATE = 2;
				return 1;
			} else {
				buf.append('\\');
				STATE = 2;
				return 1;
			}
		}
		return 0;
	}
	private boolean doubleQuoteTokenizer_accepted() {
		return (STATE == 0 ||
				STATE == 1 ||
				STATE == 2 ||
				STATE == 3 ||
				STATE == 4 ||
				STATE == 5 ||
				STATE == 6 ||
				STATE == 7 ||
				STATE == 8 ||
				STATE == 9);
	}

	private boolean doubleQuoteTokenizer_execaction(int  $c) {
		switch(STATE) {
		case 0:
			break;
		case 9:
			regex = lok.substring(1);
			break;
		case 7:
			lok.appendCodePoint($c);
			break;
		case 4:
			_adds();
			break;
		case 2:
			buf.appendCodePoint($c);
			break;
		case 8:
			lok.appendCodePoint($c);
			break;
		case 5:
			invl = true;
			break;
		case 1:
			break;
		case 6:
			break;
		case 3:
			lok = new StringBuffer();
			break;
		}
		return true;
	}

	private boolean doubleQuoteTokenizer_isend() {
		return false;
	}

	private final Engine ENGINE_doubleQuoteTokenizer = new Engine() {

		int step(java.io.Reader __rd,
				int c) throws java.io.IOException {
			return doubleQuoteTokenizer_step(__rd, c);
		}

		boolean accepted() {
			return doubleQuoteTokenizer_accepted();
		}

		boolean execaction(int c) {
			return doubleQuoteTokenizer_execaction(c);
		}

		boolean isend() {
			return doubleQuoteTokenizer_isend();
		}

		public String toString() {
			return "doubleQuoteTokenizer";
		}

	};

	private int _parse(java.io.Reader rd,
			int x) throws java.io.IOException {
		boolean b = false;
		int c = x, a;
		Engine en;

		b = __stk.peek().accepted();
		if(rd == null) {
			throw new RuntimeException("can not recurse");
		} else if(!__stk.peek().execaction(-2)) {
			if(!b)  throw new TokenException();
		}

		do {
			en = __stk.peek();
			if(c < 0) {
				// do nothing
			} else if((a = en.step(rd, c)) > 0) {
				b = en.accepted();
				if(!en.execaction(c))  break;
				if(__backtrack_flg) {
					__write_backtrack(c);
					__backtrack_flg = false;
				}
			} else if(a < 0) {
				return c;
			} else if(b) {
				UNGET(c);
				return -1;
			} else if(__lookaheadw_ptr >= 0) {
				LOOKAHEAD(c);
				LOOKAHEAD_RB();
				b = en.accepted();
			} else {
				if(!BACKTRACK(c)) {
					throw new TokenException();
				}
			}
		} while((c = _read(rd)) >= 0);
		if(!b)  throw new TokenException();
		return -1;
	}

	private boolean parse(
			java.io.Reader rd) throws java.io.IOException {
		int c = -1;

		__stk.push(ENGINE_doubleQuoteTokenizer);
		while(true) {
			if((c = _parse(rd, c)) >= 0) {
				// do nothing
			} else if(__stk.size() > 1) {
				__stk.pop();
				STATE = __sts.pop();
			} else {
				break;
			}
		}
		return __stk.peek().accepted();
	}

}
