我试图让看起来非常基本的马尔巴语法工作。我使用的代码如下:
use strict;
use warnings;
use Marpa::R2;
use Data::Dumper;
my $grammar = Marpa::R2::Scanless::G->new(
{
source => \(<<'END_OF_SOURCE'),
:start ::= ExprSingle
ExprSingle ::= Expr AndExpr
Expr ~ word
AndExpr ~ word*
word ~ [\w]+
:discard ~ ws
ws ~ [\s]+
END_OF_SOURCE
}
);
my $reader = Marpa::R2::Scanless::R->new(
{
grammar => $grammar,
}
);
my $input = 'foo';
$reader->read(\$input);
my $value = $reader->value;
print Dumper $value;
这打印$VAR1 = \'foo';
。所以它可以很好地识别一个单词。但我想让它识别一串单词
my $input='foo bar'
现在脚本打印:
Error in SLIF G1 read: Parse exhausted, but lexemes remain, at position 4
我认为这是因为ExprSingle
使用了~
(匹配)运算符,这使其成为标记级别 G0 的一部分,而不是结构级别 G1;该:discard
规则允许 G1 规则之间有空格,而不是 G0 规则。所以我像这样改变语法:
ExprSingle ::= Expr AndExpr
现在不会打印任何警告,但结果值undef
不是包含'foo'
and的东西'bar'
。老实说,我不确定这意味着什么,因为在此之前,失败的解析会引发实际错误。
我尝试更改语法以进一步区分我认为的 G0 和 G1 规则,但仍然没有运气:
:start ::= ExprSingle
ExprSingle ::= Expr AndExpr
Expr ::= token
AndExpr ::= token*
token ~ word
word ~ [\w]+
:discard ~ ws
ws ~ [\s]+
最终值仍然是undef
。trace_terminals
显示 'foo' 和 'bar' 都被接受为标记。我需要做什么来修复这个语法(我的意思是获取一个包含字符串 'foo' 和 'bar' 而不是 just 的值undef
)?