File Coverage

blib/lib/Pegex/Cmd.pm
Criterion Covered Total %
statement 12 53 22.6
branch 0 32 0.0
condition 0 3 0.0
subroutine 4 12 33.3
pod 0 8 0.0
total 16 108 14.8


line stmt bran cond sub pod time code
1             package Pegex::Cmd;
2             our $VERSION = '0.28';
3              
4             #-----------------------------------------------------------------------------#
5             package Pegex::Cmd;
6              
7 1     1   1526 use Pegex::Cmd::Mo;
  1         3  
  1         4  
8              
9 1     1   731 use Getopt::Long;
  1         12831  
  1         6  
10              
11 1         92 use constant abstract =>
12 1     1   222 'Compile a Pegex grammar to some format.';
  1         3  
13 1         889 use constant usage_desc =>
14 1     1   6 'pegex compile --to= [grammar_file.pgx]';
  1         2  
15              
16             # Output format. One of: yaml, json, perl, perl6, python.
17             has to => ();
18              
19             # Regex format: raw, perl.
20             has regex => ();
21              
22             # Use the bootstrap compiler
23             has boot => ();
24              
25             # Starting rules to combinate
26             has rules => (
27             default => sub {
28             $ENV{PEGEX_COMBINATE_RULES}
29             ? [ split / +/, $ENV{PEGEX_COMBINATE_RULES} ]
30             : []
31             },
32             );
33              
34             my %formats = map {($_,1)} qw'yaml json perl';
35             my %regexes = map {($_,1)} qw'perl raw';
36             my %commands = map {($_,1)} qw'compile help version';
37             sub usage;
38             sub error;
39              
40             sub run {
41 0     0 0   my ($self, @argv) = @_;
42              
43 0           my ($command, $args) = $self->getopt(@argv);
44 0           @ARGV = ();
45              
46 0           $self->$command($args);
47             }
48              
49             sub help {
50 0     0 0   print usage;
51             }
52              
53             sub compile {
54 0     0 0   my ($self, $args) = @_;
55              
56 0 0         my $to = $self->to or
57             error "--to=perl|yaml|json required";
58              
59 0 0 0       my $regex = $self->regex ||
60             $to eq 'perl' ? 'perl' : 'raw';
61              
62             die "'$to' is an invalid --to= format"
63 0 0         unless $formats{$to};
64             die "'$regex' is an invalid --regex= format"
65 0 0         unless $regexes{$regex};
66              
67             my $input = scalar(@$args)
68             ? $self->slurp($args->[0])
69 0 0         : do { local $/; <> };
  0            
  0            
70 0 0         my $compiler_class = $self->boot
71             ? 'Pegex::Bootstrap'
72             : 'Pegex::Compiler';
73              
74 0 0         eval "use $compiler_class; 1" or die $@;
75 0           my $compiler = $compiler_class->new();
76 0           $compiler->parse($input)->combinate(@{$self->rules});
  0            
77 0 0         $compiler->native if $regex eq 'perl';
78              
79             my $output =
80             $to eq 'perl' ? $compiler->to_perl :
81             $to eq 'yaml' ? $compiler->to_yaml :
82             $to eq 'json' ? $compiler->to_json :
83 0 0         do { die "'$to' format not supported yet" };
  0 0          
    0          
84 0           print STDOUT $output;
85             }
86              
87             sub version {
88 0     0 0   require Pegex;
89              
90 0           print <<"...";
91             The 'pegex' compiler command v$VERSION
92              
93             Using the Perl Pegex module v$Pegex::VERSION
94             ...
95             }
96              
97             sub getopt {
98 0     0 0   my ($self, @argv) = @_;
99              
100 0           local @ARGV = @argv;
101              
102             GetOptions(
103             "to=s" => \$self->{to},
104             "boot" => \$self->{boot},
105 0 0         ) or error;
106              
107 0 0         if (not @ARGV) {
108 0           print usage;
109 0           exit 0;
110             }
111              
112 0           my $command = shift @ARGV;
113 0 0         $commands{$command} or
114             error "Invalid command '$command'";
115              
116 0           return $command, [@ARGV];
117             }
118              
119             sub slurp {
120 0     0 0   my ($self, $file) = @_;
121 0 0         open my $fh, $file or
122             die "Can't open '$file' for input";
123 0           local $/;
124 0           <$fh>;
125             }
126              
127             sub error {
128 0     0 0   my $msg = usage;
129              
130 0 0         $msg = "Error: $_[0]\n\n$msg" if @_;
131              
132 0           die $msg;
133             }
134              
135             sub usage {
136 0     0 0   <<'...';
137             pegex [] []
138              
139             Commands:
140              
141             compile: Compile a Pegex grammar to some format
142             version: Show Pegex version
143             help: Show help
144              
145             Options:
146             -t,--to=: Output type: yaml, json, perl
147             -b, --boot: Use the Pegex Bootstrap compiler
148             -r, --rules=: List of starting rules
149              
150             ...
151             }
152              
153             1;