如何使用 MARPA:R2 perl 解析/识别大表达式中的双引号字符串



解析/识别大表达式中的双引号字符串时出现问题。

use strict;
use Marpa::R2;
use Data::Dumper;
my $grammar = Marpa::R2::Scanless::G->new({
default_action => '[values]',
source => (<<'END_OF_SOURCE'),
:start ::= expression
expression ::= expression OP expression
expression ::= expression COMMA expression
expression ::= func LPAREN PARAM RPAREN
expression ::= PARAM
PARAM ::= STRING | REGEX_STRING
:discard    ~ sp
sp          ~ [s]+
COMMA                      ~ [,]
STRING                     ~ [^ /(),&:"~]+
REGEX_STRING               ~ yet to identify
OP                         ~ ' - ' | '&'
LPAREN                     ~ '('
RPAREN                     ~ ')'
func                       ~ 'func'
END_OF_SOURCE
});
my $recce = Marpa::R2::Scanless::R->new({grammar => $grammar});

my $input1 = "func(foo)&func(bar)";->能够通过将foo和bar解析为STRING LEXEME来正确解析它。

my $input2 = ""foo"";-> 在这里,我想将 foo 解析为 regex_string LEXEME。REGEX_STRING是用双引号括起来的东西。

my $input3 = "func("foo") - func("bar")";-> 在这里,func 应该被当作 func LEXEME,( 应该是 LPAREN,) 应该是 RPAREN,foo 作为 REGEX_STRING, - 作为 OP,对于 func(\"bar\") 也一样

my $input4 = "func("foo")";-> 在这里,func 应该被当作 func LEXEME,(应该是 LPAREN,) 应该是 RPAREN,foo 作为REGEX_STRING

print "Trying to parse:n$inputnn";
$recce->read($input);
my $value_ref = ${$recce->value};
print "Output:n".Dumper($value_ref);

我试了什么:第一种方法:我的REGEX_STRING应该是:REGEX_STRING -> ~ '"([^:]*?)"'

如果我尝试将上面的REGEX_STRING输入表达式放入代码中,my $input4 = "func("foo")";则会出现如下错误:

SLIF 解析中出现错误:在第 1 行第 5 列未找到词法 * 错误前的字符串:func( * 错误出现在第 1 行第 5 列和字符 0x0022 '"' 处,... * 此处:"foo") 马尔帕::R2 异常

第二种方法:

尝试包含如下规则:

PARAM ::= STRING | REGEX_STRING
REGEX_STRING ::= '"' QUOTED_STRING '"'
STRING ~ [^ /(),&:"~]+
QUOTED_STRING ~ [^ ,&:"~]+

这里的问题是 ->输入是使用以下方法给出的:

my $input4 = "func("foo")";

所以,这里它给出了错误,因为现在有两种方法可以解析这个表达式,要么是双引号之间的整个东西,即 func(\"foo\") 被当作QUOTED_STRING或func应该被当作func LEXEME等等。

请帮助我如何解决这个问题。

use 5.026;
use strictures;
use Data::Dumper qw(Dumper);
use Marpa::R2 qw();
my $grammar = Marpa::R2::Scanless::G->new({
bless_package => 'parsetree',
source        => <<'',
:default ::= action => [values] bless => ::lhs
lexeme default = bless => ::name latm => 1
:start ::= expression
expression ::= expression OP expression
expression ::= expression COMMA expression
expression ::= func LPAREN PARAM RPAREN
expression ::= PARAM
PARAM ::= STRING | REGEXSTRING
:discard    ~ sp
sp          ~ [s]+
COMMA           ~ [,]
STRING          ~ [^ /(),&:"~]+
REGEXSTRING     ::= '"' QUOTEDSTRING '"'
QUOTEDSTRING    ~ [^ ,&:"~]+
OP              ~ ' - ' | '&'
LPAREN          ~ '('
RPAREN          ~ ')'
func            ~ 'func'
});
# say $grammar->show_rules;
for my $input (
'func(foo)&func(bar)', '"foo"', 'func("foo") - func("bar")', 'func("foo")'
) {
my $r = Marpa::R2::Scanless::R->new({
grammar => $grammar,
#         trace_terminals => 1
});
$r->read($input);
say "# $input";
say Dumper $r->value;
}

有问题的第二种方法对我有用。我只需要包括:

lexeme default = latm => 1

在我的代码中。

相关内容

  • 没有找到相关文章

最新更新