Введение
Многие C++ программисты слышали про разработку через тестирование. Но почти все материалы по данной теме касаются более высокоуровневых языков и сосредоточены больше на общей теории, чем на практике. Итак, в данной статье я попробую привести пример пошаговой разработки через тестирование небольшого проекта на C++. А именно, как можно предположить из названия, простого интерпретатора математических выражений. Такой проект также является неплохой code kata, так как на его выполнение затрачивается не более часа (если не писать параллельно статью об этом).
Архитектура
Несмотря на то, что при использовании TDD архитектура приложения постепенно проявляется сама собой, начальная её проработка всё же необходима. Благодаря этому может значительно снизиться общее время, затраченное на реализацию. Это особенно эффективно в тех случаях, когда существуют готовые примеры подобных систем, которые можно взять за образец. В данном случае, существует вполне устоявшееся мнение о том, как должны быть устроены компиляторы и интерпретаторы, чем и можно воспользоваться.
Для начала, составим список того, что должен уметь наш простой интерпретатор, в порядке убывания приоритета:
- Вычислять значение математического выражения, состоящего из чисел с плавающий точкой и математических операторов (-+/*).
- Учёт приоритета операторов.
- Учёт скобок.
- Унарные плюс и минус.
- Вычисление нескольких выражений, разделённых точкой с запятой (;).
- Встроенные константы (pi, e).
- Создание собственных констант с помощью оператора присваивания (=).
- Встроенные функции с переменным числом аргументов.
- Задание новых функций.
В данной статье будет реализация только первых трёх пунктов. Сам проект концептуально будет состоять из четырёх частей:
- Лексический анализатор. Преобразовывает входную строку в последовательность токенов.
- Синтаксический анализатор. Строит из токенов синтаксическое представление в виде постфиксной нотации. Делать это будем без рекурсии и таблиц, с помощью алгоритма сортировочной станции.
- Вычислитель. Вычисляет результат выражения на стековой машине.
- Собственно, интерпретатор. Служит фасадом для вышеперечисленных частей.
Инструментарий
Программа будет писаться в Visual Studio 2013 с установленным Visual C++ Compiler Nov 2013 CTP. Тесты будут на основе встроенного в студию тестового фреймворка для C++ проектов CppUnitTestFramework. Он предоставляет минимальную поддержку для написания модульных тестов (по сравнению с Boost.Test, или CppUTest), но, с другой стороны, хорошо интегрирован в среду разработки.
Итак, создадим новый проект типа «Native Unit Test Project» и удостоверимся, что всё компилируется.
Читать полностью »