4
我拿了一個虛擬語言,例如: 它只是接受一個或多個'!'。 其詞法和語法規則是:如何捕捉antlr3的樹語法中的標記列表?
grammar Ns;
options {
output=AST;
ASTLabelType=CommonTree;
}
tokens {
NOTS;
}
@header {
package test;
}
@lexer::header {
package test;
}
ns : NOT+ EOF -> ^(NOTS NOT+);
NOT : '!';
OK,你可以看到,這代表其接受的語言「!」要麼 '!!!'或「!!!!!」 ......
,我定義了一些有意義的類來建立的AST:
public class Not {
public static final Not SINGLETON = new Not();
private Not() {
}
}
public class Ns {
private List<Not> nots;
public Ns(String nots) {
this.nots = new ArrayList<Not>();
for (int i = 0; i < nots.length(); i++) {
this.nots.add(Not.SINGLETON);
}
}
public String toString() {
String ret = "";
for (int i = 0; i < this.nots.size(); i++) {
ret += "!";
}
return ret;
}
}
和這裏的樹語法:
tree grammar NsTreeWalker;
options {
output = AST;
tokenVocab = Ns;
ASTLabelType = CommonTree;
}
@header {
package test;
}
ns returns [Ns ret] : ^(NOTS n=NOT+) {$ret = new Ns($n.text);};
和主類代碼一些樣本數據來檢驗生成的類:「!」
public class Test {
public static void main(String[] args) throws Exception {
ANTLRInputStream input = new ANTLRInputStream(new ByteArrayInputStream("!!!".getBytes("utf-8")));
NsLexer lexer = new NsLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
NsParser parser = new NsParser(tokens);
CommonTree root = (CommonTree) parser.ns().getTree();
NsTreeWalker walker = new NsTreeWalker(new CommonTreeNodeStream(root));
try {
NsTreeWalker.ns_return r = walker.ns();
System.out.println(r.ret);
} catch (RecognitionException e) {
e.printStackTrace();
}
}
}
但打印的最終輸出是,除了t他期待'!!!'。 這主要是因爲這行代碼:
ns returns [Ns ret] : ^(NOTS n=NOT+) {$ret = new Ns($n.text);};
的$ N以上捕獲只有一個,我不知道如何捕捉的所有三個令牌,換句話說,一個列表「!」「!」 '!'與$ n。 有沒有人可以幫忙?謝謝!