Named actions. overloaded constructors, and non-java targets

17 views
Skip to first unread message

Burt Harris

unread,
May 10, 2020, 4:02:56 PM5/10/20
to antlr-di...@googlegroups.com
The rows.g4 grammar from chapter 4 of the book begins like this:

   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?

Mike Lischke

unread,
May 11, 2020, 2:48:35 AM5/11/20
to antlr-discussion
Hi Burt,

It seems like this might benefit from an additional @parser named actions:
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?

For the C++ target I had to create 2 dozen new named actions: https://github.com/antlr/antlr4/blob/master/doc/cpp-target.md#named-actions


Reply all
Reply to author
Forward
0 new messages