语法正则表达式独立匹配,但不一起匹配



这是我尝试解决每周挑战"实现支撑扩展"。 我在语法下面写了,这应该有效。但是没有。

grammar BraceExpansion
{
regex TOP          { <start-txt> <to-expand> <end-txt> }
regex start-txt    { <save-char>* }
regex end-txt      { <save-char>* }
token save-char    { <-[ " & ( ) ` ' ; < > | ]> }
token list-element { <-[ " ! $ & ( ) ` ' ; < > | ]> }
token alphanum     { <[ a..z A..Z 0..9 ]> }
token alpha        { <[ a..z A..Z ]> }
regex num          { -? <[ 0..9 ]>+ }
regex to-expand    { <range> | <list>  }
regex range        { <alpha-range> | <num-range> }
regex num-range    { { <num>  . . <num> [ . . <num> ]? } }
regex alpha-range  { { <alpha> . . <alpha> [ . .<num> ]? } }
regex list         { { <list-element>+ % ',' } }
}
say brace-expand( 'A{1..3}B{a..g..3}C{1,2}D' );
sub num-range( $match )
{
say "-NUM-";
my @num = |$match<range><num-range><num>.list>>.Int;
my @range = @num[0] ... @num[1];
my $steps = ( @num[2] // 1 ).abs;
@range.batch( $steps )>>.[0];
}

sub alpha-range( $match )
{
say "-ALPHA-";
my @num = |$match<range><alpha-range><alpha>.list>>.Str;
my @range = @num[0] ... @num[1];
my $steps = ( $match<range><alpha-range><num> // 1 ).abs;
@range.batch($steps)>>.[0];
}
sub list( $match )
{
say "-LIST-";
$match<list><list-element>.list>>.Str;
}
sub brace-expand( $str )
{
say "brace-expand( $str )";
my $match = BraceExpansion.parse( $str );
my @alternatives =
$match<range><num-range>   ?? num-range( $match )   !!
$match<range><alpha-range> ?? alpha-range( $match ) !!
$match<list>               ?? list( $match )        !!
();
say "A", @alternatives;
return $str
unless @alternatives;
@alternatives
.map( -> $element { $match<start-txt>.Str ~ $element ~ $match<end-txt>.Str } )
.map( -> $result  { brace-expand( $result ) } )
;
}

但是,如果我将 TOP 规则更改为

regex TOP          { <start-txt> <range> <end-txt> }

regex TOP          { <start-txt> <list> <end-txt> }

rangelist令牌独立工作,我得到了预期的输出。但是当我使用to-expand规则时,整个语法不匹配,我无法弄清楚为什么。修改有误吗?但如果是这样,那么<alpha-range> | <num-range>为什么有效呢?

....(时间流逝( ....

与此同时,我发现

regex TOP           { <start-txt> [ <range> | <list> ] <end-txt> } 

做我想做的事。但我的问题仍然存在,为什么它不能像上面那样工作?

匹配发生正常;您没有正确索引到匹配中。结果匹配的结构为:

start-txt => 「A{1..3}B{a..g..3}C」
save-char => 「A」
...
to-expand => 「{1,2}」
list => 「{1,2}」  # (or range)
...
end-txt => 「D」
save-char => 「D」
...

但是您正在像$match<list>一样索引到这个.您应该首先索引到<to-expand>中,例如$match<to-expand><list>.在线试用!

修改后的版本起作用的原因是,您正在删除to-expand的中间步骤,以便索引正常工作。

最新更新