File Coverage

blib/lib/Logic/Expr/Parser.pm
Criterion Covered Total %
statement 25 25 100.0
branch 6 6 100.0
condition 3 3 100.0
subroutine 9 9 100.0
pod 2 2 100.0
total 45 45 100.0


line stmt bran cond sub pod time code
1             # -*- Perl -*-
2             #
3             # a parser for logic expressions
4              
5             package Logic::Expr::Parser;
6             our $VERSION = '0.02';
7 3     3   337913 use Logic::Expr ':all';
  3         5  
  3         403  
8 3     3   16 use base 'Parser::MGC'; # 0.21 or higher required
  3         5  
  3         1326  
9              
10             # LE_NOT is handled outside the scope of this pair of variables
11             our %le_map = (
12             '&' => LE_AND,
13             '|' => LE_OR,
14             'v' => LE_OR,
15             '->' => LE_COND,
16             '==' => LE_BICOND,
17             );
18             our $le_regex = qr/->|==|[&|v]/;
19              
20 10     10 1 270 sub on_parse_end { Logic::Expr->new( expr => $_[1] ) }
21              
22             sub parse
23             {
24 18     18 1 11702 my ($self) = @_;
25 18         42 my $first = $self->_parse_term;
26 15         75 my ( $operator, $second );
27             $self->maybe(
28             sub {
29 15     15   151 $operator = $le_map{ $self->expect($le_regex) };
30 11         453 $second = $self->_parse_term;
31             }
32 15         67 );
33 15 100       299 defined $operator ? [ $operator, $first, $second ] : $first;
34             }
35              
36             sub _parse_term
37             {
38 29     29   36 my ($self) = @_;
39 29     29   113 my $neg = $self->maybe( sub { $self->expect(qr/!+|~+/) } );
  29         333  
40             my $term = $self->any_of(
41 29     29   312 sub { $self->scope_of( "(", \&parse, ")" ) },
42             sub {
43 26     26   1700 my $atom = $self->expect(qr/[A-Z]+/);
44 23 100       897 unless ( exists $Logic::Expr::atoms{$atom} ) {
45 10         16 push @Logic::Expr::bools, TRUE;
46 10         19 $Logic::Expr::atoms{$atom} = \$Logic::Expr::bools[-1];
47             }
48 23         80 $Logic::Expr::atoms{$atom};
49             },
50 29         1922 );
51             # simplify !!!X to !X and !!X to X
52 26 100 100     237 ( defined $neg and length($neg) & 1 ) ? [ LE_NOT, $term ] : $term;
53             }
54              
55             1;
56             __END__