Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Comment on

( #3333=superdoc: print w/ replies, xml ) Need Help??

Converts rfc5234 Augmented BNF for Syntax Specifications: ABNF to Regexp::Grammars syntax (perl5.10 compatible regex)

Indenting not implemented

#!/usr/bin/perl -- use strict; use warnings; use File::Slurp; use Parse::ABNF ; Main( @ARGV ); exit( 0 ); sub Main { my $rules = Parse::ABNF->new->parse( scalar read_file( shift ) ); print "\n\n", Value( $rules ), "\n\n"; } BEGIN { my %class = ( Choice => \&Choice, Group => \&Group, Range => \&Range, Reference => \&Reference, Repetition => \&Repetition, Rule => \&Rule, String => \&String, Literal => \&Literal, ProseValue => \&ProseValue, ); sub Value { my $ret = ""; my( $v , $dent ) = @_; $dent ||= 0; if( UNIVERSAL::isa($v, 'ARRAY') ){ $ret .= join '', map { Value($_ , $dent ) } @$v; } elsif( UNIVERSAL::isa($v, 'HASH') ){ $ret .= $class{ $$v{class} }->( $v , $dent ); } else { warn $v; } $ret; } } sub Choice { my $ret = ""; my( $v, $dent ) = @_; $ret .= join ' | ', map { Value($_ , $dent+1) } @{$$v{value}}; $ret ; } sub Group { my $ret = ""; my( $v, $dent ) = @_; $ret .= "(?: ". Value( $$v{value} , $dent+1) .' )'; $ret ; } sub Reference { my $ret = ""; my( $v, $dent ) = @_; $ret .= "<@{[fixRulename($$v{name})]}>"; $ret ; } sub Repetition { my $ret = ""; my( $v, $dent ) = @_; no warnings 'uninitialized'; my %mm = ( # max min "1 0" => '?', " 0" => '*', " 1" => '+', ); if( my $mm = $mm{"$$v{max} $$v{min}"} ){ $ret .= " (?: ". Value($$v{value} , $dent+1)." )$mm "; } elsif( $$v{min} == $$v{max} ){ $ret .= " (?: ". Value($$v{value} , $dent+1)." ){$$v{max}} "; } else { $ret .= " (?: ". Value($$v{value} , $dent+1)." ){$$v{min}, $$ +v{max}} "; } $ret ; } sub Rule { my $ret = ""; my( $v, $dent ) = @_; my $name = $$v{name}; if( 'ws' eq lc $name ){ warn "Changing rule ws to token to avoid 'infinitely recursive + unpleasantness.'\n"; $ret .= "<token: ws>\n "; } else { $ret .= "<rule: @{[fixRulename($$v{name})]}>\n "; } $ret .= Value( $$v{value} , $dent+1); $ret . "\n\n"; } #~ @{[fixRulename($$v{name})]} sub fixRulename { my( $name ) = @_; $name =~ s/\W/_/g; $name; } sub Range { my $ret = ""; my( $v, $dent ) = @_; $ret .= '['; if( $$v{type} eq 'hex' ){ $ret .= join '-', map { '\x{'.$_.'}' } $$v{min}, $$v{max}; } elsif( $$v{type} eq 'binary' ){ $ret .= join '-', map { sprintf '\\%o', oct "0b$_" } $$v{min}, + $$v{max}; } elsif( $$v{type} eq 'decimal' ){ $ret .= join '-', map { sprintf '\\%o', $_ } $$v{min}, $$v{max +}; } else { warn "## Range type $$v{type} $$v{value} \n"; } $ret .= "]"; $ret ; } sub String { my $ret = ""; my( $v, $dent ) = @_; if( $$v{type} eq 'hex' ){ $ret = join '', map { '\x'.$_ } @{$$v{value}}; } elsif( $$v{type} eq 'binary' ){ $ret .= join '', map { sprintf '\\%o', oct "0b$_" } @{$$v{valu +e}}; } elsif( $$v{type} eq 'decimal' ){ $ret .= join '', map { sprintf '\\%o', $_ } @{$$v{value}}; } else { warn "## String type $$v{type} $$v{value} \n"; #~ warn "##", map({ "$_ ( $$v{$_} ) " } sort keys %$v ), "\n" +; } #~ " $ret "; $ret; } sub Literal { my $ret = ""; my( $v, $dent ) = @_; $ret .= quotemeta $$v{value} ; $ret ; } sub ProseValue { my $ret = ""; my( $v, $dent ) = @_; #~ warn "##", map({ "$_ ( $$v{$_} ) " } sort keys %$v ), "\n"; #~ $ret .= "<$$v{value}>"; $ret .= "<@{[fixRulename($$v{value})]}>"; $ret ; } __END__

$ cat core.abnf BIT = "0" / "1" CR = %d13 CR = %x0D CR = %b1101 CRLF = CR LF LF = %x0A

Note the actual output has lots more whitespace

$ perl abnf.to.grammars.pl core.abnf <rule: BIT> 0 | 1 <rule: CR> \15 <rule: CR> \x0D <rule: CR> \15 <rule: CRLF> (?: <CR><LF> ) <rule: LF> \x0A

In reply to Convert Augmented BNF (ABNF) to Regexp::Grammars by Anonymous Monk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • Outside of code tags, you may need to use entities for some characters:
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others making s'mores by the fire in the courtyard of the Monastery: (10)
    As of 2014-08-27 11:00 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      The best computer themed movie is:











      Results (237 votes), past polls