@@ -187,58 +187,84 @@ public ParserContext getContext() {
187
187
return context ;
188
188
}
189
189
190
- public boolean hasNext () {
191
- return this .tokenizer .peek () != null ;
190
+ private PrologTermReadResult deferredReadTerm ;
191
+
192
+ private static boolean isComment (final TokenizerResult tokenizerResult ) {
193
+ return tokenizerResult != null
194
+ && tokenizerResult .getResult ().getType () == TermType .ATOM
195
+ && (tokenizerResult .getResult ().getQuotation () == Quotation .COMMENT_LINE
196
+ || tokenizerResult .getResult ().getQuotation () == Quotation .COMMENT_BLOCK );
197
+ }
198
+
199
+ private void notifyCommentTokenListeners (final TokenizerResult commentToken ) {
200
+ for (final TokenizedCommentListener listener : this .commentTokenListeners ) {
201
+ listener .onCommentToken (this , commentToken );
202
+ }
192
203
}
193
204
194
- private TokenizerResult readNextTokenCommentAware () {
205
+ private TokenizerResult extractNextTokenCommentAware () {
195
206
TokenizerResult result ;
196
- if (this .commentsAsAtoms ) {
197
- while (true ) {
198
- result = this .tokenizer .readNextToken ();
199
- if (result != null
200
- && (result .getResult ().getQuotation () == Quotation .COMMENT_BLOCK ||
201
- result .getResult ().getQuotation () == Quotation .COMMENT_LINE )) {
202
- for (final TokenizedCommentListener listener : this .commentTokenListeners ) {
203
- listener .onCommentToken (this , result );
204
- }
205
- } else {
206
- break ;
207
- }
208
- }
209
- } else {
207
+ while (true ) {
210
208
result = this .tokenizer .readNextToken ();
209
+ if (isComment (result )) {
210
+ this .notifyCommentTokenListeners (result );
211
+ } else {
212
+ break ;
213
+ }
211
214
}
212
215
return result ;
213
216
}
214
217
215
- public PrologTerm next () {
216
- final PrologTerm found = readBlock (OPERATORS_PHRASE );
217
- if (found == null ) {
218
- throw new NoSuchElementException ("No terms in source" );
219
- } else {
220
- final TokenizerResult endAtom = this .readNextTokenCommentAware ();
221
- if (endAtom == null || !endAtom .getResult ().getText ().equals (OPERATOR_DOT .getText ())) {
222
- throw new PrologParserException ("End operator is not found" ,
223
- this .tokenizer .getLine (),
224
- this .tokenizer .getPos ());
218
+ private PrologTermReadResult extractNextBlockAndWrapError () {
219
+ try {
220
+ final PrologTerm found = this .readBlock (OPERATORS_PHRASE );
221
+ if (found == null ) {
222
+ throw new NoSuchElementException ("No terms in source" );
223
+ } else {
224
+ final TokenizerResult endAtom = this .extractNextTokenCommentAware ();
225
+ if (endAtom == null || !endAtom .getResult ().getText ().equals (OPERATOR_DOT .getText ())) {
226
+ throw new PrologParserException ("End operator is not found" ,
227
+ this .tokenizer .getLine (),
228
+ this .tokenizer .getPos ());
229
+ }
225
230
}
231
+ return new PrologTermReadResult (found , null );
232
+ } catch (RuntimeException ex ) {
233
+ return new PrologTermReadResult (null , ex );
234
+ }
235
+ }
236
+
237
+ public boolean hasNext () {
238
+ if (this .deferredReadTerm == null ) {
239
+ this .deferredReadTerm = this .extractNextBlockAndWrapError ();
226
240
}
227
- return found ;
241
+ return this .deferredReadTerm .isPresented ();
242
+ }
243
+
244
+ public PrologTerm next () {
245
+ if (this .deferredReadTerm == null ) {
246
+ this .deferredReadTerm = this .extractNextBlockAndWrapError ();
247
+ }
248
+ final PrologTerm result ;
249
+ try {
250
+ result = this .deferredReadTerm .getResult ();
251
+ } finally {
252
+ this .deferredReadTerm = null ;
253
+ }
254
+ return result ;
228
255
}
229
256
230
257
private PrologStruct readStruct (final PrologTerm functor ) {
231
258
final List <PrologTerm > listOfAtoms = new ArrayList <>();
232
259
PrologStruct result ;
233
260
boolean active = true ;
234
261
while (active ) {
235
- final PrologTerm block = readBlock (OPERATORS_INSIDE_STRUCT );
236
-
262
+ final PrologTerm block = this .readBlock (OPERATORS_INSIDE_STRUCT );
237
263
if (block == null ) {
238
264
return null ;
239
265
}
240
266
241
- final TokenizerResult nextAtom = this .readNextTokenCommentAware ();
267
+ final TokenizerResult nextAtom = this .extractNextTokenCommentAware ();
242
268
if (nextAtom == null ) {
243
269
throw new PrologParserException ("Can't read next token in block" , this .tokenizer .getLine (),
244
270
this .tokenizer .getPos ());
@@ -277,7 +303,7 @@ private PrologTerm readList(final TokenizerResult openingBracket) {
277
303
while (continueReading ) {
278
304
final PrologTerm block = readBlock (OPERATORS_INSIDE_LIST );
279
305
280
- final TokenizerResult nextAtom = this .readNextTokenCommentAware ();
306
+ final TokenizerResult nextAtom = this .extractNextTokenCommentAware ();
281
307
if (nextAtom == null ) {
282
308
throw new PrologParserException ("Can't read next token in list" , this .tokenizer .getLine (),
283
309
this .tokenizer .getPos ());
@@ -316,7 +342,7 @@ private PrologTerm readList(final TokenizerResult openingBracket) {
316
342
tokenizer .getLastTokenPos (), null );
317
343
}
318
344
319
- final TokenizerResult nextAtomTwo = this .readNextTokenCommentAware ();
345
+ final TokenizerResult nextAtomTwo = this .extractNextTokenCommentAware ();
320
346
if (nextAtomTwo == null ) {
321
347
throw new PrologParserException ("Can't find expected token in list" ,
322
348
this .tokenizer .getLine (), this .tokenizer .getPos ());
@@ -374,21 +400,14 @@ private PrologTerm readList(final TokenizerResult openingBracket) {
374
400
return leftPartFirst ;
375
401
}
376
402
377
- private void checkForNull (final Object obj , final String message ,
378
- final TokenizerResult startTerm ) {
379
- if (obj == null ) {
380
- throw new PrologParserException (message , startTerm .getLine (), startTerm .getPos ());
381
- }
382
- }
383
-
384
403
private PrologTerm readBlock (final Koi7CharOpMap endOperators ) {
385
404
// the variable will contain last processed tree item contains either
386
405
// atom or operator
387
406
AstItem currentTreeItem = null ;
388
407
389
408
while (true ) {
390
409
// read next atom from tokenizer
391
- TokenizerResult readAtomContainer = this .readNextTokenCommentAware ();
410
+ TokenizerResult readAtomContainer = this .extractNextTokenCommentAware ();
392
411
393
412
if (readAtomContainer == null ) {
394
413
if (currentTreeItem == null ) {
@@ -505,7 +524,7 @@ private PrologTerm readBlock(final Koi7CharOpMap endOperators) {
505
524
readAtomContainer .getLine (), readAtomContainer .getPos ());
506
525
}
507
526
508
- final TokenizerResult token = this .readNextTokenCommentAware ();
527
+ final TokenizerResult token = this .extractNextTokenCommentAware ();
509
528
510
529
final PrologTerm closingAtom ;
511
530
if (token == null ) {
@@ -534,7 +553,7 @@ private PrologTerm readBlock(final Koi7CharOpMap endOperators) {
534
553
}
535
554
} else {
536
555
if (readAtom .getType () != TermType .VAR || (this .parserFlags & FLAG_VAR_AS_FUNCTOR ) != 0 ) {
537
- TokenizerResult nextToken = this .readNextTokenCommentAware ();
556
+ TokenizerResult nextToken = this .extractNextTokenCommentAware ();
538
557
539
558
if (nextToken == null ) {
540
559
throw new PrologParserException ("Non-closed clause" , this .tokenizer .getLastTokenLine (),
@@ -666,6 +685,19 @@ private PrologTerm readBlock(final Koi7CharOpMap endOperators) {
666
685
}
667
686
}
668
687
688
+ private void checkForNull (final Object obj , final String message ,
689
+ final TokenizerResult startTerm ) {
690
+ if (obj == null ) {
691
+ throw new PrologParserException (message , startTerm .getLine (), startTerm .getPos ());
692
+ }
693
+ }
694
+
695
+ @ Override
696
+ public void close () throws IOException {
697
+ this .deferredReadTerm = null ;
698
+ this .tokenizer .close (this .autoCloseReaderFlag );
699
+ }
700
+
669
701
@ Override
670
702
public Iterator <PrologTerm > iterator () {
671
703
return new Iterator <>() {
@@ -690,9 +722,26 @@ public Stream<PrologTerm> stream() {
690
722
);
691
723
}
692
724
693
- @ Override
694
- public void close () throws IOException {
695
- this .tokenizer .close (this .autoCloseReaderFlag );
725
+ private static final class PrologTermReadResult {
726
+ private final PrologTerm result ;
727
+ private final RuntimeException exception ;
728
+
729
+ private PrologTermReadResult (final PrologTerm result , final RuntimeException error ) {
730
+ this .result = result ;
731
+ this .exception = error ;
732
+ }
733
+
734
+ boolean isPresented () {
735
+ return this .exception == null || !(this .exception instanceof NoSuchElementException );
736
+ }
737
+
738
+ PrologTerm getResult () {
739
+ if (this .exception == null ) {
740
+ return this .result ;
741
+ } else {
742
+ throw this .exception ;
743
+ }
744
+ }
696
745
}
697
746
698
747
}
0 commit comments