The superClass=... option is used to have your Parser extend the custom class. So, I do not think that this is what you need.
Everything inside the @header section will be placed at the beginning of your Parser class. This is used to import classes:
@header { import java.io.PrintWriter; }
Please note that @header {...} not suitable for @parser::header {...} . You can also define: @lexer::header {...} for your lexer.
And inside the @member {...} sections (or: @parser::member {...} , @lexer::member {...} ) you can add instance variables and methods that can be used internally or Parser or Lexer :
@header { import java.io.PrintWriter; } @members { PrintWriter writer; }
A small demonstration of grammar, the parser of which will write the analyzed numbers to a specific writer:
grammar T; @header { import java.io.PrintWriter; } @members { PrintWriter writer; public TParser(TokenStream input, String fileName) { super(input); try { writer = new PrintWriter(fileName); } catch(Exception e) { e.printStackTrace(); } } } parse : numbers EOF ; numbers : (NUM { writer.println("parsed: " + $NUM.text); writer.flush(); } )+ ; NUM : '0'..'9'+; WS : ' ' {skip();};
which can be tested with:
import java.io.File; import org.antlr.runtime.*; public class Main { public static void main(String[] args) throws Exception { String source = "42 500000000 666"; TLexer lexer = new TLexer(new ANTLRStringStream(source)); TParser parser = new TParser(new CommonTokenStream(lexer), "log.txt"); parser.parse(); } }
If you run the class above, a file called log.txt was created containing:
parsed: 42 parsed: 500000000 parsed: 666
Note that there is a strict ordering of all these @... and options {...} , etc. copies:
grammar definitionoptions block (no @ sign!)tokens block (no @ sign!)@header block@members block
grammar T; options { // options here } tokens { // imaginary tokens here } @header { // ... } @members { // ... }
EDIT
ANTLRStarter wrote:
How to add code that runs at the end of the lexer / parser class?
There are no built-in functions for such a thing. But you can easily create your own wrapUp() method in your parser:
@members { // ... private void wrapUp() { // wrap up your parser in here } }
and then automatically call this method from the entry point of your grammar as follows:
parse @after {this.wrapUp();} : numbers EOF ;
Any code placed in the @after {...} block of the rule is executed when all the rules are correct.