jnthn / grammar-debugger

Grammar::Debugger and Grammer::Tracer Perl 6 modules
36 stars 20 forks source link

Internal "Cannot invoke this object" error #42

Open drforr opened 5 years ago

drforr commented 5 years ago

Requires two files - if I place the grammar into the test file the bug goes away. You can also comment out the <?before> alternation and the parse will complete. The complete error text is at the bottom of the file. I think something isn't correctly initializing $!state{'indent'} in the source, but I haven't figured out how to correctly initialize it.

-- Perl6/Parser/Pure/Grammar.pm6 -- {use Grammar::Debugger; grammar Perl6::Parser::Pure::Grammar { proto rule statement_control { <...> }

token statement_control:sym { }

rule statementlist { | <?before <.[)]}]>> # Commenting this out unbreaks the debugger | * }

rule TOP { } } } -- t/01-single-token.t -- use v6;

use Test; use Perl6::Parser::Pure::Grammar;

plan 1;

my $g = Perl6::Parser::Pure::Grammar.new;

ok $g.parse( Q{} ), Q{runs}; -- cut --

-- the error -- 6 t/01-single-tokens.t 1..1 TOP

r | statementlist Cannot invoke this object (REPR: Null; VMNull) in block at /home/jgoff/.rakudobrew/moar-master/install/share/perl6/site/sources/0915E37B99013FE906246809B378838A8288E251 (Grammar::Debugger) line 116 in regex statementlist at /home/jgoff/breaks-grammar-debugger/lib/Perl6/Parser/Pure/Grammar.pm6 (Perl6::Parser::Pure::Grammar) line 9 in block at /home/jgoff/.rakudobrew/moar-master/install/share/perl6/site/sources/0915E37B99013FE906246809B378838A8288E251 (Grammar::Debugger) line 123 in regex TOP at /home/jgoff/breaks-grammar-debugger/lib/Perl6/Parser/Pure/Grammar.pm6 (Perl6::Parser::Pure::Grammar) line 14 in block at /home/jgoff/.rakudobrew/moar-master/install/share/perl6/site/sources/0915E37B99013FE906246809B378838A8288E251 (Grammar::Debugger) line 123 in block at t/01-single-tokens.t line 10 -- cut here --

drforr commented 5 years ago

I should mention that this is XUbuntu Linux running in a Windows host, looking at the code in the area of failure reminded me of this.

Commenting out anything that touched $!state let me run the grammar to completion. After I did that, adding in any 'say' calls inside the cache-wrapped() call brought the problem back. 'say'ing outside the call works with no side effects, however.

vendethiel commented 5 years ago

FWIW the no precompilation workaround solved the issue I had on ubuntu

drforr commented 5 years ago

FWIW the no precompilation workaround solved the issue I had on ubuntu

Seems to work for me, thanks a lot!

drforr commented 5 years ago

It's even simpler than I suspected. Any grammar with a hyphen in a rule name should trigger the bug.

gdonald commented 5 years ago

I hit this same issue too. My quoted-string rule triggers it reliably:

  token single-quote { "'" }
  token double-quote { "\"" }
  token word { \w+ }
  rule phrase { <word> [<word>]* }
  rule single-quoted-string { <single-quote><phrase><single-quote> }
  rule double-quoted-string { <double-quote><phrase><double-quote> }
  rule quoted-string { [ <single-quoted-string> | <double-quoted-string> ] }

This code works fine if I don't include use Grammar::Tracer.

raiph commented 4 years ago

Me too. Problem goes away with no precompilation;. Thanks @vendethiel++.

I should have looked first but instead golfed before coming here to file a bug and finding this one. The following is probably all moot given that it's clearly related to precompilation. But one never knows and it's very different from the scenarios already covered and I don't want to waste what I've got just in case.

Here it is on glot.io: https://glot.io/snippets/ffrhmnf20i#

Main script:

use lib '.';
use foo;

Module foo:

say $*DISTRO;
use Grammar::Tracer;
grammar foo {
  token TOP       { <bar> | a }
  token bar       { <!before b> }
}
foo .parse: 'x'

displays in stdout:

debian (9.stretch)
TOP

and then on stderr:

===SORRY!===
Cannot invoke this object (REPR: Null; VMNull)

Curiously <!before .>, ?before, after, !after, ?after all fail with . or x but <before b> and <?before b> work while !before b and any after form still fails with b.