gpt4 book ai didi

perl - 我如何让马尔巴序列规则变得贪婪?

转载 作者:行者123 更新时间:2023-12-01 09:56:31 27 4
gpt4 key购买 nike

我正在研究 Marpa::R2将文本中的项目分组的语法。每个组只能包含特定种类的项目,但未明确定界。这会导致问题,因为 x...x(其中 . 表示可以属于组的项目)可以分组为 x(... )x, x(..)(.)x, x(.)(..)x, x(.)(. )(.)x。换句话说,语法是高度歧义的。

如果我只想要 x(...)x 解析,我怎样才能消除这种歧义,即如果我想强制 + 量词只表现“贪心”(就像在 Perl 正则表达式中一样)?

在下面的语法中,我尝试将 rank 副词添加到序列规则中,以使 Group 优先于 Sequence,但事实并非如此似乎不起作用。

下面是一个测试这个行为的案例。

use strict;
use warnings;

use Marpa::R2;
use Test::More;

my $grammar_source = <<'END_GRAMMAR';
inaccessible is fatal by default
:discard ~ space
:start ::= Sequence

Sequence
::= SequenceItem+ action => ::array
SequenceItem
::= WORD action => ::first
| Group action => ::first
Group
::= GroupItem+ action => [name, values]
GroupItem
::= ('[') Sequence (']') action => ::first

WORD ~ [a-z]+
space ~ [\s]+
END_GRAMMAR

my $input = "foo [a] [b] bar";

diag "perl $^V";
diag "Marpa::R2 " . Marpa::R2->VERSION;

my $grammar = Marpa::R2::Scanless::G->new({ source => \$grammar_source });
my $recce = Marpa::R2::Scanless::R->new({ grammar => $grammar });

$recce->read(\$input);

my $parse_count = 0;
while (my $value = $recce->value) {
is_deeply $$value, ['foo', [Group => ['a'], ['b']], 'bar'], 'expected structure'
or diag explain $$value;
$parse_count++;
}
is $parse_count, 1, 'expected number of parses';

done_testing;

测试用例的输出(失败):

# perl v5.18.2
# Marpa::R2 2.09
ok 1 - expected structure
not ok 2 - expected structure
# Failed test 'expected structure'
# at - line 38.
# Structures begin differing at:
# $got->[1][2] = Does not exist
# $expected->[1][2] = ARRAY(0x981bd68)
# [
# 'foo',
# [
# 'Group',
# [
# 'a'
# ]
# ],
# [
# ${\$VAR1->[1][0]},
# [
# 'b'
# ]
# ],
# 'bar'
# ]
not ok 3 - expected number of parses
# Failed test 'expected number of parses'
# at - line 41.
# got: '2'
# expected: '1'
1..3
# Looks like you failed 2 tests of 3.

最佳答案

序列规则是为非棘手的情况设计的。当事情变得棘手时,序列规则总是可以重写为 BNF 规则,这就是我在这里的建议。以下使您的测试工作:

use strict;
use warnings;

use Marpa::R2;
use Test::More;

my $grammar_source = <<'END_GRAMMAR';
inaccessible is fatal by default
:discard ~ space

# Three cases
# 1.) Just one group.
# 2.) Group follows by alternating words and groups.
# 3.) Alternating words and groups, starting with words
Sequence ::= Group action => ::first
Sequence ::= Group Subsequence action => [values]
Sequence ::= Subsequence action => ::first

Subsequence ::= Words action => ::first

# "action => [values]" makes the test work unchanged.
# The action for the next rule probably should be
# action => [name, values] in order to handle the general case.
Subsequence ::= Subsequence Group Words action => [values]

Words ::= WORD+ action => ::first
Group
::= GroupItem+ action => [name, values]
GroupItem
::= ('[') Sequence (']') action => [value]

WORD ~ [a-z]+
space ~ [\s]+
END_GRAMMAR

my $input = "foo [a] [b] bar";

diag "perl $^V";
diag "Marpa::R2 " . Marpa::R2->VERSION;

my $grammar = Marpa::R2::Scanless::G->new( { source => \$grammar_source } );
my $recce = Marpa::R2::Scanless::R->new( { grammar => $grammar } );

$recce->read( \$input );

my $parse_count = 0;
while ( my $value = $recce->value ) {
is_deeply $$value, [ 'foo', [ Group => ['a'], ['b'] ], 'bar' ],
'expected structure'
or diag explain $$value;
$parse_count++;
} ## end while ( my $value = $recce->value )
is $parse_count, 1, 'expected number of parses';

done_testing;

关于perl - 我如何让马尔巴序列规则变得贪婪?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25593241/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com