1 package ch.qos.logback.core.pattern.parser;
2
3 import java.util.List;
4 import java.util.Map;
5
6 import ch.qos.logback.core.pattern.Converter;
7 import ch.qos.logback.core.pattern.FormatInfo;
8 import ch.qos.logback.core.pattern.util.IEscapeUtil;
9 import ch.qos.logback.core.pattern.util.RegularEscapeUtil;
10 import ch.qos.logback.core.spi.ContextAwareBase;
11
12
13 public class Parser<E> extends ContextAwareBase {
14
15 final List tokenList;
16 int pointer = 0;
17 IEscapeUtil escapeUtil;
18
19 Parser(TokenStream ts) throws ScanException {
20 this.tokenList = ts.tokenize();
21 }
22
23
24 public Parser(String pattern) throws ScanException {
25 this(pattern, new RegularEscapeUtil());
26 }
27
28 public Parser(String pattern, IEscapeUtil escapeUtil) throws ScanException {
29 this.escapeUtil = escapeUtil;
30 try {
31 TokenStream ts = new TokenStream(pattern, escapeUtil);
32 this.tokenList = ts.tokenize();
33 } catch (NullPointerException npe) {
34 throw new ScanException("Failed to initialize Parser", npe);
35 }
36 }
37
38 public Node parse() throws ScanException {
39 return E();
40 }
41
42
43
44
45
46
47
48
49
50
51 public Converter<E> compile(final Node top, Map converterMap) {
52 Compiler<E> compiler = new Compiler<E>(top, converterMap);
53 compiler.setContext(context);
54
55 return compiler.compile();
56 }
57
58 Node E() throws ScanException {
59
60 Node t = T();
61 if (t == null) {
62 return null;
63 }
64 Node eOpt = Eopt();
65 if (eOpt != null) {
66
67 t.setNext(eOpt);
68 }
69 return t;
70 }
71
72 Node T() throws ScanException {
73
74 Token t = getCurentToken();
75 if (t == null) {
76 throw new IllegalStateException("a LITERAL or '%'");
77 }
78
79
80
81 switch (t.getType()) {
82 case Token.LITERAL:
83 advanceTokenPointer();
84 return new Node(Node.LITERAL, t.getValue());
85 case Token.PERCENT:
86 advanceTokenPointer();
87
88 FormatInfo fi;
89 Token u = getCurentToken();
90 FormattingNode c;
91 expectNotNull(u, "a FORMAT_MODIFIER, KEYWORD or LEFT_PARENTHESIS");
92 if (u.getType() == Token.FORMAT_MODIFIER) {
93 fi = FormatInfo.valueOf((String) u.getValue());
94 advanceTokenPointer();
95 c = C();
96 c.setFormatInfo(fi);
97 } else {
98 c = C();
99 }
100 return c;
101
102 default:
103 return null;
104
105 }
106
107 }
108
109 Node Eopt() throws ScanException {
110
111 Token next = getCurentToken();
112
113 if (next == null) {
114 return null;
115 } else {
116 return E();
117 }
118 }
119
120 FormattingNode C() throws ScanException {
121 Token t = getCurentToken();
122
123
124 expectNotNull(t, "a LEFT_PARENTHESIS or KEYWORD");
125 int type = t.getType();
126 switch (type) {
127 case Token.KEYWORD:
128 return SINGLE();
129 case Token.LEFT_PARENTHESIS:
130 advanceTokenPointer();
131 return COMPOSITE();
132 default:
133 throw new IllegalStateException("Unexpected token " + t);
134 }
135 }
136
137 FormattingNode SINGLE() throws ScanException {
138
139 Token t = getNextToken();
140
141 KeywordNode keywordNode = new KeywordNode(t.getValue());
142
143 Token ot = getCurentToken();
144 if (ot != null && ot.getType() == Token.OPTION) {
145 List optionList = new OptionTokenizer((String) ot.getValue()).tokenize();
146 keywordNode.setOptions(optionList);
147 advanceTokenPointer();
148 }
149 return keywordNode;
150 }
151
152 FormattingNode COMPOSITE() throws ScanException {
153 CompositeNode compositeNode = new CompositeNode();
154
155 Node childNode = E();
156
157
158 compositeNode.setChildNode(childNode);
159
160 Token t = getNextToken();
161
162
163 if (t.getType() != Token.RIGHT_PARENTHESIS) {
164 throw new IllegalStateException(
165 "Expecting RIGHT_PARENTHESIS token but got " + t);
166 } else {
167
168 }
169 return compositeNode;
170 }
171
172 Token getNextToken() {
173 if (pointer < tokenList.size()) {
174 return (Token) tokenList.get(pointer++);
175 }
176 return null;
177 }
178
179 Token getCurentToken() {
180 if (pointer < tokenList.size()) {
181 return (Token) tokenList.get(pointer);
182 }
183 return null;
184 }
185
186 void advanceTokenPointer() {
187 pointer++;
188 }
189
190 void expectNotNull(Token t, String expected) {
191 if (t == null) {
192 throw new IllegalStateException("All tokens consumed but was expecting "
193 + expected);
194 }
195 }
196
197
198
199
200 }