2016-03-24 4 views
2

は、次のようにテキストを解析が必要:Pegex文法の設計

optional free text 
@somemacro1(optional free text 
     @somemacro2(SOME TEXT)@ or other optional free text 
)@ 
another free text 

例えばそれは基本的には非常に簡単です:

  • ソースは、フォームにいくつかのマクロが含まれている可能性がフリーテキスト
  • ある@MACRONAME(一部のコンテンツ)@
  • 一部のコンテンツが再びフリーテキストであるている可能性いくつかのマクロを含む - 例えばマクロは

解析されたマクロの結果は、(マクロ名に基づいて)いくつかの文字列である(上記の例を参照)

  • ネストすることができ、私はPegexはそう、このタスクのためにそれを使用することを決め学びたいです。

    問題は:誰かが上記のためにPegex-grammarを手伝ってもらえますか?

    私がすでに試したことを誰かが疑問に思っています、ここでは私のテストソースです - 動作していません。 :(ここ

    package Rec { 
        use 5.014; 
        use warnings; 
        use base 'Pegex::Receiver'; 
        use Data::Dumper; 
    
        sub gotrule { 
         my($self, $got) = @_; 
         say "Got rule:", $self->{rule}; 
         return "GOT" . $self->{rule} . "RULE"; 
        } 
    } 
    
    use 5.014; 
    use warnings; 
    use Data::Dumper; 
    use Pegex::Parser; 
    use Pegex::Grammar; 
    
    my $source = <<'EOF'; 
    free text 
    @somemacro1(optional free text 
        @somemacro2(SOME TEXT)@ or other optional free text 
    )@ 
    another free text 
    EOF 
    
    my $grammar_text = do {local $/; <DATA>}; 
    my $grammar = Pegex::Grammar->new(text => $grammar_text); 
    my $receiver = Rec->new; 
    my $parser = Pegex::Parser->new(grammar => $grammar, receiver => $receiver); 
    my $input = Pegex::Input->new(string => $source); 
    my $ret = $parser->parse($input); 
    
    __DATA__ 
    %grammar test 
    %version 0.0.1 
    
    start:  seq* 
    
    seq:  | macro 
         | text 
    
    macro: /AT macro-name LPAREN content RPAREN AT/
    macro-name:/WORD+/
    text:  /ALL*/
    content: /ALL*/
    
  • 答えて

    2

    が可能なソリューションです。あなたのテキストは任意であるので、あなたはそれを介して動作するようにあなたのRecレシーバ・クラスのgot_*メソッドを使用する必要がありますので、それは、注意が必要です。あなたはどのように上の私のコメントを見ることができます。デバッグPegexがあまりにも文法私はあなたがPegexのデバッグのための必要としてきちんとデータをダンプするXXXモジュールを使用してここで働くのサンプルコードです:。

    #!/usr/bin/env perl 
    package Rec { 
        use 5.014; 
        use warnings; 
        use Pegex::Base; 
        extends 'Pegex::Tree'; 
    
        use XXX; 
    
        sub got_comment {} 
    
        sub got_text { 
         my ($self, $got) = @_; 
         return $self->flatten($got); 
        } 
        sub got_macro { 
         my ($self, $got) = @_; 
         return $got; 
        } 
        sub final { 
         my($self, $got) = @_; 
         XXX $got; 
        } 
    } 
    
    use 5.014; 
    use warnings; 
    use XXX; 
    use Pegex::Parser; 
    use Pegex::Grammar; 
    
    my $source = <<'EOF'; 
    free text 
    @somemacro1(optional free text 
        @somemacro2(SOME TEXT)@ or other optional free text 
    )@ 
    another free text 
    EOF 
    
    my $grammar_text = do {local $/; <DATA>}; 
    my $grammar = Pegex::Grammar->new(text => $grammar_text); 
    my $receiver = Rec->new; 
    my $parser = Pegex::Parser->new(grammar => $grammar, 
         receiver => $receiver, 
         debug => 1); ### NOTE USE THIS FOR DEBUGGING 
    my $ret = $parser->parse($source); 
    __DATA__ 
    %grammar test 
    %version 0.0.1 
    
    start: seq* end-of-seq 
    
    end-of-seq: - EOS 
    seq: comment | macro | text 
    
    comment: blank-line 
    macro-stop: -/RPAREN AT/- 
    macro-start: - macro-name - 
    macro: macro-start macro-content* macro-stop 
    macro-content: (comment | macro | text) 
    macro-name:/AT (WORD+) LPAREN/
    text: -/(!macro-start) ([ WORDS ]+)/- 
    blank-line: /- EOL/ 
    
    +1

    YESああ、メインのトリックは '(マクロ開始です! ) ' - 本当にクール。どういうわけか - 私が読んだものはすべてのpegex文法を理解していますが、私は自分自身を作り出すことはできません。もし私ができれば - 特に新しいStackOverflowユーザーの場合);)。 – Nemo

    +0

    さらに 'Pegex'の質問がある場合は、**#pegex ** channel of Freenode IRCにアクセスしてください。 – vicash