加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

perl6 – 如何使Perl 6语法产生多个匹配(如:ex和:ov)?

发布时间:2020-12-16 06:19:48 所属栏目:大数据 来源:网络整理
导读:我想语法做这样的事情: "abc" ~~ m:ex/^ (w ** 1..2) (w ** 1..2) ${say $0,$1}/?ab??c??a??bc? 或者像这样: my regex left { S ** 1..2 } my regex right { S ** 1..2 } "abc" ~~ m:ex/^ leftright ${say $left,$right}/?ab??c??a??bc? 这是我的语法
我想语法做这样的事情:

> "abc" ~~ m:ex/^ (w ** 1..2) (w ** 1..2) ${say $0,$1}/
?ab??c?
?a??bc?

或者像这样:

> my regex left { S ** 1..2  }
> my regex right { S ** 1..2  }
> "abc" ~~ m:ex/^ <left><right> ${say $<left>,$<right>}/
?ab??c?
?a??bc?

这是我的语法:

grammar LR {
  regex TOP {
    <left> 
    <right>
  }
  regex left {
    w ** 1..2 
  }
  regex right {
    w ** 1..2 
  }
}

my $string = "abc";
my $match = LR.parse($string);
say "input: $string";
printf "split: %s|%sn",~$match<left>,~$match<right>;

它的输出是:

$input: abc
$split: ab|c

所以,< left>可能只是贪婪而没有任何东西给< right>.我应该如何修改代码以匹配两种可能的变体?

$input: abc
$split: a|bc,ab|c

解决方法

语法被设计为给出零或一个答案,而不是更多,因此你必须使用一些技巧使它们做你想要的.

由于Grammar.parse只返回一个Match对象,因此您必须使用不同的方法来获取所有匹配项:

sub callback($match) {
    say $match;
}
grammar LR {
    regex TOP {
        <left> 
        <right>
        $
        { callback($/) }
        # make the match fail,thus forcing backtracking:
        <!>
    }
    regex left {
        w ** 1..2 
    }
    regex right {
        w ** 1..2 
    }
}

LR.parse('abc');

通过调用<!>使匹配失败断言(总是失败)迫使先前的原子回溯,从而找到不同的解决方案.当然,这使得语法不再可重用,因为它在语法的常规调用约定之外工作.

请注意,对于调用者,LR.parse似乎总是失败;你得到所有匹配作为回调函数的调用.

一个稍微好一点的API(但下面的方法相同)是使用gather / take来获取所有匹配的序列:

grammar LR {
    regex TOP {
        <left> 
        <right>
        $
        { take $/ }
        # make the match fail,thus forcing backtracking:
        <!>
    }
    regex left {
        w ** 1..2 
    }
    regex right {
        w ** 1..2 
    }
}

.say for gather LR.parse('abc');

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读