All Downloads are FREE. Search and download functionalities are using the official Maven repository.

java_cup.runtime.SyntaxTreeXPath Maven / Gradle / Ivy

Go to download

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