【问题标题】:Trouble separating G0 and G1 rules in grammar在语法麻烦分离G0和G1规则
【发布时间】:2013-06-13 22:47:50
【问题描述】:

我正在尝试让看似非常基本的 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]+

最终的值还是undeftrace_terminals 显示 'foo' 和 'bar' 都被接受为令牌。我需要做什么来修复这个语法(我的意思是获取一个包含字符串 'foo' 和 'bar' 而不仅仅是 undef 的值)?

【问题讨论】:

    标签: perl parsing tokenize marpa


    【解决方案1】:

    默认情况下,规则返回 undef 值,因此在您的情况下,从 $reader->value() 返回 \undef 意味着您的解析成功。也就是说,返回 undef 意味着失败,而返回 \undef 意味着成功,其中 parse 评估为 undef。

    从更有用的语义开始的一个好、快速的方法是添加以下行:

    :默认 ::= 动作 => ::数组

    这会导致解析生成一个 AST。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多