prototype xpath

This commit is contained in:
Terence Parr 2013-09-12 17:22:02 -07:00
parent 211f69d0f1
commit a86895c557
2 changed files with 23 additions and 17 deletions

View File

@ -38,7 +38,9 @@ import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.io.Writer; import java.io.Writer;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map;
public class Utils { public class Utils {
// Seriously: why isn't this built in to java? ugh! // Seriously: why isn't this built in to java? ugh!
@ -133,4 +135,15 @@ public class Utils {
t.join(); t.join();
} }
/** Convert array of strings to string->index map. Useful for
* converting rulenames to name->ruleindex map.
*/
public static Map<String, Integer> toMap(String[] keys) {
Map<String, Integer> m = new HashMap<String, Integer>();
for (int i=0; i<keys.length; i++) {
m.put(keys[i], i);
}
return m;
}
} }

View File

@ -2,27 +2,26 @@ package org.antlr.v4.runtime.tree.xpath;
import org.antlr.v4.runtime.Parser; import org.antlr.v4.runtime.Parser;
import org.antlr.v4.runtime.ParserRuleContext; import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.misc.Utils;
import org.antlr.v4.runtime.tree.ParseTree; import org.antlr.v4.runtime.tree.ParseTree;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
/** Represent a subset of XPath paths for use in identifying nodes in /** Represent a subset of XPath path syntax for use in identifying nodes in
* parse trees. * parse trees.
* *
* Split path into words and separators / and // then walk from left to right. * Split path into words and separators / and // then walk from left to right.
* At each separator-word pair, find set of nodes. Next stage uses those as * At each separator-word pair, find set of nodes. Next stage uses those as
* work list. * work list.
* *
* See TestXPath * See {@link org.antlr.v4.test.TestXPath} for descriptions.
* *
* The "root" is relative to the node passed to evaluate().
*/ */
public class XPath { public class XPath {
public static final String WILDCARD = "*"; // word not operator/separator public static final String WILDCARD = "*"; // word not operator/separator
@ -71,9 +70,12 @@ public class XPath {
return elements.toArray(new XPathElement[0]); return elements.toArray(new XPathElement[0]);
} }
public XPathElement getXPathElement(String word, boolean anywhere) { /** Convert word like * or ID or expr to a path element. anywhere is true
Map<String, Integer> ruleIndexes = toMap(parser.getRuleNames()); * if // preceds the word.
Map<String, Integer> tokenTypes = toMap(parser.getTokenNames()); */
protected XPathElement getXPathElement(String word, boolean anywhere) {
Map<String, Integer> ruleIndexes = Utils.toMap(parser.getRuleNames());
Map<String, Integer> tokenTypes = Utils.toMap(parser.getTokenNames());
if ( word.equals(WILDCARD) ) { if ( word.equals(WILDCARD) ) {
return anywhere ? return anywhere ?
new XPathWildcardAnywhereElement() : new XPathWildcardAnywhereElement() :
@ -91,8 +93,8 @@ public class XPath {
} }
} }
// following java xpath like methods; not sure it's best way
/** Return a list of all nodes starting at t as root that satisfy the path. /** Return a list of all nodes starting at t as root that satisfy the path.
* The root / is relative to the node passed to evaluate().
*/ */
public Collection<ParseTree> evaluate(final ParseTree t) { public Collection<ParseTree> evaluate(final ParseTree t) {
ParserRuleContext dummyRoot = new ParserRuleContext(); ParserRuleContext dummyRoot = new ParserRuleContext();
@ -119,13 +121,4 @@ public class XPath {
return work; return work;
} }
public static Map<String, Integer> toMap(String[] keys) {
Map<String, Integer> m = new HashMap<String, Integer>();
for (int i=0; i<keys.length; i++) {
m.put(keys[i], i);
}
return m;
}
} }