in reply to Parse::Recdescent optional subrule commit

Making the subrule mandatory, while allowing it to match nothing solves the problem.

#!/usr/bin/env perl use strict; use warnings; use feature qw( say ); use Parse::RecDescent qw( ); my $grammar = <<'__EOI__'; myrule : 'stuff' mysubrule | <error> mysubrule : 'ID' <commit> '[' ']' | <error?> <reject> | __EOI__ my $parser = Parse::RecDescent->new($grammar) or die; for my $text ("stuff ID something", "stuff something") { say "===================="; say "$text"; say "--------------------"; say $parser->myrule($text) ? 'pass' : 'fail'; }
==================== stuff ID something -------------------- ERROR (line 1): Invalid mysubrule: Was expecting '[' but found "something" instead ERROR (line 1): Invalid myrule: Was expecting mysubrule but fou +nd "ID something" instead fail ==================== stuff something -------------------- pass

Replies are listed 'Best First'.
Re^2: Parse::Recdescent optional subrule commit
by ikegami (Patriarch) on May 02, 2012 at 20:18 UTC

    And below is how to do it with the optional subrule. It even provides better error messages.

    #!/usr/bin/env perl use strict; use warnings; use feature qw( say ); use Parse::RecDescent qw( ); my $grammar = <<'__EOI__'; myrule : <rulevar: local $failed = 1> myrule : 'stuff' mysubrule(?) <reject:$failed> mysubrule : 'ID' <commit> '[' ']' | <error?> { $failed = 0; } <reject> __EOI__ my $parser = Parse::RecDescent->new($grammar) or die; for my $text ("stuff ID something", "stuff something") { say "===================="; say "$text"; say "--------------------"; say $parser->myrule($text) ? 'pass' : 'fail'; }
    ==================== stuff ID something -------------------- ERROR (line 1): Invalid mysubrule: Was expecting '[' but found "something" instead fail ==================== stuff something -------------------- pass
      This is elegant and simple! Thank you!