首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用MARPA:R2 perl解析/识别大表达式中的双引号字符串

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

Stack Overflow用户
提问于 2018-03-22 00:02:01
回答 2查看 120关注 0票数 2

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

代码语言:javascript
复制
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作为字符串LEXEME来正确解析它。

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

my $input3 = "func(\"foo\") - func(\"bar\")"; ->在这里,func应该被当作func LEXEME,(应该是LPAREN,)应该是RPAREN,foo作为REGEX_STRING,- as和func(\"bar\")相同。

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

代码语言:javascript
复制
print "Trying to parse:\n$input\n\n";
$recce->read(\$input);
my $value_ref = ${$recce->value};
print "Output:\n".Dumper($value_ref);

我尝试了什么:1方法: My REGEX_STRING应该是什么:REGEX_STRING -> ~ '\"([^:]*?)\"'

如果我尝试将上面的REGEX_STRING放在输入表达式为my $input4 = "func(\"foo\")";的代码中,就会得到以下错误:

SLIF解析中的错误:在第1行、第5列*在错误之前的字符串: func( *错误位于第1行第5列和字符0x0022‘“、.*此处:"foo") Marpa::R2异常处未找到

第二种方法:

尝试包括这样的规则:

代码语言:javascript
复制
PARAM ::= STRING | REGEX_STRING
REGEX_STRING ::= '"' QUOTED_STRING '"'

STRING ~ [^ \/\(\),&:\"~]+
QUOTED_STRING ~ [^ ,&:\"~]+

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

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

所以,这里会出现错误,因为现在有两种方法来解析这个表达式,一个是双引号之间的整件事,即func(\"foo\")被当作QUOTED_STRING,或者func应该作为func等等。

请帮我解决这件事。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-03-22 12:25:26

代码语言:javascript
复制
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;
}
票数 1
EN

Stack Overflow用户

发布于 2018-03-26 17:20:20

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

代码语言:javascript
复制
lexeme default = latm => 1

在我的密码里。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49418453

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档