
java_cup.runtime.SyntaxTreeXPath Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of javacup Show documentation
Show all versions of javacup Show documentation
A fork of the Java Cup parser generator with some bug fixes and enhancements. (Forked at version 11b)
The newest version!
package java_cup.runtime;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
public class SyntaxTreeXPath {
public static List query(String query, XMLElement element) {
if (query.startsWith("/")) query = query.substring(1);
return query0(new LinkedList(Arrays.asList(query.split("/"))), 0, element, 0);
}
private static List query0(List q, int idx, XMLElement element, int seq) {
if (q.get(idx).isEmpty()) { // match deeper descendant q[1]
return matchDeeperDescendant(q, idx + 1, element, seq);
}
List l = new LinkedList();
if (!match(q.get(idx), element, seq)) return new LinkedList();
if (q.size() - 1 == idx) return singleton(element);
List children = element.getChildren();
for (int i = 0; i < children.size(); i++) {
XMLElement child = children.get(i);
l.addAll(query0(q, idx + 1, child, i));
}
return l;
}
private static List matchDeeperDescendant(List query, int idx, XMLElement element, int seq) {
if (query.size() <= idx) return singleton(element);
boolean matches = match(query.get(idx), element, seq);
List l = new LinkedList();
List children = element.getChildren();
if (matches) return query0(query, idx, element, seq);
for (int i = 0; i < children.size(); i++) {
XMLElement child = children.get(i);
l.addAll(matchDeeperDescendant(query, idx, child, i));
}
return l;
}
private static boolean match(String m, XMLElement elem, int seq) {
// System.out.println("Matching "+elem.tagname+" with "+m);
boolean result = true;
String[] name = m.split("\\[");
String[] tag = name[0].split("\\*");
if (tag[0].isEmpty()) { // start is wildcard
if (tag.length > 2)
result &= elem.tagname.contains(tag[1]);
else if (tag.length == 2)
result &= elem.tagname.endsWith(tag[1]);
else
result &= false;
} else { // match with start
if (tag.length == 2)
result &= elem.tagname.startsWith(tag[1]);
else
result = elem.tagname.equals(tag[0]);
}
for (int i = 1; i < name.length; i++) {
String predicate = name[i];
if (!predicate.endsWith("]")) return false;
predicate = predicate.substring(0, predicate.length() - 1);
if (predicate.startsWith("@")) {
if (predicate.substring(1).startsWith("variant"))
if ((elem instanceof XMLElement.NonTerminal) && Integer.parseInt(predicate.substring(9)) == ((XMLElement.NonTerminal) elem).getVariant())
result &= true;
else
return false;
else return false;
} else if (predicate.matches("\\d+")) {
result &= Integer.parseInt(predicate) == seq;
} else
return false; // submatch
}
return result;
}
private static List singleton(XMLElement elem) {
LinkedList l = new LinkedList();
l.add(elem);
return l;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy