我已经开始接触Marpa解析器,并且在第一个符号为可选符号时遇到了问题。这是一个例子:
use strict;
use warnings;
use 5.10.0;
use Marpa::R2;
use Data::Dump;
my $grammar = Marpa::R2::Scanless::G->new({source => \<<'END_OF_GRAMMAR'});
:start ::= Rule
Rule ::= <optional a> 'X'
<optional a> ~ a *
a ~ 'a'
END_OF_GRAMMAR
my $recce = Marpa::R2::Scanless::R->new({grammar => $grammar});
dd $recce->read(\"X");
运行此命令时,出现以下错误:
Error in SLIF parse: No lexemes accepted at line 1, column 1
* String before error:
* The error was at line 1, column 1, and at character 0x0058 'X', ...
* here: X
Marpa::R2 exception at small.pl line 20
at /usr/local/lib/perl/5.14.2/Marpa/R2.pm line 126
Marpa::R2::exception('Error in SLIF parse: No lexemes accepted at line 1, column 1\x{a}...') called at /usr/local/lib/perl/5.14.2/Marpa/R2/Scanless.pm line 1545
Marpa::R2::Scanless::R::read_problem('Marpa::R2::Scanless::R=ARRAY(0x95cbfd0)', 'no lexemes accepted') called at /usr/local/lib/perl/5.14.2/Marpa/R2/Scanless.pm line 1345
Marpa::R2::Scanless::R::resume('Marpa::R2::Scanless::R=ARRAY(0x95cbfd0)', 0, -1) called at /usr/local/lib/perl/5.14.2/Marpa/R2/Scanless.pm line 926
Marpa::R2::Scanless::R::read('Marpa::R2::Scanless::R=ARRAY(0x95cbfd0)', 'SCALAR(0x95aeb1c)') called at small.pl line 20
Perl 5.14.2版(debian wheezy)
Marpa版本2.068000
(我看到有一个尚未尝试过的全新Marpa 2.069)
这是我在语法上做错了吗?
最佳答案
在Marpa Scanless中,您的语法有两个层次:主要的高层语法(可在其中分配 Action 等)和底层的词法语法。它们是独立执行的(如果您使用了传统的解析器/词法分析器,这是可以预期的,但是当您从正则表达式到Marpa时,这将非常令人困惑)。
现在,在低级语法中,Marpa将您的输入识别为单个X
,而不是“零a
s然后是X
”。但是,高级语法要求存在optional a
符号。
最好的解决方法是在高级语法中将a
设置为可选:
<optional a> ::= <many a>
<optional a> ::= # empty
<many a> ~ a* # would work the same here with "a+"
a ~ 'a'
关于perl - Marpa解析器似乎无法应付可选的第一个符号?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18634749/