Skip to content

Commit 4b0bd7b

Browse files
committed
added flag to support ./2 as list, small refactoring of Tokenizer
1 parent 2b88200 commit 4b0bd7b

File tree

3 files changed

+35
-47
lines changed

3 files changed

+35
-47
lines changed

src/main/java/com/igormaznitsa/prologparser/PrologParser.java

Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ public abstract class PrologParser implements Iterable<PrologTerm>, Closeable {
9696
protected final ParserContext context;
9797
protected final int parserFlags;
9898
private final Tokenizer tokenizer;
99-
private PrologTerm lastFoundTerm;
10099

101100
public PrologParser(final Reader source, final ParserContext context) {
102101
this.context = context == null ? of(ParserContext.FLAG_NONE) : context;
@@ -157,30 +156,20 @@ public ParserContext getContext() {
157156
}
158157

159158
public boolean hasNext() {
160-
if (this.lastFoundTerm == null) {
161-
final PrologTerm found = readBlock(OPERATORS_PHRASE);
162-
if (found != null) {
163-
final TokenizerResult endAtom = this.tokenizer.readNextToken();
164-
if (endAtom == null || !endAtom.getResult().getText().equals(OPERATOR_DOT.getText())) {
165-
throw new PrologParserException("End operator is not found", this.tokenizer.getLine(), this.tokenizer.getPos());
166-
}
167-
}
168-
this.lastFoundTerm = found;
169-
}
170-
171-
return this.lastFoundTerm != null;
159+
return this.tokenizer.peek() != null;
172160
}
173161

174162
public PrologTerm next() {
175-
try {
176-
if (hasNext()) {
177-
return this.lastFoundTerm;
178-
} else {
179-
throw new NoSuchElementException("No terms in source");
163+
final PrologTerm found = readBlock(OPERATORS_PHRASE);
164+
if (found == null) {
165+
throw new NoSuchElementException("No terms in source");
166+
} else {
167+
final TokenizerResult endAtom = this.tokenizer.readNextToken();
168+
if (endAtom == null || !endAtom.getResult().getText().equals(OPERATOR_DOT.getText())) {
169+
throw new PrologParserException("End operator is not found", this.tokenizer.getLine(), this.tokenizer.getPos());
180170
}
181-
} finally {
182-
this.lastFoundTerm = null;
183171
}
172+
return found;
184173
}
185174

186175
private PrologStruct readStruct(final PrologTerm functor) {
@@ -582,12 +571,12 @@ private PrologTerm readBlock(final Koi7CharOpMap endOperators) {
582571
return null;
583572
} else {
584573
PrologTerm result = currentTreeItem.findRoot().convertToTermAndRelease(this);
585-
if ((this.parserFlags & FLAG_DOT2_AS_LIST) != 0
574+
if ((this.parserFlags & FLAG_DOT2_AS_LIST) != 0
586575
&& result.getType() == TermType.STRUCT
587-
&& result.getText().equals(".")
576+
&& result.getText().equals(".")
588577
&& result.getArity() == 2) {
589-
final PrologStruct asStruct = (PrologStruct) result;
590-
result = new PrologList(asStruct.getTermAt(0), asStruct.getTermAt(1));
578+
final PrologStruct asStruct = (PrologStruct) result;
579+
result = new PrologList(asStruct.getTermAt(0), asStruct.getTermAt(1));
591580
}
592581
return result;
593582
}

src/main/java/com/igormaznitsa/prologparser/tokenizer/Tokenizer.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,11 @@ public static boolean isCharAllowedForRadix(final char chr, final int radix) {
102102
}
103103
}
104104

105-
public TokenizerResult getLastPushed() {
105+
TokenizerResult getLastPushed() {
106106
return this.lastPushedTerm;
107107
}
108108

109-
public synchronized int readChar() throws IOException {
109+
private synchronized int doReadChar() throws IOException {
110110
int ch;
111111
if (this.insideCharBuffer.isEmpty()) {
112112
ch = this.reader.read();
@@ -246,7 +246,7 @@ public void fixPosition() {
246246
private void skipUntilBlockCommentEnd() throws IOException {
247247
boolean starCharDetected = false;
248248
while (!Thread.currentThread().isInterrupted()) {
249-
final int readChar = this.readChar();
249+
final int readChar = this.doReadChar();
250250
if (readChar < 0 || (readChar == '/' && starCharDetected)) {
251251
break;
252252
} else {
@@ -257,7 +257,7 @@ private void skipUntilBlockCommentEnd() throws IOException {
257257

258258
private void skipUntilNextString() throws IOException {
259259
while (!Thread.currentThread().isInterrupted()) {
260-
final int readChar = this.readChar();
260+
final int readChar = this.doReadChar();
261261
if (readChar < 0 || readChar == '\n') {
262262
break;
263263
}
@@ -275,7 +275,7 @@ public TokenizerResult pop() {
275275
/**
276276
* Read next token
277277
*
278-
* @return next token or null if not found or thread interruption detected
278+
* @return next token or null if not found or stream ended
279279
*/
280280
public TokenizerResult readNextToken() {
281281

@@ -306,7 +306,7 @@ public TokenizerResult readNextToken() {
306306

307307
try {
308308
while (!Thread.currentThread().isInterrupted()) {
309-
final int readChar = this.readChar();
309+
final int readChar = this.doReadChar();
310310

311311
if (readChar < 0) {
312312
switch (state) {

src/test/java/com/igormaznitsa/prologparser/IntegrationTest.java

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,10 @@ public class IntegrationTest extends AbstractIntegrationTest {
4646

4747
@Test
4848
public void testReadingClausesTokensAndCharsFromSameParser() throws IOException {
49-
final PrologParser parser = parseEd("some(a). alone. next(b).c");
49+
final PrologParser parser = parseEd("lsome(a). alone. next(b).c");
5050
assertTrue(parser.hasNext());
5151
final PrologTerm term1 = parser.next();
52-
assertEquals("some(a)", term1.toString());
52+
assertEquals("lsome(a)", term1.toString());
5353
assertTrue(parser.hasNext());
5454
final TokenizerResult token1 = parser.getInternalTokenizer().readNextToken();
5555
assertEquals("alone", token1.getResult().toString());
@@ -59,9 +59,8 @@ public void testReadingClausesTokensAndCharsFromSameParser() throws IOException
5959
assertTrue(parser.hasNext());
6060
final PrologTerm term2 = parser.next();
6161
assertEquals("next(b)", term2.toString());
62-
assertEquals('c', parser.getInternalTokenizer().readChar());
63-
assertFalse(parser.hasNext());
64-
assertEquals(-1, parser.getInternalTokenizer().readChar());
62+
assertTrue(parser.hasNext());
63+
assertThrows(PrologParserException.class, () -> parser.next());
6564
}
6665

6766
@Test
@@ -74,18 +73,18 @@ public void testEmptyAndNonClause() {
7473

7574
@Test
7675
public void testDot2StructAsList() {
77-
assertEquals("'.'(a, [])", parseGen("'.'(a,[]).").next().toString());
78-
assertEquals("'.'(a, X)", parseGen("'.'(a,X).").next().toString());
79-
assertEquals("'.'(a, b)", parseGen("'.'(a,b).").next().toString());
80-
81-
assertEquals("[a]", parseIso("'.'(a,[]).").next().toString());
82-
assertEquals("[a|X]", parseIso("'.'(a,X).").next().toString());
83-
assertEquals("[a|b]", parseIso("'.'(a,b).").next().toString());
84-
85-
assertEquals("[a, b, c]", parseIso("'.'(a,'.'(b,'.'(c,[]))).").next().toString());
86-
assertEquals("[a, b, c|X]", parseIso("'.'(a,'.'(b,'.'(c,X))).").next().toString());
87-
}
88-
76+
assertEquals("'.'(a, [])", parseGen("'.'(a,[]).").next().toString());
77+
assertEquals("'.'(a, X)", parseGen("'.'(a,X).").next().toString());
78+
assertEquals("'.'(a, b)", parseGen("'.'(a,b).").next().toString());
79+
80+
assertEquals("[a]", parseIso("'.'(a,[]).").next().toString());
81+
assertEquals("[a|X]", parseIso("'.'(a,X).").next().toString());
82+
assertEquals("[a|b]", parseIso("'.'(a,b).").next().toString());
83+
84+
assertEquals("[a, b, c]", parseIso("'.'(a,'.'(b,'.'(c,[]))).").next().toString());
85+
assertEquals("[a, b, c|X]", parseIso("'.'(a,'.'(b,'.'(c,X))).").next().toString());
86+
}
87+
8988
@Test
9089
public void testSwiCpl() {
9190
assertEquals("X in 5 .. 10 , 5 , Y #=< X + -1 , 6 , Y in 4 .. 8", parseCpl("X in 5..10,5,Y#=<X+ -1,6,Y in 4..8.").next().toString());

0 commit comments

Comments
 (0)