package edu.stanford.nlp.ling.tokensregex;
import java.util.function.Function;
import edu.stanford.nlp.util.Interval;
import edu.stanford.nlp.util.StringUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Basic results for a Sequence Match
*
* @author Angel Chang
*/
public class BasicSequenceMatchResult<T> implements SequenceMatchResult<T>
{
SequencePattern<T> pattern; // Pattern we matched against
List<? extends T> elements; // Original sequence
MatchedGroup[] matchedGroups; // Groups that we matched
Object[] matchedResults; // Additional information about matches (per element)
Function<List<? extends T>, String> nodesToStringConverter;
SequencePattern.VarGroupBindings varGroupBindings;
double score = 0.0;
double priority = 0.0;
int order;
@Override
public List<? extends T> elements() { return elements; }
@Override
public SequencePattern<T> pattern() { return pattern; }
// public static <T> BasicSequenceMatchResult<T> toBasicSequenceMatchResult(List<? extends T> elements) {
// BasicSequenceMatchResult<T> matchResult = new BasicSequenceMatchResult<T>();
// matchResult.elements = elements;
// matchResult.matchedGroups = new MatchedGroup[0];
// return matchResult;
// }
@Override
public BasicSequenceMatchResult<T> toBasicSequenceMatchResult() {
return copy();
}
public BasicSequenceMatchResult<T> copy() {
BasicSequenceMatchResult<T> res = new BasicSequenceMatchResult<>();
res.pattern = pattern;
res.elements = elements;
res.matchedGroups = new MatchedGroup[matchedGroups.length];
res.nodesToStringConverter = nodesToStringConverter;
res.score = score;
res.priority = priority;
res.order = order;
res.varGroupBindings = varGroupBindings;
for (int i = 0; i < matchedGroups.length; i++ ) {
if (matchedGroups[i] != null) {
res.matchedGroups[i] = new MatchedGroup(matchedGroups[i]);
}
}
if (matchedResults != null) {
res.matchedResults = new Object[matchedResults.length];
System.arraycopy(res.matchedResults, 0, matchedResults, 0, matchedResults.length);
}
return res;
}
@Override
public Interval<Integer> getInterval() {
return TO_INTERVAL.apply(this);
}
@Override
public int getOrder() {
return order;
}
public void setOrder(int order) {
this.order = order;
}
@Override
public double priority() {
return priority;
}
@Override
public double score() {
return score;
}
@Override
public int start() {
return start(0);
}
@Override
public int start(int group) {
if (group == GROUP_BEFORE_MATCH) {
return 0;
} else if (group == GROUP_AFTER_MATCH) {
return matchedGroups[0].matchEnd;
}
if (matchedGroups[group] != null) {
return matchedGroups[group].matchBegin;
} else {
return -1;
}
}
@Override
public int start(String var) {
int g = getFirstVarGroup(var);
if (g >= 0) {
return start(g);
} else {
return -1;
}
}
@Override
public int end() {
return end(0);
}
@Override
public int end(int group) {
if (group == GROUP_BEFORE_MATCH) {
return matchedGroups[0].matchBegin;
} else if (group == GROUP_AFTER_MATCH) {
return elements.size();
}
if (matchedGroups[group] != null) {
return matchedGroups[group].matchEnd;
} else {
return -1;
}
}
@Override
public int end(String var) {
int g = getFirstVarGroup(var);
if (g >= 0) {
return end(g);
} else {
return -1;
}
}
@Override
public String group() {
return group(0);
}
@Override
public String group(int group) {
List<? extends T> groupTokens = groupNodes(group);
if (nodesToStringConverter == null) {
return (groupTokens != null)? StringUtils.join(groupTokens, " "): null;
} else {
return nodesToStringConverter.apply(groupTokens);
}
}
@Override
public String group(String var) {
int g = getFirstVarGroup(var);
if (g >= 0) {
return group(g);
} else {
return null;
}
}
@Override
public List<T> groupNodes() {
return groupNodes(0);
}
@Override
public List<T> groupNodes(int group) {
if (group == GROUP_BEFORE_MATCH || group == GROUP_AFTER_MATCH) {
// return a new list so the resulting object is serializable
return new ArrayList<>(elements.subList(start(group), end(group)));
}
if (matchedGroups[group] != null) {
// return a new list so the resulting object is serializable
return new ArrayList<>(elements.subList(matchedGroups[group].matchBegin, matchedGroups[group].matchEnd));
} else {
return null;
}
}
@Override
public List<? extends T> groupNodes(String var) {
int g = getFirstVarGroup(var);
if (g >= 0) {
return groupNodes(g);
} else {
return null;
}
}
@Override
public Object groupValue() {
return groupValue(0);
}
@Override
public Object groupValue(int group) {
if (group == GROUP_BEFORE_MATCH || group == GROUP_AFTER_MATCH) {
// return a new list so the resulting object is serializable
return new ArrayList<>(elements.subList(start(group), end(group)));
}
if (matchedGroups[group] != null) {
return matchedGroups[group].value;
} else {
return null;
}
}
@Override
public Object groupValue(String var) {
int g = getFirstVarGroup(var);
if (g >= 0) {
return groupValue(g);
} else {
return null;
}
}
@Override
public MatchedGroupInfo<T> groupInfo() {
return groupInfo(0);
}
@Override
public MatchedGroupInfo<T> groupInfo(int group) {
List<? extends T> nodes = groupNodes(group);
if (nodes != null) {
Object value = groupValue(group);
String text = group(group);
List<Object> matchedResults = groupMatchResults(group);
String varName = group >= this.varGroupBindings.varnames.length ? null : this.varGroupBindings.varnames[group];
return new MatchedGroupInfo<>(text, nodes, matchedResults, value, varName);
} else {
return null;
}
}
@Override
public MatchedGroupInfo<T> groupInfo(String var) {
int g = getFirstVarGroup(var);
if (g >= 0) {
return groupInfo(g);
} else {
return null;
}
}
@Override
public int groupCount() {
return matchedGroups.length-1;
}
@Override
public List<Object> groupMatchResults() {
return groupMatchResults(0);
}
@Override
public List<Object> groupMatchResults(int group) {
if (matchedResults == null) return null;
if (group == GROUP_BEFORE_MATCH || group == GROUP_AFTER_MATCH) {
return Arrays.asList(Arrays.copyOfRange(matchedResults, start(group), end(group)));
}
if (matchedGroups[group] != null) {
return Arrays.asList(Arrays.copyOfRange(matchedResults, matchedGroups[group].matchBegin, matchedGroups[group].matchEnd));
} else {
return null;
}
}
@Override
public List<Object> groupMatchResults(String var) {
int g = getFirstVarGroup(var);
if (g >= 0) {
return groupMatchResults(g);
} else {
return null;
}
}
@Override
public Object nodeMatchResult(int index) {
if (matchedResults != null) {
return matchedResults[index];
} else {
return null;
}
}
@Override
public Object groupMatchResult(int group, int index) {
if (matchedResults != null) {
int s = start(group);
int e = end(group);
if (s >= 0 && e > s) {
int d = e - s;
if (index >= 0 && index < d) {
return matchedResults[s+index];
}
}
}
return null;
}
@Override
public Object groupMatchResult(String var, int index) {
int g = getFirstVarGroup(var);
if (g >= 0) {
return groupMatchResult(g, index);
} else {
return null;
}
}
private int getFirstVarGroup(String v)
{
// Trim the variable...
v = v.trim();
for (int i = 0; i < varGroupBindings.varnames.length; i++) {
String s = varGroupBindings.varnames[i];
if (v.equals(s)) {
if (matchedGroups[i] != null) {
return i;
}
}
}
return -1;
}
protected static class MatchedGroup
{
int matchBegin = -1;
int matchEnd = -1;
Object value = null;
protected MatchedGroup(MatchedGroup mg) {
this.matchBegin = mg.matchBegin;
this.matchEnd = mg.matchEnd;
this.value = mg.value;
}
protected MatchedGroup(int matchBegin, int matchEnd, Object value) {
this.matchBegin = matchBegin;
this.matchEnd = matchEnd;
this.value = value;
}
public String toString()
{
return "(" + matchBegin + ',' + matchEnd + ')';
}
public int matchLength() {
if (matchBegin >= 0 && matchEnd >= 0) {
return matchEnd - matchBegin;
} else {
return -1;
}
}
}
}