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.zemucan.core.syntactic.impl;
30
31 import java.util.ArrayList;
32 import java.util.Iterator;
33 import java.util.List;
34
35 import name.angoca.zemucan.AbstractZemucanException;
36 import name.angoca.zemucan.core.graph.model.AbstractGraphNode;
37 import name.angoca.zemucan.core.graph.model.GraphNode;
38 import name.angoca.zemucan.core.graph.model.NonReservedGraphNode;
39 import name.angoca.zemucan.core.graph.model.StartingNode;
40 import name.angoca.zemucan.core.graph.model.TextualGraphNode;
41 import name.angoca.zemucan.core.lexical.impl.InvalidTokenException;
42 import name.angoca.zemucan.core.lexical.model.Token;
43 import name.angoca.zemucan.core.syntactic.api.AbstractSyntacticAnalyzer;
44 import name.angoca.zemucan.core.syntactic.model.GraphAnswer;
45 import name.angoca.zemucan.grammarReader.api.GrammarReaderController;
46 import name.angoca.zemucan.tools.Constants;
47 import name.angoca.zemucan.tools.messages.Messages;
48
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104 public final class ImplementationSyntacticAnalyzer extends
105 AbstractSyntacticAnalyzer {
106
107
108
109
110 private static ImplementationSyntacticAnalyzer instance;
111
112
113
114
115 private static final Logger LOGGER = LoggerFactory
116 .getLogger(ImplementationSyntacticAnalyzer.class);
117
118
119
120
121 public static void destroyInstance() {
122 ImplementationSyntacticAnalyzer.LOGGER
123 .debug("Destroying ImplementationSyntacticAnalyzer instance.");
124
125 if (ImplementationSyntacticAnalyzer.instance != null) {
126 ImplementationSyntacticAnalyzer.instance.startingNode = null;
127 ImplementationSyntacticAnalyzer.instance = null;
128 }
129
130 assert ImplementationSyntacticAnalyzer.instance == null;
131 }
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146 public static ImplementationSyntacticAnalyzer
147 throws AbstractZemucanException {
148 if (ImplementationSyntacticAnalyzer.instance == null) {
149 ImplementationSyntacticAnalyzer.LOGGER
150 .debug("Creating ImplementationSyntaticAnalyzer instance.");
151 synchronized (ImplementationSyntacticAnalyzer.class) {
152 ImplementationSyntacticAnalyzer.instance = new ImplementationSyntacticAnalyzer();
153 }
154 }
155
156 assert ImplementationSyntacticAnalyzer.instance != null;
157 return ImplementationSyntacticAnalyzer.instance;
158 }
159
160
161
162
163 private boolean assertsEnabled;
164
165
166
167
168
169 private StartingNode startingNode;
170
171
172
173
174
175
176
177
178
179 private ImplementationSyntacticAnalyzer() throws AbstractZemucanException {
180 super();
181 this.assertsEnabled = false;
182
183 assert this.assertsEnabled = true;
184
185 this.startingNode = GrammarReaderController.getInstance()
186 .getStartingNode();
187
188
189 GrammarReaderController.destroyInstance();
190 }
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207 private List<Token>
208 final List<Token>
209 assert token != null;
210 assert options != null;
211 if (this.assertsEnabled) {
212 for (final Token token2 : options) {
213 assert token2 != null;
214 }
215 }
216
217 final List<Token> ret = new ArrayList<Token>();
218 final String pattern = token.getToken().toLowerCase();
219 final int size = options.size();
220 for (int i = 0; i < size; i += 1) {
221 final Token option = options.get(i);
222
223
224
225 if (option.getToken().startsWith(pattern)
226 && !option.getToken().equals(pattern)) {
227 if (option.getToken().equals(Constants.ENDING_NODE)) {
228 ImplementationSyntacticAnalyzer.LOGGER
229 .error(Messages
230 .getString("ImplementationSyntacticAnalyzer."
231 + "FatalError"), pattern);
232 assert true;
233 }
234 ret.add(option);
235 }
236 }
237
238 assert ret != null;
239 if (this.assertsEnabled) {
240 for (final Token token3 : ret) {
241 assert token3 != null;
242 }
243 }
244 return ret;
245 }
246
247
248
249
250
251
252
253 @Override
254 public GraphAnswer
255 final boolean endsWithSpace) throws AbstractZemucanException {
256 assert phrase != null;
257 if (this.assertsEnabled) {
258 for (final Token token : phrase) {
259 assert token != null;
260 }
261 }
262
263
264 if (ImplementationSyntacticAnalyzer.LOGGER.isDebugEnabled()) {
265 ImplementationSyntacticAnalyzer.LOGGER.debug(
266 "Getting option: {}", phrase.toString());
267 }
268
269
270 AbstractGraphNode currentNode = this.startingNode;
271
272 List<Token> lastValidOptions = new ArrayList<Token>(0);
273 List<Token> nextTokenOptions = new ArrayList<Token>(0);
274
275 final int size = phrase.size();
276 int index = -1;
277
278
279
280
281 boolean valid = true;
282
283 while ((index <= size - 1) && valid) {
284
285 if (currentNode == null) {
286 this.optionNotFound(phrase, index);
287 valid = false;
288 } else {
289
290
291 if (index == size - 1) {
292 index += 1;
293 nextTokenOptions = this.getWays(currentNode);
294
295 } else
296
297
298
299
300 if (index == size - 2) {
301 index += 1;
302 final List<Token> lastTokenOptions = this
303 .getWays(currentNode);
304 final Token token = phrase.get(index);
305 if (!endsWithSpace) {
306 lastValidOptions = this.analyzeOptions(token,
307 lastTokenOptions);
308 }
309 currentNode = this.nextToken(currentNode, token);
310
311 } else
312
313
314 if (index < size - 2) {
315 index += 1;
316 currentNode = this
317 .nextToken(currentNode, phrase.get(index));
318 }
319 }
320 }
321
322 final GraphAnswer graphAnswer = new GraphAnswer(lastValidOptions,
323 nextTokenOptions);
324 assert graphAnswer != null;
325 return graphAnswer;
326 }
327
328
329
330
331
332
333
334
335
336
337
338
339
340 private List<Token>
341 final AbstractGraphNode
342 throws InvalidTokenException {
343 assert currentNode != null;
344
345 final Iterator<AbstractGraphNode> ways = currentNode.getWays();
346
347 final List<Token> ret = new ArrayList<Token>();
348
349 while (ways.hasNext()) {
350 final AbstractGraphNode graphNode = ways.next();
351 if (graphNode instanceof TextualGraphNode) {
352 if (graphNode instanceof NonReservedGraphNode) {
353 final NonReservedGraphNode nonReserved = (NonReservedGraphNode) graphNode;
354 ret.add(new Token(nonReserved.getName(), false));
355 } else if (graphNode instanceof GraphNode) {
356 final GraphNode reservedWordNode = (GraphNode) graphNode;
357 ret.add(new Token(reservedWordNode.getName(), true));
358 }
359 }
360 }
361
362 assert ret != null;
363 if (this.assertsEnabled) {
364 for (final Token token : ret) {
365 assert token != null;
366 }
367 }
368 return ret;
369 }
370
371
372
373
374
375
376
377
378
379
380
381
382
383 private AbstractGraphNode
384 final AbstractGraphNode
385 final Token
386 assert currentNode != null;
387 assert token != null;
388
389 AbstractGraphNode ret = null;
390 final Iterator<AbstractGraphNode> ways = currentNode.getWays();
391
392
393
394 boolean found = false;
395
396 int count = 0;
397 while (ways.hasNext() && !found) {
398 final AbstractGraphNode temp = ways.next();
399 if (temp.represent(token.getToken())) {
400 ret = temp;
401 found = true;
402 }
403
404 count += 1;
405 }
406
407 if (ImplementationSyntacticAnalyzer.LOGGER.isDebugEnabled()) {
408 if (ret == null) {
409 ImplementationSyntacticAnalyzer.LOGGER
410 .debug("Next: {}:\t{}->\tNULL",
411 new String[] { token.toString(),
412 currentNode.toString() });
413 } else {
414 ImplementationSyntacticAnalyzer.LOGGER.debug(
415 "Next: {}:\t{}->\t{}", new String[] {
416 token.toString(), currentNode.toString(),
417 ret.toString() });
418 }
419 }
420
421 return ret;
422 }
423
424 private void optionNotFound(final List<Token> phrase, final int index) {
425 if (ImplementationSyntacticAnalyzer.LOGGER.isDebugEnabled()) {
426 ImplementationSyntacticAnalyzer.LOGGER.debug(
427 "The '{}' option was not found in the grammar.",
428 phrase.get(index).getToken());
429 }
430 }
431 }