Much of the logic here could perhaps be replaced by `new StringTokenizer(s.substring(start, end), "[]()," true)`. StringTokenizer can be configured to return the tokens (namely '[', ',', etc) so it should be enough for parsing these data types.