Skip to content

Commit b8577c6

Browse files
committed
refactor: simplified parser somewhat
1 parent dd59876 commit b8577c6

File tree

2 files changed

+94
-140
lines changed

2 files changed

+94
-140
lines changed

src/main/java/org/codejive/properties/PropertiesParser.java

Lines changed: 52 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,31 @@
55
import java.util.ArrayList;
66
import java.util.List;
77
import java.util.Objects;
8+
import java.util.function.Supplier;
89

910
class PropertiesParser {
1011

12+
public enum Type {
13+
KEY,
14+
SEPARATOR,
15+
VALUE,
16+
COMMENT,
17+
WHITESPACE
18+
}
19+
1120
public static class Token {
21+
final Type type;
1222
final String text;
1323

14-
Token(String text) {
24+
Token(Type type, String text) {
25+
this.type = type;
1526
this.text = text;
1627
}
1728

29+
public Type getType() {
30+
return type;
31+
}
32+
1833
public String getText() {
1934
return text;
2035
}
@@ -34,125 +49,62 @@ public int hashCode() {
3449

3550
@Override
3651
public String toString() {
37-
return this.getClass().getSimpleName() + "{'" + text + "'}";
38-
}
39-
}
40-
41-
public static class KeyToken extends Token {
42-
KeyToken(String text) {
43-
super(text);
44-
}
45-
}
46-
47-
public static class ValueToken extends Token {
48-
ValueToken(String text) {
49-
super(text);
50-
}
51-
}
52-
53-
public static class SeparatorToken extends Token {
54-
SeparatorToken(String text) {
55-
super(text);
56-
}
57-
}
58-
59-
public static class CommentToken extends Token {
60-
CommentToken(String text) {
61-
super(text);
52+
return "Token('" + type + ", " + text + "')";
6253
}
6354
}
6455

65-
public static class WhitespaceToken extends Token {
66-
WhitespaceToken(String text) {
67-
super(text);
68-
}
69-
}
70-
71-
private enum State {
72-
INIT,
73-
KEY,
74-
SEPARATOR,
75-
VALUE,
76-
COMMENT,
77-
WHITESPACE
78-
}
79-
8056
private final Reader rdr;
8157

82-
private State state;
58+
private Type state;
8359
private int ch;
8460
private int pch;
8561
StringBuilder chr;
8662
StringBuilder str;
8763

8864
public PropertiesParser(Reader rdr) throws IOException {
8965
this.rdr = rdr;
90-
state = State.INIT;
66+
state = null;
9167
chr = new StringBuilder();
9268
str = new StringBuilder();
9369
pch = -1;
9470
nextChar();
9571
}
9672

9773
public Token nextToken() throws IOException {
74+
Supplier<Boolean> isValid = () -> false;
75+
Type nextState = null;
9876
while (true) {
99-
switch (state) {
100-
case INIT:
101-
if (isCommentChar(ch)) {
102-
state = State.COMMENT;
103-
} else if (isWhitespaceChar(ch)) {
104-
state = State.WHITESPACE;
105-
} else if (isEof(ch)) {
106-
return null;
107-
} else {
108-
state = State.KEY;
109-
}
110-
break;
111-
case KEY:
112-
if (!isSeparatorChar(ch)) {
113-
str.append(chr);
114-
nextChar();
115-
} else {
116-
state = State.SEPARATOR;
117-
return new KeyToken(string());
118-
}
119-
break;
120-
case SEPARATOR:
121-
if (isSeparatorChar(ch)) {
122-
str.append(chr);
123-
nextChar();
124-
} else {
125-
state = State.VALUE;
126-
return new SeparatorToken(string());
127-
}
128-
break;
129-
case VALUE:
130-
if (!isEol(ch)) {
131-
str.append(chr);
132-
nextChar();
133-
} else {
134-
state = State.INIT;
135-
return new ValueToken(trimmedString());
136-
}
137-
break;
138-
case COMMENT:
139-
if (!isEol(ch)) {
140-
str.append(chr);
141-
nextChar();
142-
} else {
143-
state = State.INIT;
144-
return new CommentToken(trimmedString());
145-
}
146-
break;
147-
case WHITESPACE:
148-
if (isWhitespaceChar(ch)) {
149-
str.append(chr);
150-
nextChar();
151-
} else {
152-
state = State.INIT;
153-
return new WhitespaceToken(string());
154-
}
155-
break;
77+
if (state == null) {
78+
if (isCommentChar(ch)) {
79+
state = Type.COMMENT;
80+
isValid = () -> !isEol(ch);
81+
nextState = null;
82+
} else if (isWhitespaceChar(ch)) {
83+
state = Type.WHITESPACE;
84+
isValid = () -> isWhitespaceChar(ch);
85+
nextState = null;
86+
} else if (isEof(ch)) {
87+
return null;
88+
} else {
89+
state = Type.KEY;
90+
isValid = () -> !isSeparatorChar(ch);
91+
nextState = Type.SEPARATOR;
92+
}
93+
} else if (state == Type.SEPARATOR) {
94+
isValid = () -> isSeparatorChar(ch);
95+
nextState = Type.VALUE;
96+
} else if (state == Type.VALUE) {
97+
isValid = () -> !isEol(ch);
98+
nextState = null;
99+
}
100+
if (isValid.get()) {
101+
str.append(chr);
102+
nextChar();
103+
} else {
104+
String text = (state == Type.VALUE || state == Type.COMMENT) ? trimmedString() : string();
105+
Token token = new Token(state, text);
106+
state = nextState;
107+
return token;
156108
}
157109
}
158110
}

src/test/java/org/codejive/properties/TestPropertiesParser.java

Lines changed: 42 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package org.codejive.properties;
22

3-
import static org.codejive.properties.PropertiesParser.*;
43
import static org.hamcrest.MatcherAssert.assertThat;
54
import static org.hamcrest.Matchers.equalTo;
65

@@ -11,8 +10,11 @@
1110
import java.util.stream.Collectors;
1211
import org.junit.jupiter.api.Test;
1312

13+
import org.codejive.properties.PropertiesParser.Token;
14+
import org.codejive.properties.PropertiesParser.Type;
15+
1416
public class TestPropertiesParser {
15-
private String props =
17+
private final String props =
1618
""
1719
+ "#comment1\n"
1820
+ "# comment2 \n"
@@ -27,7 +29,7 @@ public class TestPropertiesParser {
2729
+ "multiline = one \\\n"
2830
+ " two \\\n\r"
2931
+ "\tthree\n"
30-
+ "key.4 = \u1234\n"
32+
+ "key.4 = \\u1234\n"
3133
+ "# final comment";
3234

3335
@Test
@@ -38,43 +40,43 @@ void testTokens() throws IOException {
3840
tokens,
3941
equalTo(
4042
Arrays.asList(
41-
new CommentToken("#comment1"),
42-
new WhitespaceToken("\n"),
43-
new CommentToken("# comment2"),
44-
new WhitespaceToken(" \n\n"),
45-
new CommentToken("! comment3"),
46-
new WhitespaceToken("\n"),
47-
new KeyToken("one"),
48-
new SeparatorToken("="),
49-
new ValueToken("simple"),
50-
new WhitespaceToken("\n"),
51-
new KeyToken("two"),
52-
new SeparatorToken("="),
53-
new ValueToken("value containing spaces"),
54-
new WhitespaceToken("\n\r"),
55-
new CommentToken("# another comment"),
56-
new WhitespaceToken("\n"),
57-
new KeyToken("three"),
58-
new SeparatorToken("="),
59-
new ValueToken("and escapes\\n\\t\\r\\f"),
60-
new WhitespaceToken("\n "),
61-
new KeyToken("\\ with\\ spaces"),
62-
new SeparatorToken(" = "),
63-
new ValueToken("everywhere"),
64-
new WhitespaceToken(" \n"),
65-
new KeyToken("altsep"),
66-
new SeparatorToken(":"),
67-
new ValueToken("value"),
68-
new WhitespaceToken("\n"),
69-
new KeyToken("multiline"),
70-
new SeparatorToken(" = "),
71-
new ValueToken("one \\\n two \\\n\r\tthree"),
72-
new WhitespaceToken("\n"),
73-
new KeyToken("key.4"),
74-
new SeparatorToken(" = "),
75-
new ValueToken("\u1234"),
76-
new WhitespaceToken("\n"),
77-
new CommentToken("# final comment"))));
43+
new Token(Type.COMMENT, "#comment1"),
44+
new Token(Type.WHITESPACE, "\n"),
45+
new Token(Type.COMMENT, "# comment2"),
46+
new Token(Type.WHITESPACE, " \n\n"),
47+
new Token(Type.COMMENT, "! comment3"),
48+
new Token(Type.WHITESPACE, "\n"),
49+
new Token(Type.KEY, "one"),
50+
new Token(Type.SEPARATOR, "="),
51+
new Token(Type.VALUE, "simple"),
52+
new Token(Type.WHITESPACE, "\n"),
53+
new Token(Type.KEY, "two"),
54+
new Token(Type.SEPARATOR, "="),
55+
new Token(Type.VALUE, "value containing spaces"),
56+
new Token(Type.WHITESPACE, "\n\r"),
57+
new Token(Type.COMMENT, "# another comment"),
58+
new Token(Type.WHITESPACE, "\n"),
59+
new Token(Type.KEY, "three"),
60+
new Token(Type.SEPARATOR, "="),
61+
new Token(Type.VALUE, "and escapes\\n\\t\\r\\f"),
62+
new Token(Type.WHITESPACE, "\n "),
63+
new Token(Type.KEY, "\\ with\\ spaces"),
64+
new Token(Type.SEPARATOR, " = "),
65+
new Token(Type.VALUE, "everywhere"),
66+
new Token(Type.WHITESPACE, " \n"),
67+
new Token(Type.KEY, "altsep"),
68+
new Token(Type.SEPARATOR, ":"),
69+
new Token(Type.VALUE, "value"),
70+
new Token(Type.WHITESPACE, "\n"),
71+
new Token(Type.KEY, "multiline"),
72+
new Token(Type.SEPARATOR, " = "),
73+
new Token(Type.VALUE, "one \\\n two \\\n\r\tthree"),
74+
new Token(Type.WHITESPACE, "\n"),
75+
new Token(Type.KEY, "key.4"),
76+
new Token(Type.SEPARATOR, " = "),
77+
new Token(Type.VALUE, "\\u1234"),
78+
new Token(Type.WHITESPACE, "\n"),
79+
new Token(Type.COMMENT, "# final comment"))));
7880
}
7981

8082
@Test

0 commit comments

Comments
 (0)