ABNF-Grammar
view release on metacpan or search on metacpan
lib/ABNF/Grammar.pm view on Meta::CPAN
This module parses IETF ABNF (STD 68, RFC 5234, 4234, 2234) grammars
via B<Parse::ABNF> and provides tools to :
=over 4
=item * verify validity of string
=item * generate valid messages
=item * generate invalid messages
=back
=head1 METHODS
=cut
use 5.014;
use strict;
use warnings;
use Carp;
use Readonly;
use Method::Signatures;
use Data::Dumper;
use Parse::ABNF;
use Storable qw(dclone);
use base "Exporter";
our @EXPORT_OK = qw(splitRule Grammar $BASIC_RULES);
our $VERSION = "0.08";
Readonly our $BASIC_RULES => do {
my $res = {};
foreach my $rule ( @{$Parse::ABNF::CoreRules} ) {
die "Multiple definitions for $rule->{name}" if exists($res->{$rule->{name}});
$res->{$rule->{name}} = $rule;
}
$res;
};
=pod
=head1 ABNF::Grammar->C<new>($fname, @commands)
Creates a new B<ABNF::Grammar> object.
Read ABNF rules from file with $fname.
@commands consists of main command names for generation and validation.
=cut
method new(Str $fname, @commands) {
my $class = ref($self) || $self;
$self = {_commands => { map {$_ => 1} @commands} };
bless($self, $class);
open(my $file, $fname)
or croak "Cant open $fname";
my $content = join("", <$file>) . "\n";
close($file)
or carp "Cant close $fname";
$self->_init($content);
foreach my $command ( @commands ) {
croak "Grammar doesn't have command $command" unless exists($self->{_rules}->{$command});
}
return $self;
}
=pod
=head1 ABNF::Grammar->C<fromString>($content, @commands)
Creates a new B<ABNF::Grammar> object.
Get ABNF rules from string $rule
@commands consists of main command names for generation and validation.
=cut
method fromString(Str $content, @commands) {
my $class = ref($self) || $self;
$self = {_commands => { map {$_ => 1} @commands} };
bless($self, $class);
$self->_init($content . "\n");
foreach my $command ( @commands ) {
croak "Grammar doesn't have command $command" unless exists($self->{_rules}->{$command});
}
return $self;
}
method _init($content) {
my $parser = Parse::ABNF->new();
my $rules = $parser->parse($content)
or croak "Bad rules";
foreach my $rule ( @$rules ) {
croak "Multiple definitions for $rule->{name}" if exists($self->{_rules}->{$rule->{name}});
$self->{_rules}->{$rule->{name}} = $rule;
}
}
=pod
=head1 $grammar->C<rule>($name)
Return rule form $name with name $name.
Result structure is identical to B<Parse::ABNF> structure.
For debug only.
Do not modify result structure.
=cut
method rule(Str $name) {
croak "Unexisted rule $name" unless exists($self->{_rules}->{$name});
$self->{_rules}->{$name};
}
=pod
=head1 $grammar->C<rules>()
Return all rules.
Result structures is identical to B<Parse::ABNF> structure.
For debug only.
Do not modify result structure.
=cut
method rules() {
$self->{_rules};
( run in 0.853 second using v1.01-cache-2.11-cpan-39bf76dae61 )