ANTLR @header, @parser, superClass option and io base file (Java)

I want to use parser actions with the main io (Java), e file. d. PrintWriter in ANTLR Grammar. Should I use the superClass option, or can I use @header? In both cases, how can I declare a PrintWriter object and how should I handle exceptions?

+4
source share
1 answer

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 definition
  • options 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.

+7
source

All Articles