package edu.stanford.nlp.parser.lexparser;
import edu.stanford.nlp.trees.HeadFinder;
import edu.stanford.nlp.trees.Tree;
import edu.stanford.nlp.util.Generics;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* Extracts raw Nary rules from a treebank. They are returned as a Map from
* passive constituents to Lists of right-hand side rule "paths", each of which is a List.
*/
class PathExtractor extends AbstractTreeExtractor<Map<String, List<List<String>>>> {
private static final String END = "END";
//protected final Index<String> stateIndex;
private Map<String, List<List<String>>> allPaths = Generics.newHashMap();
private HeadFinder hf;
public PathExtractor(HeadFinder hf, Options op) {
super(op);
this.hf = hf;
}
private List<List<String>> getList(String key) {
List<List<String>> result = allPaths.get(key);
if (result == null) {
result = new ArrayList<>();
allPaths.put(key, result);
}
return result;
}
@Override
protected void tallyInternalNode(Tree lt, double weight) {
Tree[] children = lt.children();
Tree headChild = hf.determineHead(lt);
if (children.length == 1) {
return;
}
List<String> path = new ArrayList<>();
// determine which is the head
int headLoc = -1;
for (int i = 0; i < children.length; i++) {
if (children[i] == headChild) {
headLoc = i;
}
}
path.add(children[headLoc].label().value());
if (headLoc == 0) {
// we are finishing on the right
for (int i = headLoc + 1; i < children.length - 1; i++) {
path.add(children[i].label().value() + ">");
}
if (op.trainOptions.markFinalStates) {
path.add(children[children.length - 1].label().value() + "]");
} else {
path.add(children[children.length - 1].label().value() + ">");
}
} else {
// we are finishing on the left
for (int i = headLoc + 1; i < children.length; i++) {
path.add(children[i].label().value() + ">");
}
for (int i = headLoc - 1; i > 0; i--) {
path.add(children[i].label().value() + "<");
}
if (op.trainOptions.markFinalStates) {
path.add(children[0].label().value() + "[");
} else {
path.add(children[0].label().value() + "<");
}
}
path.add(END); // add epsilon at the end
String label = lt.label().value();
List<List<String>> l = getList(label);
l.add(path);
}
@Override
public Map<String, List<List<String>>> formResult() {
return allPaths;
}
}