I took a dummy language, for example: It just accepts one or more "!" . its lexers and grammar rules:
grammar Ns; options { output=AST; ASTLabelType=CommonTree; } tokens { NOTS; } @header { package test; } @lexer::header { package test; } ns : NOT+ EOF -> ^(NOTS NOT+); NOT : '!';
ok, as you can see, this is a language that accepts "!" or '!!!' or '!!!!!'...
and I defined some meaningful classes for building 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; } }
and here is the grammar of the tree:
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);};
and the main class code with some sample data for testing the generated classes:
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(); } } }
but the final print result is '!', except for the expected '!!!'. which is mainly because this line of code:
ns returns [Ns ret] : ^(NOTS n=NOT+) {$ret = new Ns($n.text);};
$ n above is captured by only one "!" I donβt know how to capture all three tokens! in other words, a list of "!" with $ n. Can anybody help? Thanks!
source share