bmstu-iu9 / bmstu-iu9/refal-5-lambda

Рефакторинг синтаксического дерева

Open
#315 5 comments 0 reactions 1 assignee Claimed by @Mazdaywik View on GitHub
task
Dominant language
C++
Stars
97
Forks
40
PR merge metrics
No merged PRs in 30d

Description

Мотивация
========
Предлагается упростить синтаксическое дерево на выходе рассахаривания. Упрощение позволит писать более простой и лаконичный код. Писать `(Symbol Identifier e.Name)` или `(TkVariable s.Mode e.Index s.Depth)` слишком громоздко, тем более префикс `Tk` в слове `TkVariable` уже не имеет смысла на проходах после синтаксического анализа.

Многие из этих имён уже являют собой древнее легаси. Например, тот же префикс `Tk` в `TkVariable` и `(Symbol Name e.Name)` и `(Symbol Identifier e.Name)`. Последнее сохранилось со времён Простого Рефала, когда исходно в нём не было идентификаторов, а были имена функций и для них было удобно писать `TkName`. Позже добавились идентификаторы, для которых был введён новый тип `TkIdentifier`. В ходе решения задачи #198 узлы `(TkName e.Name)` и `(TkIdentifier e.Name)` были механически переименованы в `(Symbol Name …)` и `(Symbol Identifier …)`, я тогда даже не задумался дать им более подходящие имена.

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

Реализация
========
Изменения будут двух видов:
* переименования, сокращающие размер текста,
* изменения структуры.

Переименования узлов
---------------------------
* `Symbol` → `Sym`,
* `Symbol Identifier` → `Sym Word`,
* `Symbol Name` → `Sym Func` или `Sym Ptr`,
* `Symbol Number` → `Sym Num` или `Sym Number`,
* `Brackets` → `Parens`,
* `CallBrackets` → `Call`,
* `ADT-Brackets` → `ADT`,
* `ClosureBrackets` → `Closure`,
* `TkVariable` → `Var`.

Изменения структуры
-------------------------
### Узлы `(Extern e.Names)`, `(Entry e.Names)`, `(Drive e.Names)`…
Вместо того, чтобы рассыпать по дереву ненужные метки `Declaration`, имеет смысл после рассахаривателя сразу собрать все актуальные внешние имена в один список. Это упростит и генерацию кода, и предшествующие проходы.

Точно также удобно будет собрать все entry-функции в одну кучу. В этом случае можно отказаться от метки `s.ScopeClass` в дереве для самых разных элементов.

С метками `Drive` и `Inline` аналогично.

### Удалить глубину у переменных
Добавление поля глубины было простейшим способом реализовать сокрытие переменных, т.е. назначение разных имён переменным в разных областях видимости при совпадении их индексов. Но, как сказано выше, это частное решение сильно усложняет и проходы древесной оптимизации, и проход рассахаривания условий, и затрудняет чтение лога.

Новые имена можно назначать и более консервативным способом — функцией `NewVarName`. В этом случае поле `s.Depth` исчезнет изо всех образцов и результатов, что существенно упростит работу с деревом.

### Удалить `$SCOPEID`
Про это отдельная задача #284. Сюда написал для полноты картины.

### Указатель направления сопоставления с образцом
Образцы нужно будет представлять не как `(e.Pattern)`, а как `(L e.Pattern)` или `(R e.Pattern)`. Это изменение потребуется для задачи #175. Раз уж большой рефакторинг делается, то почему бы и не сделать это сейчас.

### Координаты для предложений (?)
Тут я пока не уверен. Для задачи #256 изначально предполагалось добавить в дерево координаты предложений, чтобы при выводе предупреждений показывать на них. Но решили дерево не менять, вместо этого выводить координаты функции и указывать на предложения в нотации суффиксов функций.

Во время рефакторинга можно добавить координаты в дерево до рассахаривания, чтобы сообщать о них при проверке. Но надо ли?

### Представлять имена и индексы переменных как слова (?)
Тоже неоднозначный вопрос. Можно представлять значения символов-слов и символов-функций до префикса, а также индексы переменных как символы-слова. С одной стороны, это приведёт к аллокации большого количества символов-слов, которые никаким сборщиком мусора не чистятся. С другой — повысится быстродействие, т.к. сравнение одного символа быстрее, чем сравнение строки.

Исследовать этот вопрос можно — написать отдельный коммит, померить быстродействие, и если не понравится, откатить коммит.

Дополнительные замечания
===================
* Задача, хоть и ремесленная, не выносится на практику. Я планирую летом заняться задачами, связанными с древесными оптимизациями. Задача рефакторинга с ними не параллелится в принципе, а ждать, когда студент сделает рефакторинг и отладит, слишком долго.
* Задача #198 в некотором смысле является подзадачей настоящей задачи.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.