![JAR search and dependency download from the Maven repository](/logo.png)
org.zkoss.zk.ui.select.impl.Parser Maven / Gradle / Ivy
/**
*
*/
package org.zkoss.zk.ui.select.impl;
import java.util.LinkedList;
import java.util.List;
import org.zkoss.fsm.MacroStateCtx;
import org.zkoss.fsm.StateCtx.TransitionListener;
import org.zkoss.fsm.StateMachine;
import org.zkoss.fsm.StateMachine.StateMachineException;
import org.zkoss.zk.ui.select.impl.InSeqMachine.SubState;
import org.zkoss.zk.ui.select.impl.Selector.Combinator;
import org.zkoss.zk.ui.select.impl.Token.Type;
/**
* A parser that parses selector string and generates selector objects.
* @since 6.0.0
* @author simonpai
*/
public class Parser {
private String _source;
private List _selectorSet = new LinkedList(); //to preserve order
private Selector _selector;
private InSeqMachine _submachine;
private StateMachine _machine = new StateMachine() {
protected void init() {
getState(State.PRE_SELECTOR).addReturningClasses(CharClass.WHITESPACE)
.addTransition(CharClass.SELECTOR_LITERAL, State.IN_SELECTOR);
setState(State.IN_SELECTOR,
new MacroStateCtx(_submachine = new InSeqMachine()))
.addReturningClasses(CharClass.SELECTOR_LITERAL)
.addTransition(CharClass.WHITESPACE, State.PRE_COMBINATOR)
.addTransition(CharClass.SELECTOR_SEPARATOR, State.PRE_SELECTOR,
new TransitionListener() {
public void onTransit(Token input, CharClass inputClass) {
flushCurrentSelector();
}
});
getState(State.PRE_COMBINATOR).addTransition(CharClass.COMBINATOR, State.POST_COMBINATOR,
new TransitionListener() {
public void onTransit(Token input, CharClass inputClass) {
_selector.attachCombinator(getCombinator(input));
}
}).addTransition(CharClass.SELECTOR_LITERAL, State.IN_SELECTOR).addTransition(CharClass.SELECTOR_SEPARATOR,
State.PRE_SELECTOR, new TransitionListener() {
public void onTransit(Token input, CharClass inputClass) {
flushCurrentSelector();
}
});
getState(State.POST_COMBINATOR).addTransition(CharClass.WHITESPACE, State.PRE_SELECTOR);
}
protected CharClass getClass(Token input) {
switch (input.getType()) {
case WHITESPACE:
return CharClass.WHITESPACE;
case CBN_CHILD:
case CBN_ADJACENT_SIBLING:
case CBN_GENERAL_SIBLING:
return CharClass.COMBINATOR;
case SELECTOR_SEPARATOR:
return CharClass.SELECTOR_SEPARATOR;
default:
return CharClass.SELECTOR_LITERAL;
}
}
protected State getLandingState(Token input, CharClass inputClass) {
switch (inputClass) {
case WHITESPACE:
return State.PRE_SELECTOR;
case SELECTOR_LITERAL:
return State.IN_SELECTOR;
}
return null;
}
protected void onReset() {
_submachine.setSelector(_selector);
_submachine.setSource(_source);
}
protected void onStop(boolean endOfInput) {
// TODO: check state?
}
private void flushCurrentSelector() {
// flush current selector
_selectorSet.add(_selector = new Selector(_selectorSet.size()));
_submachine.setSelector(_selector);
}
};
public List parse(String source) {
try {
return parse(new Tokenizer().tokenize(source), source);
} catch (StateMachineException e) {
throw new ParseException("Illegal selector string: " + source);
}
}
public List parse(List tokens, String source) {
_source = source;
_selectorSet.clear();
_selectorSet.add(_selector = new Selector(0));
_machine.start(tokens.iterator());
return _selectorSet;
}
public void setDebugMode(boolean mode) {
_machine.setDebugMode(mode);
_submachine.setDebugMode(mode);
}
// state, char class //
private enum State {
PRE_SELECTOR, IN_SELECTOR, PRE_COMBINATOR, POST_COMBINATOR;
}
private enum CharClass {
SELECTOR_LITERAL, WHITESPACE, COMBINATOR, SELECTOR_SEPARATOR;
}
// helper //
private Combinator getCombinator(Token token) {
switch (token.getType()) {
case CBN_CHILD:
return Combinator.CHILD;
case CBN_ADJACENT_SIBLING:
return Combinator.ADJACENT_SIBLING;
case CBN_GENERAL_SIBLING:
return Combinator.GENERAL_SIBLING;
}
throw new IllegalStateException();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy