14 March 2018

Who ordered that (array)?

You know how it is when coming back to some code after days, weeks or in this case, maybe even months away? I'm going through that right now, and thought I'd talk about one issue I just ran into. While reworking the actions for the ANTLR4 translator, I really don't want to rewrite the grammar. It passes the full ANTLR4 corpus, and I don't want to touch that.

So I've just finished rewriting a bunch of tests, and am ready to capture ANTLR tokens so that I can rewrite them into Perl 6. The match object looks like this when you dump it ("dump" is a bit overblown - in other languages you might need a separate Dump() method, in Perl 6 "say $/" is all you need.):

prequelConstruct => 「tokens { INDENT }」
 tokensSpec => 「tokens { INDENT }」
  token_list_trailing_comma => 「INDENT 」
   tokenName => 「INDENT」
    ID => 「INDENT」

But when I started trying to capture the 'INDENT' text with $/<prequelConstruct><tokensSpec><token_list_trailing_comma>, I get this weird error:

Type Array does not support associative indexing.
  in method TOP at /home/jgoff/perl6-ANTLR4/lib/ANTLR4/Actions/Perl6.pm6 (ANTLR4::Actions::Perl6) line 88

But... but... it's just prequelConstruct containing a tokensSpec and so on, I don't see any arrays involved. Now, if I were using 'dd' rather than the built-in stringifier I'd probably see the problem right away. Unfortunately if you're using the default 'say $/' stringifier, there's no easy way to see what's going on. What's happening here is the prequelConstruct actually contains an array of matches, but the default 'say' output won't show you this.

Thankfully, Perl 6, just like its sister Perl 5, encourages experimentation. If you back off and just use 'say $/<prequelConstruct>;', that will work. When you add '<tokensSpec>', which looks like what should be the next layer down, you'll get the 'Type Array...' error, which will tell you that prequelConstruct contains an array of stuff. 'dd' should tell you more clearly what portion of the match is an array, and what are hash keys, and I'd recommend using that to clarify what's going on. This is just a little posting to help people debug what I suspect is a common confusion.

Thank you again, dear reader. Comments, clarifications and questions are of course welcome.