blob: 8b726c05f61d1eac484ab7891ed4659f3d63f705 [file] [log] [blame]
package de.ids_mannheim.korap.query.serialize;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.antlr.v4.runtime.Parser;
import org.antlr.v4.runtime.tree.ParseTree;
public abstract class Antlr4AbstractSyntaxTree extends AbstractSyntaxTree {
/**
* Parser object deriving the ANTLR parse tree.
*/
protected Parser parser;
/**
* Returns the category (or 'label') of the root of a (sub-) ParseTree (ANTLR 4).
*
* @param node
* @return
*/
public String getNodeCat(ParseTree node) {
String nodeCat = node.toStringTree(parser);
Pattern p = Pattern.compile("\\((.*?)\\s"); // from opening parenthesis to 1st whitespace
Matcher m = p.matcher(node.toStringTree(parser));
if (m.find()) {
nodeCat = m.group(1);
}
return nodeCat;
}
/**
* Tests whether a certain node has a child by a certain name
*
* @param node The parent node.
* @param childCat The category of the potential child.
* @return true iff one or more children belong to the specified category
*/
public boolean hasChild(ParseTree node, String childCat) {
for (int i = 0; i < node.getChildCount(); i++) {
if (getNodeCat(node.getChild(i)).equals(childCat)) {
return true;
}
}
return false;
}
public boolean hasDescendant(ParseTree node, String childCat) {
for (int i = 0; i < node.getChildCount(); i++) {
ParseTree child = node.getChild(i);
if (getNodeCat(child).equals(childCat)) {
return true;
}
if (hasDescendant(child, childCat)) {
return true;
}
}
return false;
}
public static List<ParseTree> getChildren(ParseTree node) {
ArrayList<ParseTree> children = new ArrayList<ParseTree>();
for (int i = 0; i < node.getChildCount(); i++) {
children.add(node.getChild(i));
}
return children;
}
public List<ParseTree> getChildrenWithCat(ParseTree node, String nodeCat) {
ArrayList<ParseTree> children = new ArrayList<ParseTree>();
for (int i = 0; i < node.getChildCount(); i++) {
if (getNodeCat(node.getChild(i)).equals(nodeCat)) {
children.add(node.getChild(i));
}
}
return children;
}
public ParseTree getFirstChildWithCat(ParseTree node, String nodeCat) {
return getNthChildWithCat(node, nodeCat, 1);
}
public ParseTree getNthChildWithCat(ParseTree node, String nodeCat, int n) {
int counter = 0;
for (int i = 0; i < node.getChildCount(); i++) {
if (getNodeCat(node.getChild(i)).equals(nodeCat)) {
counter++;
if (counter == n) {
return node.getChild(i);
}
}
}
return null;
}
/**
* Checks whether a node only serves as a container for another node (e.g. in (cq_segment ( cg_seg_occ ...)), the cq_segment node does not contain
* any information and only contains the cq_seg_occ node.
* @param node The node to check
* @return true iff the node is a container only.
*/
public boolean isContainerOnly(ParseTree node) {
String[] validNodeNamesArray = "cq_segment sq_segment element empty_segments spanclass".split(" ");
List<String> validNodeNames = Arrays.asList(validNodeNamesArray);
List<ParseTree> children = getChildren(node);
for (ParseTree child : children) {
if (validNodeNames.contains(getNodeCat(child))) {
return false;
}
}
return true;
}
}