Regexp::Grammars 调试成功,不调试失败

Regexp::Grammars Succeeds with Debug and Fails Without

我有一个 Regexp::Grammars 语法无法匹配,但是当我打开调试时成功了:

#!/usr/bin/env perl

use feature 'say';

my $parser = do {
  use Regexp::Grammars;
  qr{
#    <debug:step>

    \A <command> \Z

    <token: command>
       <.identifier>+ %% [:]{2} 

    <token: identifier>
       [a-zA-Z0-9_]+
  };
};

my $input = 'foo::bar';

if ($input =~ $parser) {
  use Data::Dumper; say Data::Dumper::Dumper(\%/);
}
else {
  say 'Parse failed!';
}
$ ./grammar_problem.pl
Parse failed!

打开调试让我:

#!/usr/bin/env perl

use feature 'say';

my $parser = do {
  use Regexp::Grammars;
  qr{
    <debug:step>

    \A <command> \Z

    <token: command>
       <.identifier>+ %% [:]{2} 

    <token: identifier>
       [a-zA-Z0-9_]+
  };
};

my $input = 'foo::bar';

if ($input =~ $parser) {
  use Data::Dumper; say Data::Dumper::Dumper(\%/);
}
else {
  say 'Parse failed!';
}
$ ./grammar_problem.pl
=======> Trying <grammar> from position 0
foo::bar |...Trying subpattern /\A/ 
         |    \_____subpattern /\A/ matched ''  
         |...Trying <command>   
         |   |...Trying <.identifier>   
         |   |   |...Trying subpattern /[a-zA-Z0-9_]+/  
::bar    |   |   |    \_____subpattern /[a-zA-Z0-9_]+/ matched 'foo'    
         |   |    \_____<.identifier> matched 'foo' 
         |   |...Trying subpattern /[:]{2}/ 
bar      |   |    \_____subpattern /[:]{2}/ matched '::'    
         |   |...Trying <.identifier>   
         |   |   |...Trying subpattern /[a-zA-Z0-9_]+/  
[eos]    |   |   |    \_____subpattern /[a-zA-Z0-9_]+/ matched 'bar'    
         |   |    \_____<.identifier> matched 'bar' 
         |   |...Trying subpattern /[:]{2}/ 
         |   |    \FAIL subpattern /[:]{2}/
         |   |...Trying subpattern /[:]{2}/ 
         |   |    \FAIL subpattern /[:]{2}/
         |    \_____<command> matched 'foo::bar'    
         |...Trying subpattern /\Z/ 
         |    \_____subpattern /\Z/ matched ''  
$VAR1 = {
          '' => 'foo::bar',
          'command' => 'foo::bar'
        };

知道这里发生了什么吗?谢谢! Stack Overflow 说我需要更多详细信息才能提交,但我不知道还能说什么。打字来解决这个问题。我向 reader!

致歉

我认为这与 %% 运算符的工作方式有关(并且是一个很棒的小工具)。您需要在其后对子规则进行分组:

  qr{
    (?: \A <command> \Z )

    <rule: command>
       <.identifier>+ %% (::)

    <rule: identifier>
       [a-zA-Z0-9_]+
  }x;

Regexp::Grammars 模块非常强大,但您还需要完全按照指定的方式获取内容(这并不总是很清楚)。

在文档中查找此短语:

Note that, if a pattern is used to specify the separator, it must be specified in some kind of matched parentheses.

现在,打开 debug 的问题很有趣。这会在您的整个模式中插入代码,所以我的猜测是,无论发生什么情况,您使用的子模式周围都有一些括号(可能也包含调试代码)。这满足了语法,嗯,语法并且它起作用了。