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.lexical.impl;
30
31 import java.util.ArrayList;
32 import java.util.List;
33 import java.util.StringTokenizer;
34
35 import name.angoca.zemucan.AbstractZemucanException;
36 import name.angoca.zemucan.GeneralException;
37 import name.angoca.zemucan.ParameterNullException;
38 import name.angoca.zemucan.core.lexical.api.AbstractLexicalAnalyzer;
39 import name.angoca.zemucan.core.lexical.model.Token;
40 import name.angoca.zemucan.core.syntactic.impl.ImplementationSyntacticAnalyzer;
41 import name.angoca.zemucan.core.syntactic.model.GraphAnswer;
42 import name.angoca.zemucan.grammarReader.api.GrammarReaderController;
43 import name.angoca.zemucan.interfaze.model.ReturnOptions;
44 import name.angoca.zemucan.tools.Base64;
45
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
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
77
78
79
80
81
82
83
84 public final class ImplementationLexicalAnalyzer extends
85 AbstractLexicalAnalyzer {
86
87
88
89
90 private static byte[] CODE = new byte[] { 97, 110, 103, 111, 99, 97 };
91
92
93
94 private static String HUEVO = "VGhpcyBzb2Z0d2FyZSB3YXMgd3JpdHRlbiBieSBBbmRyZXMgR29tZXogQ2FzYW5vdmEgKEFuZ29jQSksIGFuZCBpdCBpcyBkZWRpY2F0ZWQgdG8gbXkgbG92ZWx5IExpbGlhbmEgT3JqdWVsYSwgd2hvIGlzIHRoZSBnaXJsIHRoYXQgSSBsb3ZlIGZyb20gdGhlIGRlZXAgb2YgbXkgaGVhcnQhIFRoaXMgYXBwbGljYXRpb24gaGFzIGEgaGlnaCBxdWFsaXR5IGluIHNldmVyYWwgYXNwZWN0cyBiZWNhdXNlIExpbGkgaXMgbXkgaW5zcGlyYXRpb24u";
95
96
97
98 private static ImplementationLexicalAnalyzer instance;
99
100
101
102
103 private static final Logger LOGGER = LoggerFactory
104 .getLogger(ImplementationLexicalAnalyzer.class);
105
106
107
108
109 private static final String WHITE_SPACE = " ";
110
111
112
113
114 public static void destroyInstance() {
115 ImplementationLexicalAnalyzer.LOGGER
116 .debug("Destroying ImplementationLexicalAnalyzer instance");
117 if (ImplementationLexicalAnalyzer.instance != null) {
118 ImplementationSyntacticAnalyzer.destroyInstance();
119 ImplementationLexicalAnalyzer.instance.delimiters = null;
120 ImplementationLexicalAnalyzer.instance = null;
121 }
122
123 assert ImplementationLexicalAnalyzer.instance == null;
124 }
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140 public static ImplementationLexicalAnalyzer
141 throws AbstractZemucanException {
142 if (ImplementationLexicalAnalyzer.instance == null) {
143 ImplementationLexicalAnalyzer.LOGGER
144 .debug("Creating ImplementationLexicalAnalyzer instance");
145 synchronized (ImplementationLexicalAnalyzer.class) {
146 ImplementationLexicalAnalyzer.instance = new ImplementationLexicalAnalyzer();
147 }
148 }
149
150 assert ImplementationLexicalAnalyzer.instance != null;
151 return ImplementationLexicalAnalyzer.instance;
152 }
153
154
155
156
157 private String delimiters;
158
159
160
161
162
163
164
165
166 private ImplementationLexicalAnalyzer() throws AbstractZemucanException {
167 super();
168
169
170 this.delimiters = GrammarReaderController.getInstance().getDelimiters();
171 }
172
173
174
175
176
177
178
179
180 @Override
181 public ReturnOptions
182 throws AbstractZemucanException {
183 assert phrase != null;
184
185
186 if (ImplementationLexicalAnalyzer.LOGGER.isDebugEnabled()) {
187 ImplementationLexicalAnalyzer.LOGGER.debug(
188 "Entering to lexical analyzer: '{}'",
189 phrase);
190 }
191
192
193 final String newPhrase = phrase.trim();
194 final boolean endsWithSpace = phrase
195 .endsWith(ImplementationLexicalAnalyzer.WHITE_SPACE);
196
197 final StringTokenizer tokenizer = new StringTokenizer(newPhrase,
198 this.delimiters, true);
199 final ReturnOptions ret1 = this.pascua(phrase);
200
201 final List<Token> tokens = new ArrayList<Token>(tokenizer.countTokens());
202 String currentToken;
203
204 while (tokenizer.hasMoreTokens()) {
205 currentToken = tokenizer.nextToken();
206 if (!(currentToken
207 .equals(ImplementationLexicalAnalyzer.WHITE_SPACE))) {
208
209
210
211
212 tokens.add(new Token(currentToken, true));
213 ImplementationLexicalAnalyzer.LOGGER.debug(
214 "Token: {{}}", currentToken);
215 }
216 }
217
218 final GraphAnswer answer = ImplementationSyntacticAnalyzer
219 .getInstance().analyzeTokens(tokens, endsWithSpace);
220
221 if (ImplementationLexicalAnalyzer.LOGGER.isDebugEnabled()) {
222 ImplementationLexicalAnalyzer.LOGGER.debug("{} : {}",
223 answer.getPhrases().toString(), answer.getOptions()
224 .toString());
225 }
226
227
228
229 ReturnOptions ret = this.processAnswer(newPhrase, endsWithSpace,
230 tokens, answer);
231 if (ret1 != null) {
232 ret = ret1;
233 }
234
235 assert ret != null;
236
237 return ret;
238 }
239
240
241
242
243
244
245
246
247
248 private ReturnOptions
249 throws ParameterNullException {
250 assert phrase != null;
251
252 ReturnOptions ret = null;
253 if (phrase.equals(new String(ImplementationLexicalAnalyzer.CODE))) {
254 final String decode = Base64
255 .decodeString(ImplementationLexicalAnalyzer.HUEVO);
256 ret = new ReturnOptions(phrase, new String[] {},
257 new String[] { decode });
258 }
259
260 return ret;
261 }
262
263 private ReturnOptions phraseMultiple(String newPhrase,
264 final List<Token> tokens, final GraphAnswer answer,
265 final int sizeOptions, String[] setOfOptions, String[] setOfPhrases)
266 throws GeneralException, ParameterNullException {
267 if (sizeOptions > 1) {
268
269
270 ImplementationLexicalAnalyzer.LOGGER.debug("Case 1!");
271 } else if (sizeOptions == 1) {
272
273
274 ImplementationLexicalAnalyzer.LOGGER.debug("Case 2!");
275
276 throw new RuntimeException("Notify this to AngocA, case 2: "
277 + newPhrase);
278 } else if (sizeOptions == 0) {
279
280 ImplementationLexicalAnalyzer.LOGGER.debug("Case 3!");
281 final String prefix = this
282 .samePrefixForPhrases(answer.getPhrases());
283 if (prefix.length() > 0) {
284
285 newPhrase = this.replaceLastToken(newPhrase, tokens, prefix);
286 }
287 }
288 setOfOptions = this.returnCandidates(answer.getOptions());
289 setOfPhrases = this.returnCandidates(answer.getPhrases());
290 final ReturnOptions ret = new ReturnOptions(newPhrase, setOfPhrases,
291 setOfOptions);
292 return ret;
293 }
294
295 private ReturnOptions phraseOne(String newPhrase, final List<Token> tokens,
296 final GraphAnswer answer, final int sizeOptions,
297 String[] setOfOptions, String[] setOfPhrases)
298 throws GeneralException, ParameterNullException {
299 if (sizeOptions > 1) {
300
301 ImplementationLexicalAnalyzer.LOGGER.debug("Case 4!");
302 setOfPhrases = this.returnCandidates(answer.getPhrases());
303 } else if (sizeOptions == 1) {
304
305 ImplementationLexicalAnalyzer.LOGGER.debug("Case 5!");
306 setOfPhrases = this.returnCandidates(answer.getPhrases());
307 } else if (sizeOptions == 0) {
308
309 ImplementationLexicalAnalyzer.LOGGER.debug("Case 6!");
310
311 newPhrase = this.replaceLastToken(newPhrase, tokens, answer
312 .getPhrases().get(0).getToken());
313 setOfPhrases = new String[] {};
314 }
315 setOfOptions = this.returnCandidates(answer.getOptions());
316 final ReturnOptions ret = new ReturnOptions(newPhrase, setOfPhrases,
317 setOfOptions);
318 return ret;
319 }
320
321 private ReturnOptions phraseZero(String newPhrase,
322 final boolean endsWithSpace, final GraphAnswer answer,
323 final int sizeOptions, String[] setOfOptions, String[] setOfPhrases)
324 throws GeneralException, ParameterNullException {
325 if (sizeOptions > 1) {
326
327
328 ImplementationLexicalAnalyzer.LOGGER.debug("Case 7");
329 if (newPhrase.length() > 0) {
330 newPhrase += " ";
331 }
332 newPhrase += this.samePrefixForPhrases(answer.getOptions());
333 setOfOptions = this.returnCandidates(answer.getOptions());
334 } else if (sizeOptions == 1) {
335
336 ImplementationLexicalAnalyzer.LOGGER.debug("Case 8!");
337 newPhrase += " ";
338 if (answer.getOptions().get(0).isReservedWord()) {
339
340
341 ImplementationLexicalAnalyzer.LOGGER.debug("Case 8a");
342 newPhrase += answer.getOptions().get(0).getToken();
343 setOfOptions = new String[] {};
344 } else {
345
346 ImplementationLexicalAnalyzer.LOGGER.debug("Case 8b");
347 setOfOptions = this.returnCandidates(answer.getOptions());
348 }
349 } else if (sizeOptions == 0) {
350
351
352 ImplementationLexicalAnalyzer.LOGGER.debug("Case 9!");
353
354 if (endsWithSpace) {
355 newPhrase += " ";
356 }
357
358 setOfOptions = new String[] {};
359 }
360 setOfPhrases = new String[] {};
361 final ReturnOptions ret = new ReturnOptions(newPhrase, setOfPhrases,
362 setOfOptions);
363 return ret;
364 }
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383 private ReturnOptions processAnswer(final String newPhrase,
384 final boolean endsWithSpace, final List<Token> tokens,
385 final GraphAnswer answer) throws AbstractZemucanException {
386 final int sizePhrases = answer.getPhrases().size();
387 final int sizeOptions = answer.getOptions().size();
388 final String[] setOfOptions = null;
389 final String[] setOfPhrases = null;
390 ReturnOptions ret = null;
391 if (sizePhrases > 1) {
392 ret = this.phraseMultiple(newPhrase, tokens, answer, sizeOptions,
393 setOfOptions, setOfPhrases);
394 } else if (sizePhrases == 1) {
395 ret = this.phraseOne(newPhrase, tokens, answer, sizeOptions,
396 setOfOptions, setOfPhrases);
397 } else if (sizePhrases == 0) {
398 ret = this.phraseZero(newPhrase, endsWithSpace, answer,
399 sizeOptions, setOfOptions, setOfPhrases);
400 }
401
402 return ret;
403 }
404
405
406
407
408
409
410
411
412
413
414
415
416 String
417 final List<Token>
418 assert phrase != null;
419 assert tokens != null;
420 boolean assertsEnabled = false;
421
422 assert assertsEnabled = true;
423 if (assertsEnabled) {
424 for (final Token token : tokens) {
425 assert token != null;
426 }
427 }
428 assert prefix != null;
429
430 final int lastIndexPhrase = tokens.size() - 1;
431
432 final String lastTokenPhrase = tokens.get(lastIndexPhrase).getToken();
433
434 final int lastTokenIndex = phrase.lastIndexOf(lastTokenPhrase);
435 String newPhrase = "";
436 if (lastIndexPhrase != 0) {
437
438 newPhrase = phrase.substring(0, lastTokenIndex) + prefix;
439 } else {
440 newPhrase = prefix;
441 }
442
443 assert newPhrase != null;
444
445 return newPhrase;
446 }
447
448
449
450
451
452
453
454
455 private String[]
456 final List<Token>
457 assert candidates != null;
458 boolean assertsEnabled = false;
459
460 assert assertsEnabled = true;
461 if (assertsEnabled) {
462 for (final Token token : candidates) {
463 assert token != null;
464 }
465 }
466
467 final int size = candidates.size();
468 final String[] ret = new String[size];
469 for (int i = 0; i < size; i += 1) {
470 final Token token = candidates.get(i);
471 ret[i] = token.getToken();
472 }
473
474 assert ret != null;
475
476 assert assertsEnabled = true;
477 if (assertsEnabled) {
478 for (int i = 0; i < ret.length; i++) {
479 assert ret[i] != null;
480 }
481 }
482
483 return ret;
484 }
485
486
487
488
489
490
491
492
493
494 private String
495 assert tokens != null;
496 boolean assertsEnabled = false;
497
498 assert assertsEnabled = true;
499 if (assertsEnabled) {
500 for (final Token token : tokens) {
501 assert token != null;
502 }
503 }
504
505 final String example = tokens.get(0).getToken();
506 final int sizePrefix = example.length();
507 String prefix = "";
508 boolean allSamePrefix = true;
509 for (int i = 0; (i < sizePrefix) && allSamePrefix; i += 1) {
510 final String temp = example.substring(0, i + 1);
511
512 for (final Token token : tokens) {
513 allSamePrefix &= token.getToken().startsWith(temp);
514 }
515
516 if (allSamePrefix) {
517 prefix = temp;
518 }
519 }
520
521 assert prefix != null;
522
523 return prefix;
524 }
525 }