Как я могу посчитать количество логических условий, используемых в if, elseif или в Perl? - PullRequest
0 голосов
/ 21 декабря 2009

у меня есть некоторое время if if elseif в файле с несколькими условиями внутри это ... это язык C ... формат, упомянутый ниже, является стандартным для всех Несколько условий. Так что не стоит беспокоиться о неопределенности. Единственная проблема состоит в том, чтобы проверить, как Есть много условий и список в соответствии с форматом вывода, который я описал .... например, если мой файл C имеет код ...

while(
      condition1 &&
      condition2 ||
      condition3
     )
{
  #statements; 
}

Я хочу посчитать, сколько условий в это время, и мой вывод должен быть
примерно так ...

  while(
  1    condition1 &&
  2    condition2 ||
  3    condition3
     )
{
  #statements; 
}

Я написал код, и он отлично работает для простого ... мой код ....

open(A,"e:\\a\\a.txt")or die;
@a=<A>;
close(A);
$count=1;
for($i=0;$i<scalar@a;$i++)
{
  if($a[$i]=~m/while/g)
  {
    $line=$i;
    until($a[$line]=~/\{/g)
    {
       if($a[$line]=~/(.*)[\&&\||]/g){print"$count $a[$line]";$count++;}  
       elsif($a[$line]=~/\(.*\)[\&&\||]/g){print"$count $a[$line]";$count++;}  
       else{print$a[$line];}
       $line++;
    }
  }
 last if($a[$line]=~/\{/g);
}

но для сложных условий, таких как

while(
        ( 
         condition1 &&
         condition2 &&
         condition3
        ) ||
        (
          condition4 ||
          condition5 &&
          condition6
         )

{
  #statements;
}

получаю вывод как

while(
        ( 
       1  condition1 &&
       2  condition2 &&
          condition3
       3 ) ||
        (
       4  condition4 ||
       5  condition5 &&
          condition6
         )

что нежелательно .... я намерен просчитать все условия относительно того, насколько сложным оно является ..... пожалуйста, помогите мне ...

желаемый результат может быть

в то время как ( ( 1 условие1 && 2 условие2 && 3 условие3 ) || ( 4 условие4 || 5 условие5 && 6 условие6 ) ) так как он использовал 6 условий внутри ... следовательно, для любых случаев.

Ответы [ 3 ]

8 голосов
/ 21 декабря 2009

Какой это язык? Доступны ли полные парсеры для этого языка? Если это так, я предлагаю вам использовать их. Если нет, я думаю, вам будет трудно решить эту проблему надежно. Ваш подход основан на том, как программист отформатировал свой код.

Право, когда вы решили свою проблему для своего примера, кто-то бросит вам следующее:

while(
        ( condition1 && condition2)
          && condition3            )
        ||
        ( condition4 || condition5
          && condition6            )

{
  #statements;
}

Если вы настаиваете на написании собственного парсера макетов, я бы предложил следующее:

  • Не разбирать по линиям. Не стесняйтесь читать построчно. Но не разбирайте каждую строку отдельно.
  • Извлечь содержимое соответствующего набора скобок через некоторое время. Подсказка здесь " match ". Запустите perldoc -q match и взгляните на первую запись Perl FAQ о разборе совпадений / вложенных скобок.
  • Если у вас есть код, содержащийся в скобках, попробуйте извлечь количество операндов для логических операторов, разделив их на логические операции.
  • Отчаяние, если операнды (условиеX) могут содержать строки, которые содержат, например, "&&".

Инструменты, которые вы можете найти полезными в порядке утонченности:

  • perldoc -q вложение, как указано выше
  • Модуль Text :: Balanced (доступен из коробки с любой версией perl> = 5.8)
  • Модули генератора синтаксического анализатора * CPAN Parse :: Yapp и Parse :: RecDescent . Yapp недокументирован, но не страдает от некоторых патологических проблем, от которых страдает P :: RD.
  • Parse :: Eyapp , по-видимому, сочетает в себе достоинства обоих вышеупомянутых модулей.
0 голосов
/ 23 декабря 2009

Для этого я думаю, что я бы пошел с чем-то вроде PPI , который часто выполняет достаточно хорошую работу по разбору исходных текстов Perl, и, безусловно, будет лучше для большинства людей, начиная с нуля.

Вы также можете посмотреть на Devel :: Cover , которая включает такую ​​информацию в свой отчет как часть своей метрики условного покрытия.

0 голосов
/ 22 декабря 2009

Я надеюсь, что вы можете узнать что-то из этого.

use 5.010;
use Text::Balanced qw(extract_bracketed);
my $logical_keywords = join '|', qw(while if);
my $logical_operators = join '|', map {quotemeta} qw(|| &&);

my $code = do { local $/; <DATA>; }; # slurp the whole thing into a scalar

for my $chunk (split /$logical_keywords \s+/msx, $code) {
    # a chunk is the (...)... part after an »if« or »while«
    # until the next »if« or »while«

    next unless $chunk =~ /\A [(]/msx;
    # discard preceding junk

    my $balanced_parentheses = extract_bracketed($chunk, '()');
    # only the (...) part after an »if« or »while«

    my @conditions = split /(?<=$logical_operators)/msx, $balanced_parentheses;

    say scalar(@conditions). " conditions were found. And here's the enumerated code block.";
    my $index = 0;
    for my $condition (@conditions) {
        $index++;
        my ($pre, $post) = $condition =~ /( (?: [(] | \s )* ) (.*)/msx;
        print "$pre $index $post";
    }
    say; # force a new line
}

__DATA__
# start of the source code.

while(
      condition1 &&
      condition2 ||
      condition3
     )
{
  #statements;
}

# some other code

while(
        (
         condition1 &&
         condition2 &&
         condition3
        ) ||
        (
          condition4 ||
          condition5 &&
          condition6
         )
)
{
  #statements;
}

(some (nested (nonsense))) || (
);

if (
    (
    condition1 &&
    condition2
    ) ||
    ((
    condition3
    ) ||
    (
    condition4 &&
    condition5
    ))
)
{
    ((these parentheses do not count) &&
        neither does this.
    );
}

Выход:

3 conditions were found. And here's the enumerated code block.
(
       1 condition1 &&
       2 condition2 ||
       3 condition3
     )
6 conditions were found. And here's the enumerated code block.
(
        (
          1 condition1 &&
          2 condition2 &&
          3 condition3
        ) ||
        (
           4 condition4 ||
           5 condition5 &&
           6 condition6
         )
)
5 conditions were found. And here's the enumerated code block.
(
    (
     1 condition1 &&
     2 condition2
    ) ||
    ((
     3 condition3
    ) ||
    (
     4 condition4 &&
     5 condition5
    ))
)
...