我有表達一個平凡的ANTLR語法像a.b.c + d.e.f
匹配:ANTLR的樹模式與重寫規則
grammar Test;
options {
output=AST;
}
tokens {
VARIABLE_ID;
QUALIFIER_ID;
}
ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*;
DOT : '.';
WS : (' ' | '\t' | '\r' | '\n') {$channel=HIDDEN;} ;
variable_id : id=ID -> VARIABLE_ID[$id];
qualifier_id : id=ID -> QUALIFIER_ID[$id];
expr_start : expr EOF;
expr : var (options {greedy=true;} : '+' expr)*;
var : variable_id (DOT qualifier_id)*;
現在我想要定義了這個語法,輪流a.b.c
爲0.1.2
模式匹配,所以我定義了一個樹模式匹配如下
tree grammar TestWalker;
options {
tokenVocab=Test;
ASTLabelType=CommonTree;
filter=true;
backtrack=true;
}
@members {
TokenRewriteStream tokens;
public void setTreeNodeStream(TreeNodeStream input) {
super.setTreeNodeStream(input);
tokens = (TokenRewriteStream)input.getTokenStream();
}
}
topdown : var;
variable_id [int i] : id=VARIABLE_ID {
tokens.replace($id.getToken(), "" + $i);
};
qualifier_id [int i] : id=QUALIFIER_ID {
tokens.replace($id.getToken(), "" + $i);
};
var
@init { int index = 0; }
: variable_id[index]
( DOT
{ ++index; }
qualifier_id[index]
)*;
然後我把一個小的測試程序:
import org.antlr.runtime.*;
import org.antlr.runtime.tree.*;
public class Main {
public static void main(String[] args) throws Exception {
TestLexer lex = new TestLexer(new ANTLRInputStream(System.in));
TokenStream tokens = new TokenRewriteStream(lex);
TestParser parser = new TestParser(tokens);
TestParser.expr_return expr = parser.expr();
CommonTreeNodeStream nodes = new CommonTreeNodeStream((Tree)expr.getTree());
nodes.setTokenStream(tokens);
TestWalker walker = new TestWalker(nodes);
walker.downup(expr.getTree());
System.out.println(tokens.toString());
}
}
當我運行這個程序與基本輸入,我看到了令人吃驚的結果:
a.b.c
- >0.b.c
a.b + d.e
- >0.b + 0.e
等。看起來,我的規則的(DOT qualifier_id)*
部分從來沒有匹配,我不明白爲什麼。我嘗試將自己的規則添加到Tree Pattern Match的自上而下和自下而上的部分。如果我從一個過濾器匹配器切換到一個完整的樹匹配器並添加規則來適當地分支'+'
的情況,它會起作用,但是當重寫只是一個更大的語法的較小片段時,這變得站不住腳。任何指針將不勝感激。
更新:使用antlr 3.3
太棒了!感謝您發佈解決方案+1。 – 2011-03-08 22:33:22