Лабораторная №4 — задание 4.2D #
Нужно реализовать класс Interpreter, представляющий интерпретатор вашего языка программирования. На основе этого класса надо реализовать:
- Консольную программу — интерпретатор с поддержкой ввода/вывода
- Функциональные тесты, проверяющие обработку примеров программ, подготовленных аналитиком
⚠️ Обратите внимание #
Это задание выполняется по примерам программ, подготовленным аналитиком в задании 4.2A.
- Примеры должны появиться до начала кодирования — так же, как и в реальных проектах.
- Вы можете составлять примеры совместно с аналитиком, а затем приступить к реализации.
- Ждать проверки задания аналитика преподавателем не нужно.
Порядок выполнения #
- Получите примеры программ для своего языка программирования у аналитика
- Создайте пустой проект интерпретатора:
dotnet new classlib -o src/Interpreter- добавьте его в решение:
dotnet sln add src/Interpreter - добавьте ссылку на библиотеку синтаксического анализа:
dotnet add src/Interpreter reference src/Parser
- добавьте его в решение:
- Создайте пустой проект тестов:
dotnet new xunit -o tests/Interpreter.Specs- добавьте его в решение:
dotnet sln add tests/Interpreter.Specs - добавьте ссылку на библиотеку из проекта тестов:
dotnet add tests/Interpreter.Specs reference src/Interpreter
- добавьте его в решение:
- Сразу добавьте в проект
tests/Interpreter.Specsтесты для всех примеров программ, подготовленных аналитиком - Затем добавьте класс Interpreter в модуле
src/Interpreter/и пройдите все тесты
Требования к тестам #
Вы сами выбираете инструмент для приёмочных тестов:
- Вы можете использовать Gherkin для тестов интерпретатора: Gherkin для приёмочных тестов.
- Вы также можете не использовать Gherkin, опираясь только на базовые возможности фреймворка тестов и многострочные литералы для описания программ в тестах.
В любом варианте типичный тест содержит три шага:
- Пусть я написал программу:
""" ... многострочный код ... """ - Когда я ввожу в консоли:
""" ... текст ввода ... """ - Тогда я увижу в консоли:
""" ... текст ожидаемого вывода ..."""
Вместо реального ввода-вывода можно в тестах создать дублирующий класс, который используется тестом, чтобы записать ввод и прочитать фактический вывод интерпретатора — см. FakeEnvironment в примере ниже.
Структура модуля Interpreter #
Предлагаемая диаграмма классов показана ниже. Вы можете реализовать иной вариант на своё усмотрение.
classDiagram
direction LR
class Context {
<<контекст выполнения программы>>
+PushScope(Scope scope)
+PopScope()
+DefineVariable(name: string, value: decimal)
+AssignVariable(name: string, value: decimal)
+GetValue(name: string): decimal
}
class IEnvironment {
<<ввод-вывод>>
+ReadNumber(): decimal
+WriteNumber(value: decimal)
}
class ConsoleEnvironment {
<<консольный ввод-вывод>>
+ReadNumber(): decimal
+WriteNumber(value: decimal)
}
class FakeEnvironment {
<<симулирует ввод-вывод в тестах>>
+ReadNumber(): decimal
+WriteNumber(value: decimal)
}
class Interpreter {
<<фасад>>
-_context: Context
-_environment: IEnvironment
+Execute(code: string)
}
Interpreter --o Context : содержит
Interpreter --o IEnvironment : содержит
FakeEnvironment --|> IEnvironment : реализует
ConsoleEnvironment --|> IEnvironment : реализует