4

非常に基本的な 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';ます。そのため、1 つの単語を問題なく認識します。しかし、単語の文字列を認識したい

my $input='foo bar'

スクリプトは次のように出力します。

Error in SLIF G1 read: Parse exhausted, but lexemes remain, at position 4

これは、構造レベル G1 の代わりにトークン化レベル G0 の一部にする (match) 演算子をExprSingle使用しているためだと思います。~この:discard規則では、G0 規則ではなく、G1 規則の間にスペースを許可します。したがって、文法を次のように変更します。

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)。

4

1 に答える 1

5

ルールはデフォルトで undef の値を返すため、あなたのケースでは $reader->value() から \undef が返された場合、解析が成功したことを意味します。つまり、undef の戻り値は失敗を意味し、\undef の戻り値は解析が undef に評価された場合の成功を意味します。

より便利なセマンティクスから始める良い、手っ取り早い方法は、次の行を追加することです。

:デフォルト ::= アクション => ::配列

これにより、解析で AST が生成されます。

于 2013-06-18T00:02:02.770 に答える