package ch.qos.logback.core.pattern.parser;
import java.util.List;
import java.util.Map;
import ch.qos.logback.core.pattern.Converter;
import ch.qos.logback.core.pattern.FormatInfo;
import ch.qos.logback.core.pattern.util.IEscapeUtil;
import ch.qos.logback.core.pattern.util.RegularEscapeUtil;
import ch.qos.logback.core.spi.ContextAwareBase;
public class Parser<E> extends ContextAwareBase {
final List tokenList;
int pointer = 0;
IEscapeUtil escapeUtil;
Parser(TokenStream ts) throws ScanException {
this.tokenList = ts.tokenize();
}
// this variant should be used for testing purposes only
public Parser(String pattern) throws ScanException {
this(pattern, new RegularEscapeUtil());
}
public Parser(String pattern, IEscapeUtil escapeUtil) throws ScanException {
this.escapeUtil = escapeUtil;
try {
TokenStream ts = new TokenStream(pattern, escapeUtil);
this.tokenList = ts.tokenize();
} catch (NullPointerException npe) {
throw new ScanException("Failed to initialize Parser", npe);
}
}
public Node parse() throws ScanException {
return E();
}
/**
* When the parsing step is done, the Node list can be transformed into a
* converter chain.
*
* @param top
* @param converterMap
* @return
* @throws ScanException
*/
public Converter<E> compile(final Node top, Map converterMap) {
Compiler<E> compiler = new Compiler<E>(top, converterMap);
compiler.setContext(context);
//compiler.setStatusManager(statusManager);
return compiler.compile();
}
Node E() throws ScanException {
// System.out.println("in E()");
Node t = T();
if (t == null) {
return null;
}
Node eOpt = Eopt();
if (eOpt != null) {
// System.out.println("setting next node to " + eOpt);
t.setNext(eOpt);
}
return t;
}
Node T() throws ScanException {
// System.out.println("in T()");
Token t = getCurentToken();
if (t == null) {
throw new IllegalStateException("a LITERAL or '%'");
}
// System.out.println("Current token is " + t);
switch (t.getType()) {
case Token.LITERAL:
advanceTokenPointer();
return new Node(Node.LITERAL, t.getValue());
case Token.PERCENT:
advanceTokenPointer();
// System.out.println("% token found");
FormatInfo fi;
Token u = getCurentToken();
FormattingNode c;
expectNotNull(u, "a FORMAT_MODIFIER, KEYWORD or LEFT_PARENTHESIS");
if (u.getType() == Token.FORMAT_MODIFIER) {
fi = FormatInfo.valueOf((String) u.getValue());
advanceTokenPointer();
c = C();
c.setFormatInfo(fi);
} else {
c = C();
}
return c;
default:
return null;
}
}
Node Eopt() throws ScanException {
// System.out.println("in Eopt()");
Token next = getCurentToken();
// System.out.println("Current token is " + next);
if (next == null) {
return null;
} else {
return E();
}
}
FormattingNode C() throws ScanException {
Token t = getCurentToken();
// System.out.println("in C()");
// System.out.println("Current token is " + t);
expectNotNull(t, "a LEFT_PARENTHESIS or KEYWORD");
int type = t.getType();
switch (type) {
case Token.KEYWORD:
return SINGLE();
case Token.LEFT_PARENTHESIS:
advanceTokenPointer();
return COMPOSITE();
default:
throw new IllegalStateException("Unexpected token " + t);
}
}
FormattingNode SINGLE() throws ScanException {
// System.out.println("in SINGLE()");
Token t = getNextToken();
// System.out.println("==" + t);
KeywordNode keywordNode = new KeywordNode(t.getValue());
Token ot = getCurentToken();
if (ot != null && ot.getType() == Token.OPTION) {
List optionList = new OptionTokenizer((String) ot.getValue()).tokenize();
keywordNode.setOptions(optionList);
advanceTokenPointer();
}
return keywordNode;
}
FormattingNode COMPOSITE() throws ScanException {
CompositeNode compositeNode = new CompositeNode();
Node childNode = E();
// System.out.println("Child node: " + childNode);
compositeNode.setChildNode(childNode);
Token t = getNextToken();
// System.out.println("Next token is" + t);
if (t.getType() != Token.RIGHT_PARENTHESIS) {
throw new IllegalStateException(
"Expecting RIGHT_PARENTHESIS token but got " + t);
} else {
// System.out.println("got expected ')'");
}
return compositeNode;
}
Token getNextToken() {
if (pointer < tokenList.size()) {
return (Token) tokenList.get(pointer++);
}
return null;
}
Token getCurentToken() {
if (pointer < tokenList.size()) {
return (Token) tokenList.get(pointer);
}
return null;
}
void advanceTokenPointer() {
pointer++;
}
void expectNotNull(Token t, String expected) {
if (t == null) {
throw new IllegalStateException("All tokens consumed but was expecting "
+ expected);
}
}
// public void setStatusManager(StatusManager statusManager) {
// this.statusManager = statusManager;
// }
}