Почему мой Perl-скрипт не находит плохой неопределенности от моего соответствия регулярному выражению - PullRequest
4 голосов
/ 12 августа 2011

Стандарт кодирования моей работы использует отступ в скобках:

some declaration
    {
    stuff = other stuff;
    };

control structure, function, etc()
    {
    more stuff;
    for(some amount of time)
        {
        do something;
        }
    more and more stuff;
    }

Я пишу Perl-скрипт для обнаружения неверного отступа. Вот что у меня в теле while(<some-file-handle>):

# $prev holds the previous line in the file
# $current holds the current in the file
if($prev =~ /^(\t*)[^;]+$/ and $current =~ /^(?<=!$1\t)[\{\}].+$/) {
    print "$file @ line ${.}: Bracket indentation incorrect\n";
}

Здесь я пытаюсь найти соответствие:

  • $prev: строка не заканчивается точкой с запятой, за которой следует ...
  • $current: строка , а не , имеющая количество ведущих вкладок + 1 предыдущей строки.

В данный момент это не похоже ни на что.

Ответы [ 4 ]

0 голосов
/ 13 августа 2011

Рассматривали ли вы глядя на Perltidy ?

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

Я на самом деле не использовал его, но, возможно, стоит посмотретьВаша проблема - попытаться найти все различные крайние случаи и убедиться, что вы обрабатываете их правильно.Вы можете проанализировать 100 программ, чтобы найти, что 101-я обнаруживает проблемы в вашем форматере.Perltidy был использован тысячами людей на миллионах строк кода.Если есть проблема, она, вероятно, уже найдена.

0 голосов
/ 12 августа 2011

А вы собираетесь рассчитывать только табуляцию (не пробелы) для отступа?

Написание этого вида проверки сложно. Просто подумайте обо всех возможных конструкциях, использующих фигурные скобки, которые не должны изменять отступ:

s{some}{thing}g

qw{ a b c }

grep { defined } @a

print "This is just a { provided to confuse";

print <<END;
This {
  $is = not $code
}
END

Но в любом случае, если перечисленные выше проблемы не важны для вас, подумайте, важна ли точка с запятой вообще в вашем регулярном выражении. Ведь написание

while($ok)
    {
    sort { some_op($_) }
        grep { check($_} }
        my_func(
            map { $_->[0] } @list
        );
    }

Должно быть возможно.

0 голосов
/ 12 августа 2011

я вижу пару проблем ...

  1. Ваше предыдущее регулярное выражение соответствует всем строкам, которые не имеют; в любом месте. которая будет разбиваться на строки типа (для int x = 1; x <10; x ++) </li>
  2. если отступ в открытии {неверен, вы его не обнаружите.

попробуйте вместо этого, это заботится только о том, что у вас есть; {(за которым следует любой пробел) в конце .

/^(\s*).*[^{;]\s*$/

теперь вы должны изменить свою стратегию так, чтобы, если вы видите строку, которая не заканчивается на {или; Вы увеличиваете счетчик отступа.

если вы видите строку, которая заканчивается на}; или} уменьшить счетчик отступов.

сравнить все строки с этим

/^\t{$counter}[^\s]/ 

так ...

$counter = 0;

if (!($curr =~ /^\t{$counter}[^\s]/)) {
    # error detected
}

if ($curr =~ /[};]+/) {
  $counter--;

} else if ($curr =~ /^(\s*).*[^{;]\s*$/) }
  $counter++;

}

извините за то, что я не разработал мой код в соответствии с вашими стандартами ...:)

0 голосов
/ 12 августа 2011

переменная $ prev нуждается в некоторой модификации.

это должно быть что-то вроде \t*, затем .+, затем не заканчивается semicolon

, $ current должен быть похож на:

все, что заканчивается ; или { или } , а не , имеющее количество ведущих вкладок + 1 предыдущей строки.

РЕДАКТИРОВАТЬ код perl, чтобы попробовать $prev

#!/usr/bin/perl -l

open(FP,"example.cpp");

while(<FP>)
{
  if($_ =~ /^(\t*)[^;]+$/) {
    print "got the line: $_";
  }
}

close(FP);

// example.cpp

for(int i = 0;i<10;i++)
{
  //not this;
  //but this
}

// output

got the line: {

got the line:   //but this

got the line: }

это сделалне определить строку с циклом for ... я что-то упустил ...

...