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