我正在努力获得看似非常基本的Marpa语法。我使用的代码如下:
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'
和'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'的值,而不仅仅是undef
)?
答案 0 :(得分:5)
默认情况下,规则会返回undef值,因此在您的情况下,从$ reader-&gt; value()返回\ undef表示您的解析成功。也就是说,undef的返回意味着失败,而\ undef的返回意味着成功,其中解析被评估为undef。
从一个更有用的语义开始的一个好的,快速的方法是添加以下行:
:default :: = action =&gt; ::阵列
这会导致解析生成AST。