Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 40 additions & 7 deletions tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -501,20 +501,44 @@ def tree_to_program(tree: ParserRuleContext) -> str:

## Задача 12. Интерпретатор языка запросов к графам

Полный балл: 22
Полный балл: 35

В данной задаче необходимо разработать интерпретатор языка запросов, разработанного в предыдущей работе. Для исполнения запросов использовать алгоритмы, реализованные в предыдущих работах. Кроме реализации необходимо предоставить минимальную документацию, поясняющую принятые в процессе реализации решения (например, в readme).
Балл складывается из следующих подзадач.

Обратите внимание, что кроме непосредственно интерпретатора необходимо реализовать вывод типов. Тестирование данной функциональности должно быть возможно в изоляции. Фактически, должна быть реализована отдельная функция, которая по дереву разбора выводит типы и кидает исключение, если программа не можете быть типизирована корректно.
* Простой однопроходный интерпретатор: 10
* Вывод типов: 10
* Проверять необъявленные нетерминалы: 5
* Проверять недостижимые нетерминалы: 5
* Проверять непорождающие нетерминалы: 5

В данной задаче необходимо реализовать интерпретатор языка запросов, разработанного в предыдущей работе. Для исполнения запросов использовать алгоритмы, реализованные в предыдущих работах. Кроме реализации необходимо предоставить минимальную документацию, поясняющую принятые в процессе реализации решения (например, в readme).

Обратите внимание, что кроме непосредственно интерпретатора необходимо реализовать вывод типов и проверку корректности запросов.
Тестирование данной функциональности должно быть возможно в изоляции.
Фактически, должна быть реализована отдельная функция, которая по дереву разбора выводит типы и кидает исключение, если программа не может быть типизирована корректно.
Аналогично с обнаружением необъявленных, недостижимых, непорождающих нетерминалов.
Важно, что все проверки производятся "статически" до непосредственно выполнения программы.

- [ ] Используя парсер из предыдущей работы и выбранные алгоритмы, реализовать простой однопроходный интерпретатор языка, описанного в предыдущей задаче.
- На данном этапе реализовать проверки не требуется. Можно реализовать самое "наивное" поведение с пошаговым исполнением программы, которое прерывается при первой же проблеме.
- Требуется реализовать функцию, которая по дереву разбора, предоставленному ANTLR, вернёт пару из словаря, содержащего для всех связываний, где в правой части `select`, имя (левую часть связывания) в качестве ключа, а в качестве значения --- результат выполнения соответствующего запроса, и статуса выполнения (удалось ли выполнить всё до конца или же произошла ошибка). Обратите внимание, что такой словарь должен быть построен для всего корректного префикса программы. Условно, если третий `select` не удалось выполнить, то вернётся словарь с результатами для первых двух и флагом `false`, говорящем о том, что в процессе исполнения возникла ошибка.
- Проследите за адекватностью сообщений об ошибках. Вам же проще отлаживаться будет.
- Постарайтесь максимально использовать возможности ANTLR по работе с деревом разбора.

- [ ] Реализовать механизм вывода типов, гарантирующий корректность построения запросов (в частности, что не строится пересечение двух контекстно-свободных языков, или что множества вершин задаются значениями допустимых типов).
- На данном этапе считаем, что все объявления сделаны корректно (все нетерминалы объявлены, все достижимы, все порождающие).
- Работа системы типов должна соответствовать правилам, указанным предыдущей задаче.
- Постарайтесь сделать сообщения об ошибках максимально дружественными к пользователю.
- Вывод типов запускается до интерпретации и помогает интерпретатору использовать правильные алгоритмы (если типизировалось как регулярное, то и алгоритм для регулярных). Если типизация не прошла, то интерпретатор не запускается.

- [ ] Реализовать функцию обнаружения необъявленных нетерминалов. Функция принимает дерево разбора и возвращает **все** необъявленные нетерминалы. Проверка выполняется до интерпретации вывода типов. Если проверка не пройдена, следующие шаги не запускаются. Помните, что у нас декларативное описание грамматики (запроса), потому объявление может идти после использования.

- [ ] Реализовать функцию обнаружения недостижимых нетерминалов. Функция принимает дерево разбора и возвращает **все** недостижимые нетерминалы. Проверка выполняется до интерпретации вывода типов. Если проверка не пройдена, следующие шаги не запускаются.

- [ ] Реализовать функцию обнаружения непорождающих нетерминалов. Функция принимает дерево разбора и возвращает **все** непорождающие нетерминалы. Проверка выполняется до интерпретации вывода типов. Если проверка не пройдена, следующие шаги не запускаются.

- [ ] Из множества реализованных в предыдущих работах алгоритмов выполнения запросов к графам выбрать те, которые будут использоваться в интерпретаторе. Обосновать свой выбор (зафиксировать в документации).
- [ ] Используя парсер из предыдущей работы, разработанную систему вывода типов, выбранные алгоритмы, реализовать интерпретатор языка, описанного в предыдущей задаче.
- Требуется реализовать функцию, которая по дереву разбора, предоставленному ANTLR, вернёт словарь, содержащий для всех связываний, где в правой части `select`, имя (левую часть связывания) в качестве ключа, а в качестве значения --- результат выполнения соответствующего запроса.
- Проследите за адекватностью сообщений об ошибках. Вам же проще отлаживаться будет.
- Постарайтесь максимально использовать возможности ANTLR по работе с деревом разбора.

- [ ] Добавить необходимые тесты.

Требуемые функции:
Expand All @@ -525,4 +549,13 @@ def typing_program(program: str) -> bool:

def exec_program(program: str) -> dict[str, set[tuple]]:
pass

def find_undefined_nonterminals(program: str) -> set[str]:
pass

def find_unreachable_nonterminals(program: str) -> set[str]:
pass

def find_non_generative_nonterminals(program: str) -> set[str]:
pass
```
Loading