Как разобрать / идентифицировать строку в двойных кавычках из большого выражения, используя 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$input\n\n";
$recce->read(\$input);
my $value_ref = ${$recce->value};
print "Output:\n".Dumper($value_ref);

Что я попробовал: 1-й метод: мой REGEX_STRING должен быть что-то: REGEX_STRING -> ~ '\"([^:]*?)\"'

Если я попытаюсь поставить выше REGEX_STRING в коде с входным выражением как my $input4 = "func(\"foo\")"; я получаю ошибку как:

Ошибка в синтаксическом анализе SLIF: лексема не найдена в строке 1, столбце 5 * Строка до ошибки: func( * Ошибка была в строке 1, столбце 5 и в символе 0x0022 '"', ... * здесь: "foo") Marpa::R2 исключение

2-й метод:

Пробовал в том числе правило, как:

PARAM ::= STRING | REGEX_STRING
REGEX_STRING ::= '"' QUOTED_STRING '"'

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

Проблема здесь -> Ввод дается с помощью:

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

Таким образом, здесь это дает ошибку, потому что теперь есть два способа разбора этого выражения: либо все, что находится между двойными кавычками, которое является func(\"foo\"), принимается за QUOTED_STRING, или func должно приниматься как func LEXEME и так далее.

Пожалуйста, помогите, как я могу это исправить.

2 ответа

Решение
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;
}

2-й метод, размещенный в вопросе, работал для меня. Я просто должен включить:

lexeme default = latm => 1

в моем коде.

Другие вопросы по тегам