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