public BacktrackItem handle(ProdElement state, BacktrackItem previous) { if (Strings.isEmpty(state.getValue())) return previous; if (Strings.isEmpty(state.getName())) { if (text.regionMatches(previous.offset, state.getValue(), 0, state.getValue().length())) { int newOffset = previous.offset + state.getValue().length(); Matcher ws = WS.matcher(text).region(newOffset, text.length()); int childOffset = ws.find() ? ws.end() : newOffset; return new BacktrackItem(childOffset, state, state.getValue()); } } else { Token t = Token.valueOf(state.getValue()); Matcher matcher = t.pattern.matcher(text).region(previous.offset, text.length()); if (matcher.find()) { Matcher ws = WS.matcher(text).region(matcher.end(), text.length()); int childOffset = ws.find() ? ws.end() : matcher.end(); String value = matcher.groupCount() > 0 && matcher.group(1) != null ? matcher.group(1) : matcher.group(0); return new BacktrackItem(childOffset, state, value); } } return null; }