DESC
=>
'Mixed high and low-precedence booleans'
,
EXPL
=> [70],
};
ALPHABETICAL
=> 1,
NON_ALPHABETICAL
=> 2,
INVALID
=> 3,
};
sub
evaluate {
my
(
$class
,
$file
,
$tokens
,
$src
,
$args
) =
@_
;
my
@violations
;
my
@context_for_each_depth
;
my
$left_paren_num
= 0;
for
(
my
$i
= 0,
my
$token_type
;
my
$token
=
$tokens
->[
$i
];
$i
++) {
$token_type
=
$token
->{type};
if
(
$token_type
== SEMI_COLON) {
if
(
$left_paren_num
<= 0) {
if
(
my
$status
=
$context_for_each_depth
[0]) {
if
(
$status
== INVALID) {
push
@violations
, {
filename
=>
$file
,
line
=>
$token
->{line},
description
=> DESC,
explanation
=> EXPL,
policy
=> __PACKAGE__,
};
}
}
@context_for_each_depth
= ();
}
}
elsif
(
$token_type
== LEFT_PAREN) {
$left_paren_num
++;
}
elsif
(
$token_type
== RIGHT_PAREN) {
if
(
@context_for_each_depth
and
my
$status
=
splice
@context_for_each_depth
,
$left_paren_num
) {
if
(
$status
== INVALID) {
push
@violations
, {
filename
=>
$file
,
line
=>
$token
->{line},
description
=> DESC,
explanation
=> EXPL,
policy
=> __PACKAGE__,
};
}
}
$left_paren_num
--;
}
elsif
(
$token_type
== AND ||
$token_type
== OR ||
$token_type
== NOT
) {
if
(
my
$context
=
$context_for_each_depth
[
$left_paren_num
]) {
if
(
$context
!= NON_ALPHABETICAL) {
$context_for_each_depth
[
$left_paren_num
] = INVALID;
}
next
;
}
$context_for_each_depth
[
$left_paren_num
] = NON_ALPHABETICAL;
}
elsif
(
$token_type
== ALPHABET_AND ||
$token_type
== ALPHABET_OR ||
$token_type
== ALPHABET_NOT ||
$token_type
== ALPHABET_XOR
) {
if
(
my
$context
=
$context_for_each_depth
[
$left_paren_num
]) {
if
(
$context
!= ALPHABETICAL) {
$context_for_each_depth
[
$left_paren_num
] = INVALID;
}
next
;
}
$context_for_each_depth
[
$left_paren_num
] = ALPHABETICAL;
}
}
return
\
@violations
;
}
1;