
I currently have a working solution, but I feel like there's a simpler/easier way of representing this.
I need to be able to parse these valid examples:
A/B/C/D
A2/B/C/D
A, B, C
A3/C
B/C/D
Invalid:
A/A2
D, C, B, A
So there's a known restricted vocabulary of:
A,A2,A3,B,C,D,D2,D3,...(100s more)
where numbers signify a simplified/acronymized variant of the same type.
Note that only one token of the same type can exist at a time. And types must come in order and are separated by some string.
Here's what I have working:
Rule SequenceOfSeparatedOptionals(String separator, Index tokens) {
Rule maybe = FirstOf(tokens.possible());
return Sequence(
Sequence(maybe, push(tokens.lookup(match(), 0))),
ZeroOrMore(
separator,
maybe,
push(tokens.lookup(match(), (int) pop() + 1)) && (int) peek() >= 0));
}
class Index {
private final Map<String, Integer> index;
// E.G. { "A":1, "A1":1, "B":2, "C":3 }
Index(Map<String, Integer> index) {
this.index = index;
}
String[] possible() {
return index.keySet().toArray(new String[index.size()]);
}
int lookup(String value, int after) {
Integer maybe = index.get(value);
if (maybe != null && maybe > after) {
return maybe;
}
return 1;
}
}
Am I missing a better solution?
