Skip to content

Instantly share code, notes, and snippets.

@reznikmm
Created November 14, 2022 15:35
Show Gist options
  • Save reznikmm/dc1e3f197795d920927cb4f5a6df3dfd to your computer and use it in GitHub Desktop.
Save reznikmm/dc1e3f197795d920927cb4f5a6df3dfd to your computer and use it in GitHub Desktop.

Name Resolution

Разрешение неоднозначностей выполняется в два прохода:

  • Первый (от листьев к корню) собирает возможные интерпретации и поднимается к конструкции названной в ARM complete context (См [http://www.ada-auth.org/standards/12aarm/html/AA-8-6.html ARM 8.6 (4)]). Там выбирается одна из возможных интерпретаций всего поддерева.
  • Второй проход (в обратном направлении от complete context к листьям) распространяет информацию о выбранной интерпретации

Соответственно нужны следующие абстракции:

  • Interpretation (Meaning?) - возможная интерпретация
  • Interpretation_Set - множество возможных интерпретаций
  • Interpretation_Set_Tuple - вектор/кортеж из Interpretation_Set собирает в единое целое несколько независимых множеств интерпретаций, например ассоциация в агрегате A | B => C нужно собрать три множества интерпретаций, которые будут трактоваться в зависимости от контекста.
  • Interpretation_Set_Tuple_List - вектор таких векторов, например для обобщения списка ассоциаций, A | B => C, D => 1

Сами интерпретации бывают такими (в скобках указаны параметры интерпретации):

  • Symbol (идентификатор) - когда известен только идентификатор
  • Defining_Name (ссылка на имя)- когда известно имя обозначаемое конструкцией
  • Expression (тип выражения) - когда известен тип выражения
  • Expression_Category (категория типов)- когда известен лишь категория типа выражения, например строковый тип как результат строчного литерала "Hello"
  • Attr_Function (атрибут) - интерпретация функций обозначаемых атрибутами, например Integer'Image
  • Placeholder () - интерпретация-заменитель, используется там, где должна быть интерпретация по синтаксису, но ее нет, например 1 => <> для бокса

От спускаемых интерпретациях нужно следующее:

  • до identifier, operator_symbol должна дойти интерпретация у которой можно взять Defining_Name
  • для конструкций с несколькими потомками нужно спускать список с элементами соответствующими структуре элемента, например для selected_component нужно иметь элементы для prefix и для selector
  • для конструкций-списков (возвращающих Tuple, Tuple_List) ожидается списки спускаемых интерпретациях с совпадающим кол-вом элементов
  • нужно как-то спускать информацию о типе

Для некоторых конструкций с дочерними элементами, при построении возможных интерпретаций можно выбрать по одной из возможных интерпретаций для каждого дочернего элемента конструкции и составить список соответствующих спускаемые интерпретаций. Если прикрепить этот список к интерпретации, то на обратном проходе достаточно будет выбрать готовые спускаемые интерпретации из списка. К примеру вызов функции F(X), перебрав все интерпретации F, можно выбрать все соответствующие профилю F интерпретацию X и сформировать "возможную интерпретацию" Expression, запомнив в ней выбранные интерпретации F и X. На обратном проходе получив данную интерпретацию для F(X), достаточно взять из нее сохраненные интерпретации F и X, чтобы спустить их в дочерние элементы.

Так можно сделать не для всех конструкций. Интерпретации Symbol, Expression_Category подразумевают, что итоговая интерпретация не известна. Соответственно выбирать спускаемую интерпретацию приходится на обратном проходе, получив Expression или Defining_Name сверху. В качестве примера можно рассмотреть агрегат записи (A => B). Единственная возможная интерпретация будет Expression_Category с категорией "тип запись". На обратном проходе мы получаем Expression с указанием типа выражения, можем выбрать по символу A имя компонента записи, сформировать Defining_Name и передать его элемент A. Аналогично для B мы создадим интерпретацию Expression с типов компоненты A.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment