1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 package name.angoca.db2sa.core.syntax;
30
31 import java.util.ArrayList;
32 import java.util.List;
33
34 import name.angoca.db2sa.Constants;
35 import name.angoca.db2sa.core.lexical.Token;
36 import name.angoca.db2sa.core.lexical.exceptions.InvalidTokenException;
37 import name.angoca.db2sa.core.syntax.graph.EndingToken;
38 import name.angoca.db2sa.core.syntax.graph.GraphConstructor;
39 import name.angoca.db2sa.core.syntax.graph.GraphToken;
40 import name.angoca.db2sa.core.syntax.graph.StartingToken;
41 import name.angoca.db2sa.core.syntax.graph.exception.InvalidGraphException;
42 import name.angoca.db2sa.messages.Messages;
43 import name.angoca.db2sa.readers.GrammarReader;
44
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47 import org.xml.sax.InputSource;
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76 public final class ImplSyntaxAnalyzer extends AbstractSyntacticalAnalyzer {
77
78
79
80
81 private static final Logger LOGGER = LoggerFactory
82 .getLogger(ImplSyntaxAnalyzer.class);
83
84
85
86
87 private static ImplSyntaxAnalyzer s_instance;
88
89
90
91
92
93 private StartingToken m_startingToken;
94
95
96
97
98
99
100
101 public ImplSyntaxAnalyzer() throws InvalidGraphException {
102 super();
103 final InputSource content = GrammarReader.read();
104 this.m_startingToken = GraphConstructor.build(content);
105 }
106
107
108
109
110
111
112
113
114
115 public static ImplSyntaxAnalyzer
116 throws InvalidGraphException {
117 synchronized (ImplSyntaxAnalyzer.class) {
118 if (ImplSyntaxAnalyzer.s_instance == null) {
119 ImplSyntaxAnalyzer.LOGGER
120 .debug("Creating ImplSyntaxAnalyzer instance.");
121 ImplSyntaxAnalyzer.s_instance = new ImplSyntaxAnalyzer();
122 }
123 }
124 return ImplSyntaxAnalyzer.s_instance;
125 }
126
127
128
129
130 public static void destroyInstance() {
131 ImplSyntaxAnalyzer.LOGGER
132 .debug("Destroying ImplSyntaxAnalyzer instance.");
133
134 if (ImplSyntaxAnalyzer.s_instance != null) {
135 ImplSyntaxAnalyzer.s_instance.m_startingToken = null;
136 ImplSyntaxAnalyzer.s_instance.m_startingToken = null;
137 }
138 ImplSyntaxAnalyzer.s_instance = null;
139 }
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155 private List<Token>
156 final List<Token>
157 final List<Token> ret = new ArrayList<Token>();
158 final String pattern = token.getToken();
159 final int size = options.size();
160 for (int i = 0; i < size; i += 1) {
161 final Token option = options.get(i);
162
163
164 if (option.getToken().startsWith(pattern)
165 && option.getToken().compareTo(pattern) != 0) {
166
167 if (option.getToken().compareTo(Constants.ENDING_TOKEN) == 0) {
168 ImplSyntaxAnalyzer.LOGGER.debug("Ending token!!");
169 }
170 ret.add(option);
171 }
172 }
173 return ret;
174 }
175
176
177
178
179
180
181
182
183 @Override
184 public GraphAnswer
185 throws InvalidGraphException {
186
187 if (ImplSyntaxAnalyzer.LOGGER.isDebugEnabled()) {
188 ImplSyntaxAnalyzer.LOGGER.debug(
189 "Getting option: {}", phrase.toString());
190 }
191
192 List<Token> lastValidOptions = new ArrayList<Token>(0);
193 List<Token> nextTokenOptions = new ArrayList<Token>(0);
194
195 final int size = phrase.size();
196 int index = -1;
197
198
199 GraphToken currentNode = this.m_startingToken;
200
201
202
203 boolean valid = true;
204 try {
205
206 while (index <= size - 1 && valid) {
207
208 if (currentNode == null) {
209 if (ImplSyntaxAnalyzer.LOGGER.isDebugEnabled()) {
210 if (phrase.get(index) == null) {
211
212 ImplSyntaxAnalyzer.LOGGER
213 .warn("\t--Nothing found.");
214 } else {
215 ImplSyntaxAnalyzer.LOGGER.warn(
216 "\t--Nothing found {} ",
217 phrase.get(index).getToken());
218 }
219 }
220 valid = false;
221 } else {
222
223
224
225
226 if (index == size - 1) {
227 index += 1;
228 nextTokenOptions = this.getWays(currentNode);
229
230 } else
231
232
233
234 if (index == size - 2) {
235 index += 1;
236 final List<Token> lastTokenOptions = this
237 .getWays(currentNode);
238 lastValidOptions = this.analyzeOptions(phrase
239 .get(index), lastTokenOptions);
240 currentNode = this.nextToken(currentNode, phrase
241 .get(index));
242
243 } else
244
245
246 if (index < size - 2) {
247 index += 1;
248 currentNode = this.nextToken(currentNode, phrase
249 .get(index));
250 }
251 }
252 }
253 } catch (InvalidTokenException e) {
254
255 throw new InvalidGraphException(e);
256 } catch (NullPointerException nullExcep) {
257
258
259 throw new RuntimeException(Messages
260 .getString("ImplSyntaxAnalyzer.InvalidGraph")
261 , nullExcep);
262 }
263 return new GraphAnswer(lastValidOptions, nextTokenOptions);
264 }
265
266
267
268
269
270
271
272
273
274
275
276 private List<Token>
277 throws InvalidTokenException {
278 final List<GraphToken> ways = currentNode.getWays();
279 final int size = ways.size();
280
281 final List<Token> ret = new ArrayList<Token>(size);
282
283 for (int i = 0; i < size; i += 1) {
284 final GraphToken graphToken = ways.get(i);
285 if (!(graphToken instanceof EndingToken)) {
286 final String identifier = graphToken.getName();
287 ret.add(this.createToken(identifier));
288 }
289 }
290 return ret;
291 }
292
293
294
295
296
297
298
299
300
301
302 private Token
303 throws InvalidTokenException {
304 return new Token(identifier);
305 }
306
307
308
309
310
311
312
313
314
315
316
317
318
319 private GraphToken
320 final Token
321
322 GraphToken ret = null;
323 final List<GraphToken> ways = currentNode.getWays();
324
325
326 boolean found = false;
327
328 final int size = ways.size();
329 int count = 0;
330 while (count < size && !found) {
331 final GraphToken temp = ways.get(count);
332 if (temp.represent(token.getToken())) {
333 ret = temp;
334 found = true;
335 }
336
337 count += 1;
338 }
339
340 if (ImplSyntaxAnalyzer.LOGGER.isDebugEnabled()) {
341 if (ret == null) {
342 ImplSyntaxAnalyzer.LOGGER
343 .debug("Next: {}:\t{}->\tNULL",
344 new String[] { token.toString(),
345 currentNode.toString() });
346 } else {
347 ImplSyntaxAnalyzer.LOGGER.debug(
348 "Next: {}:\t{}->\t{}", new String[] {
349 token.toString(), currentNode.toString(),
350 ret.toString() });
351 }
352 }
353
354 return ret;
355 }
356 }