如何使用 MARPA:R2 perl 从大表达式中 parse/identify 双引号字符串
How to parse/identify double quoted string from the big expression using MARPA:R2 perl
大表达式中 parsing/identifying 双引号字符串中的问题。
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$input\n\n";
$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")
Marpa::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
在我的代码中。
大表达式中 parsing/identifying 双引号字符串中的问题。
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$input\n\n";
$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") Marpa::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
在我的代码中。