grammar Rows;
@parser::members { // add members to generated RowsParser
int col;
public RowsParser(TokenStream input, int col) { // custom constructor
this(input);
this.col = col;
}
}
This approach can be hard to translate into other language targets, since it works (in Java) by generating a
overloaded constructor for the RowsParser class. Some languages don't support overloaded constructors, for example JavaScript / TypeScript. For a JavaScript target, we can translate the above into the following grammar:
grammar Rows;
@parser::members { // add members to generated RowsParser
this.col = arguments[1];
}
The reason this should work in the JavaScript target seems to be because the contents of the @parser::members gets emitted inside the constructor. (And in JavaScript, "arguments" can be used to access formal arguments passed to a function, even if they aren't declared.)
For TypeScript, the generated code isn't valid because @parser::members get emitted outside the context of the constructor, so that it can declare typed members. I tried this:
grammar Rows;
@parser::members { // add members to generated RowsParser
col: number = arguments[1];
}
But that fails because the `arguments` pseudo-variable isn't in scope.
It seems like this might benefit from an additional @parser named actions, perhaps @parser::constructor to replace (not overload) the parser's constructor with the additional col parameter.
Have any other ANTLR language targets faced a similar challenge, and/or extended the set of named actions for Parsers and Lexers beyond the ones supported in the Java target?
Perhaps the simplest approach is to abandon trying to use a constructor to customize the value in col, using a grammar like this:
grammar Rows;
@parser::members { // add members to generated RowsParser
public col: number = 1;
}
And then in the driver code, setting parser.col = argv[1] after constructing the object. Comments?