Проверка содержания метода C # - PullRequest
4 голосов
/ 19 марта 2010

Мне нужно проверить содержимое метода C #.

Меня не волнуют синтаксические ошибки, которые не влияют на область действия метода.

Я забочусь о символах, которые лишат законной силы анализ остальной части кода. Например:

method()
{
  /* valid comment */
  /*           <-- bad
  for (i..) {
  } 
  for (i..) {  <-- bad
}

Мне нужно проверить / исправить любые непарные символы.

Сюда входят / * * /, {} и, возможно, другие.

Как мне поступить об этом?

Моей первой мыслью было Regex, но это явно не поможет.

Ответы [ 5 ]

3 голосов
/ 19 марта 2010

Чтобы получить разумный ответ, вам нужно более тщательно оценить проблему.

Например, что вы собираетесь делать с методами, содержащими директивы препроцессора?

void M()
{

#if FOO
    for(foo;bar;blah) {
#else
    while(abc) {
#endif
        Blah();
    }
}

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

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

1 голос
/ 19 марта 2010

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

  1. Создать пустой стек S.
  2. Пока (осталось символов) {
  3. Прочитайте символ ch.
  4. Если ch является открывающим пареном (любого типа), наденьте его на S
  5. Остальное
  6. Если ch - закрывающая скобка (любого рода), посмотрите на верхнюю часть S.
  7. Если в качестве этой точки S пусто, сообщите об ошибке.
  8. Если вершина S - это открывающая фигура, которая соответствует c, затем нажмите S и переходите к 1, эта пара соответствует OK.
  9. Остальное сообщить об ошибке.
  10. Если в конце ввода стек S не пуст, вернуть ошибку. Остальное вернет успех.

для получения дополнительной информации проверьте http://www.ccs.neu.edu/home/sbratus/com1101/lab4.html и http://codeidol.com/csharp/csharpckbk2/Data-Structures-and-Algorithms/Determining-Where-Characters-or-Strings-Do-Not-Balance/

1 голос
/ 19 марта 2010

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

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

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

0 голосов
/ 19 марта 2010

Вы рисуете ложную дихотомию между «символами, которые отменяют синтаксический анализ остальной части кода» и «синтаксическими ошибками». Отсутствие закрывающей фигурной скобки (одна из упомянутых вами проблем) является синтаксической ошибкой. Похоже, вы имеете в виду, что ищете синтаксические ошибки, которые потенциально нарушают границы области видимости? К сожалению, не существует надежного способа сделать это за исключением использования полного синтаксического анализатора.

Как пример:

method()
{ <-- is missing closing brace
  /* valid comment */
  /*           <-- bad
  for (i..) {
  } 
  for (i..) {  
} <-- will be interpreted as the closing brace for the for loop

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

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

0 голосов
/ 19 марта 2010

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

Написание собственного полнофункционального парсера для проверки будет очень и очень сложно, особенно если вы хотите поддерживать C # 3 или более позднюю версию. Лямбда-выражения и другие подобные конструкции будет очень трудно "проверить" чисто.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...