Is the @headers
and @members
options only used in the Java target? For example, to test a simple import, I added the following to my grammar:
# TestParser.g4
parser grammar TestParser;
options {tokenVocab=TestLexer;}
@headers {import fs;} // <-- this part here
root : cost EOF;
cost : CURRENCY NUMBER;
# TestLexer.g4
lexer grammar TestLexer;
CURRENCY: [$€] ;
NUMBER : [0-9] ;
WS : [ \n\r\t] -> skip;
And when I do the JS
target output with:
$ antlr4 -Dlanguage=JavaScript *.g4
There is no fs
import in any of the generated JS files. What would be an example of how it could be used in JS?
CodePudding user response:
@headers
and @members
are just inserted into your generated code at a specific location. As such, they will generally make a grammar target-language specific. Occasionally, if you use a couple of languages with similar enough syntax, you might get lucky that the same inserted text "just works", but it's unlikely.
They're handy if you know you'll only target one language for generated parsers.
You may find that, by using the -DsuperClass=XXXX
command line option, you can have the parser inherit from your own super class where you could inject some special functionality you want. You would write a class that subclasses the Parser
class (the normal superClass for generated Parsers), and then have the generated code inherit from your class. (You'd have to implement that superclass in each target language)
Often, using these options is an indication that you may be trying to do too much in the parser/grammar. It's generally a good idea to make your grammar "just good enough" to unambiguously, correctly, recognize your input (even if it also matches some potentially invalid input. You can always check for that situation in a listener or visitor (and often provide a better error message than you might get out of straight ANTLR).
CodePudding user response:
These are so-called named actions. They are used to allow the grammar writer to specify text that should go into the generated code. This can be anything from copyright notices to imports/includes up to specific target code or linter/formatter comments.
Originally only two named actions were supported, namely @header and @members. That is good enough for the Java target (and others), but for specific targets (like C ) many more named actions have been defined, but they all serve only one goal: to insert text at specific locations in the generated code.
Note also that named actions can be specified with or w/o a scope. A scope determines if that action applies only to lexer or parser code, or both (if no scope is given). Scopes can only be used in combined grammars. Here's the list of possible combinations:
- @parser::header
- @parser::members
- @lexer::header
- @lexer::members
The C target defines many more, however.