This commit is contained in:
Terence Parr 2013-11-22 11:31:59 -08:00
parent b2ec85d14d
commit 4c52a103e1
4 changed files with 47 additions and 35 deletions

View File

@ -126,4 +126,8 @@ public class ParseTreeMatch {
public ParseTree getTree() { public ParseTree getTree() {
return tree; return tree;
} }
public String toString() {
return tree.getText();
}
} }

View File

@ -65,7 +65,7 @@ public class ParseTreePattern {
ParseTreePatternMatcher p = new ParseTreePatternMatcher(lexer, parser); ParseTreePatternMatcher p = new ParseTreePatternMatcher(lexer, parser);
for (ParseTree t : subtrees) { for (ParseTree t : subtrees) {
ParseTreeMatch match = p.match(t, pattern, patternRuleName); ParseTreeMatch match = p.match(t, pattern, patternRuleName);
if ( !match.succeeded() ) { if ( match.succeeded() ) {
matches.add(match); matches.add(match);
} }
} }

View File

@ -162,7 +162,7 @@ public class ParseTreePatternMatcher {
/** Does pattern matched as a patternRuleName match tree? */ /** Does pattern matched as a patternRuleName match tree? */
public boolean matches(ParseTree tree, String pattern, String patternRuleName) { public boolean matches(ParseTree tree, String pattern, String patternRuleName) {
ParseTreePattern p = compile(patternRuleName, pattern); ParseTreePattern p = compile(pattern, patternRuleName);
return matches(tree, p); return matches(tree, p);
} }
@ -180,7 +180,7 @@ public class ParseTreePatternMatcher {
* or the node at which the match failed. * or the node at which the match failed.
*/ */
public ParseTreeMatch match(ParseTree tree, String pattern, String patternRuleName) { public ParseTreeMatch match(ParseTree tree, String pattern, String patternRuleName) {
ParseTreePattern p = compile(patternRuleName, pattern); ParseTreePattern p = compile(pattern, patternRuleName);
return match(tree, p); return match(tree, p);
} }
@ -195,6 +195,32 @@ public class ParseTreePatternMatcher {
return match; return match;
} }
/** For repeated use of a tree pattern, compile it to a ParseTreePattern
* using this method.
*/
public ParseTreePattern compile(String pattern, String patternRuleName) {
List<? extends Token> tokenList = tokenize(pattern);
ListTokenSource tokenSrc = new ListTokenSource(tokenList);
CommonTokenStream tokens = new CommonTokenStream(tokenSrc);
ParserInterpreter parserInterp = new ParserInterpreter(parser.getGrammarFileName(),
Arrays.asList(parser.getTokenNames()),
Arrays.asList(parser.getRuleNames()),
atnWithBypassAlts,
tokens);
ParseTree tree = null;
try {
Integer ruleIndex = ruleToIndex.get(patternRuleName);
tree = parserInterp.parse(ruleIndex);
// System.out.println("pattern tree = "+tree.toStringTree(parserInterp));
}
catch (Exception e) {
throw new CannotInvokeStartRule(e);
}
return new ParseTreePattern(patternRuleName, pattern, tree);
}
public Lexer getLexer() { public Lexer getLexer() {
return lexer; return lexer;
@ -284,7 +310,7 @@ public class ParseTreePatternMatcher {
if ( r.getChildCount()==1 && r.getChild(0) instanceof TerminalNode ) { if ( r.getChildCount()==1 && r.getChild(0) instanceof TerminalNode ) {
TerminalNode c = (TerminalNode)r.getChild(0); TerminalNode c = (TerminalNode)r.getChild(0);
if ( c.getSymbol() instanceof RuleTagToken ) { if ( c.getSymbol() instanceof RuleTagToken ) {
System.out.println("rule tag subtree "+t.toStringTree(parser)); // System.out.println("rule tag subtree "+t.toStringTree(parser));
return (RuleTagToken)c.getSymbol(); return (RuleTagToken)c.getSymbol();
} }
} }
@ -292,30 +318,6 @@ public class ParseTreePatternMatcher {
return null; return null;
} }
public ParseTreePattern compile(String patternRuleName, String pattern) {
List<? extends Token> tokenList = tokenize(pattern);
ListTokenSource tokenSrc = new ListTokenSource(tokenList);
CommonTokenStream tokens = new CommonTokenStream(tokenSrc);
ParserInterpreter parserInterp = new ParserInterpreter(parser.getGrammarFileName(),
Arrays.asList(parser.getTokenNames()),
Arrays.asList(parser.getRuleNames()),
atnWithBypassAlts,
tokens);
ParseTree tree = null;
try {
Integer ruleIndex = ruleToIndex.get(patternRuleName);
tree = parserInterp.parse(ruleIndex);
System.out.println("pattern tree = "+tree.toStringTree(parserInterp));
}
catch (Exception e) {
throw new CannotInvokeStartRule(e);
}
return new ParseTreePattern(patternRuleName, pattern, tree);
}
public List<? extends Token> tokenize(String pattern) { public List<? extends Token> tokenize(String pattern) {
// make maps for quick look up // make maps for quick look up
Map<String, Integer> tokenNameToType = Utils.toMap(parser.getTokenNames()); Map<String, Integer> tokenNameToType = Utils.toMap(parser.getTokenNames());
@ -332,16 +334,22 @@ public class ParseTreePatternMatcher {
// add special rule token or conjure up new token from name // add special rule token or conjure up new token from name
if ( Character.isUpperCase(tagChunk.tag.charAt(0)) ) { if ( Character.isUpperCase(tagChunk.tag.charAt(0)) ) {
Integer ttype = tokenNameToType.get(tagChunk.tag); Integer ttype = tokenNameToType.get(tagChunk.tag);
if ( ttype==null ) {
throw new IllegalArgumentException("Unknown token "+tagChunk.tag+" in pattern: "+pattern);
}
TokenTagToken t = new TokenTagToken(tagChunk.tag, ttype, tagChunk.label); TokenTagToken t = new TokenTagToken(tagChunk.tag, ttype, tagChunk.label);
tokens.add(t); tokens.add(t);
} }
else if ( Character.isLowerCase(tagChunk.tag.charAt(0)) ) { else if ( Character.isLowerCase(tagChunk.tag.charAt(0)) ) {
int ruleIndex = ruleNameToIndex.get(tagChunk.tag); Integer ruleIndex = ruleNameToIndex.get(tagChunk.tag);
if ( ruleIndex==null ) {
throw new IllegalArgumentException("Unknown rule "+tagChunk.tag+" in pattern: "+pattern);
}
int ruleImaginaryTokenType = atnWithBypassAlts.ruleToTokenType[ruleIndex]; int ruleImaginaryTokenType = atnWithBypassAlts.ruleToTokenType[ruleIndex];
tokens.add(new RuleTagToken(tagChunk.tag, ruleImaginaryTokenType, tagChunk.label)); tokens.add(new RuleTagToken(tagChunk.tag, ruleImaginaryTokenType, tagChunk.label));
} }
else { else {
System.err.println("invalid tag: "+tagChunk.tag); throw new IllegalArgumentException("invalid tag: "+tagChunk.tag+" in pattern: "+pattern);
} }
} }
else { else {
@ -357,12 +365,12 @@ public class ParseTreePatternMatcher {
} }
catch (IOException ioe) { catch (IOException ioe) {
// ----------------- // -----------------
System.err.println("what?-----------------"); throw new IllegalArgumentException("IOException lexing pattern: "+pattern, ioe);
} }
} }
} }
System.out.println("tokens="+tokens); // System.out.println("tokens="+tokens);
return tokens; return tokens;
} }

View File

@ -112,7 +112,7 @@ public class TestParseTreeMatcher extends BaseTest {
ParseTreePatternMatcher p = getMatcher("X2"); ParseTreePatternMatcher p = getMatcher("X2");
ParseTreePattern t = p.compile("s", "<ID> = <expr> ;"); ParseTreePattern t = p.compile("<ID> = <expr> ;", "s");
String results = t.patternTree.toStringTree(p.getParser()); String results = t.patternTree.toStringTree(p.getParser());
String expected = "(s <ID> = (expr <expr>) ;)"; String expected = "(s <ID> = (expr <expr>) ;)";
assertEquals(expected, results); assertEquals(expected, results);
@ -133,7 +133,7 @@ public class TestParseTreeMatcher extends BaseTest {
ParseTreePatternMatcher p = getMatcher("X2"); ParseTreePatternMatcher p = getMatcher("X2");
ParseTreePattern t = p.compile("s", "<ID> = <expr> ;"); ParseTreePattern t = p.compile("<ID> = <expr> ;", "s");
String results = t.patternTree.toStringTree(p.getParser()); String results = t.patternTree.toStringTree(p.getParser());
String expected = "(s <ID> = (expr <expr>) ;)"; String expected = "(s <ID> = (expr <expr>) ;)";
assertEquals(expected, results); assertEquals(expected, results);
@ -152,7 +152,7 @@ public class TestParseTreeMatcher extends BaseTest {
ParseTreePatternMatcher p = getMatcher("X2"); ParseTreePatternMatcher p = getMatcher("X2");
ParseTreePattern t = p.compile("s", "<ID> = <ID> ;"); ParseTreePattern t = p.compile("<ID> = <ID> ;", "s");
String results = t.patternTree.toStringTree(p.getParser()); String results = t.patternTree.toStringTree(p.getParser());
String expected = "(s <ID> = <ID> ;)"; String expected = "(s <ID> = <ID> ;)";
assertEquals(expected, results); assertEquals(expected, results);