к надежности которого чрезвычайно высоки.
Компилятор является инструментом, требования к надежности которого чрезвычайно высоки. И это неудивительно, ведь от правильности работы компилятора зависит правильность работы всех скомпилированных им программ. Из-за сложности входных данных и преобразований задача тестирования компиляторов является весьма трудоемкой и непростой. Поэтому вопрос автоматизации всех фаз тестирования (создания тестов, их прогона, оценки полученных результатов) стоит здесь особенно остро. Синтаксический анализ является частью функциональности любого компилятора. От корректности синтаксического анализа зависит корректность практически всей остальной функциональности – проверки семантических ограничений, оптимизирующих преобразований, генерации кода. Поэтому решение задачи тестирования синтаксических анализаторов является базой для решения задач тестирования всех остальных компонент компилятора. Для очень многих языков программирования существует формальное описание синтаксиса – описание грамматики языка в форме BNF, а для тех языков, для которых существуют только эталонные компиляторы (например, COBOL), делаются активные попытки построить такое описание (см.[9, 10, 14]). BNF языка является одновременно и спецификацией функциональности синтаксического анализа, таким образом, в этой области наиболее привлекательным является тестирование на основе спецификаций (см. [17]). Существование формального описания позволяет автоматизировать процесс построения тестов, что существенно снижает трудозатраты, а систематичность тестирования повышает доверие к его результатам. Построением тестов по грамматике занимались многие авторы. Основополагающей работой в этой области является работа [18], в которой сформулирован следующий критерий покрытия для множества позитивных тестов: для каждого правила в данной грамматике в множестве тестов должно присутствовать предложение языка, в выводе которого используется это правило. В той же работе Пардом предложил метод построения минимального тестового набора, удовлетворяющего этому критерию.
Однако указанный критерий оказался недостаточным. Ламмель в работе [9] показал, что тестовые наборы, построенные алгоритмом Пардома, не обнаруживают простейших ошибок. Ламмель также предложил более сильный критерий покрытия, состоящий в том, что покрывается каждая пара правил, одно из которых можно применить непосредственно после другого. Предлагаемые другими авторами методы являются вероятностными (см. [7, 13, 11, 12]) и не описывают критериев покрытия, и потому для них возникает вопрос остановки генерации тестов, который решается, например, с помощью введения вероятностей появления правил и уменьшения этих вероятностей при каждом новом появлении правила в выводе. В любом случае завершение работы алгоритма за конечное время является проблемой. Кроме того, произвольность остановки генерации нарушает систематичность тестирования. Все приведенные выше работы касаются генерации позитивных тестов для синтаксического анализатора (т.е. тестов, являющихся предложениями целевого языка). В настоящее время работы, предлагающие методы генерации негативных тестов для синтаксических анализаторов (т.е. тестов, не принадлежащих целевому языку), практически отсутствуют. Однако такие тесты также важны, поскольку пропуск неверной последовательности лексем на этапе синтаксического анализа может привести к аварийному завершению компиляции. В работе [8] высказано предположение, что если имеется генератор предложений языка из грамматики (генератор позитивных тестов для синтаксического анализатора), то для генерации негативных тестов для синтаксического анализатора можно использовать метод мутационного тестирования (mutation testing)1 (см. [6, 15]). Идея состоит в том, что в исходную грамматику вносятся изменения (мутации) для получения грамматик, описывающих близкие, но не эквивалентные исходному языки. Эти мутированные грамматики подаются на вход генератору тестов для получения потенциально негативных тестов. Общие проблемы данного подхода состоят в следующем:
- Грамматика-мутант может оказаться эквивалентной исходной грамматике.
Такие мутанты должны быть выявлены и не должны использоваться для генерации тестов.
- Даже если грамматика-мутант не эквивалентна исходной, полученные из нее тесты могут оказаться правильными. Выявить эти тесты можно лишь прогнав их через эталонный синтаксический анализатор, которого может и не быть (например, в случае создания нового или расширения существующего языка).