Re: Refal+ abstract syntax


Subject: Re: Refal+ abstract syntax
From: Andrey Slepuhin (pooh@msu.ru)
Date: Fri Dec 17 1999 - 18:55:33 MSK


Arkady Klimov wrote:
>
> Андрей, спасибо, это уже почти то, что надо.
> "У целом" принимается.
>
> А теперь перейдем к постатейному обсуждению.
>
> Но сначала одно общефилософское замечание.

[note snipped]

С моей точки зрения главное в АС - это
1) Общий синтаксис для всех рефалов.
2) Самодостаточное описание модуля, не требующее никакой дополнительной
   информации для его компиляции.

Во всех своих утверждениях я исхожу именно из этого.

> А теперь перейдем к обсуждению по пунктам.
>
> Сначала по изменениям.
>
> ----- Original Message -----
> From: Andrey Slepuhin <pooh@msu.ru>
> To: Arkady Klimov <klark@bagirra.rinet.ru>
> Cc: Sergei M. Abramov <abram@botik.ru>; <refal@botik.ru>
> Sent: Thursday, December 16, 1999 6:11 AM
> Subject: Re: Refal+ abstract syntax
>
> > Добрый день всем!
> >
> > Извиняюсь за некоторую паузу в дискуссии.
> > Я еще раз внимательно посмотрел на проект абстрактного синтаксиса
> > и сделал свой вариант. Он лежит на
> >
> > http://forest.nmd.msu.ru/~pooh/refal_abstract_syntax.html
> >
> > На самом деле принципиальных различий практически нет, так что
> > я думаю, что утверждение окончательного варианта не за горами.
> > Что я изменил (по порядку):
> >
> > 1) t.ProgramFile заменено на t.Module (чисто косметическая замена :-))
> > 2) t.Source удалено - вместо этого нужно использовать прагмы
> > (тем более, что абстрактный синтаксис не обязательно может
> > иметь какой-то исходный текст)
> ОК
> > 3) t.Import удалено - на уровне абстрактного синтаксиса нельзя ничего
> > вытащить из других модулей, т.к. их представление в АС может и не
> > существовать. Вместо этого каждый объект имеет свой описатель
> > IMPORT/EXPORT/LOCAL. Если нужно сохранить информацию о том,
> > из каких модулей импортировались объекты - можно использовать прагмы.
> Это, конечно же, нужно, поэтому непонятно,
> почему для этого надо прибегать к прагмам.
> Причем это нужно будет сохранять не только в АС, но и в загрузочном модуле.
> Нам наконец пора иметь возможность (не обязательно в любой реализации,
> но хотя бы в некоторых) обеспечить цивилизованную динамическую загрузку.
> Цивилизованной я называю такую, когда при загрузке модуля автоматически
> могут быть подзагружены все используемые в нем модули, если они еще
> не загружены. При этом также не нужно будет перечислять имена всех
> модулей для начальной загрузки. (Сейчас в рефале-6 загрузка не является
> цивилизованной)
> Поэтому предлагаю.
> а) Оставить список (USE e.ModuleNames).
> б) В имени функции (REF s.name) разрешить использовать полные имена для
> внешних функций: (REF s.ModuleName s.Name). Имена таких функций s.Name
> могут безболезненно пересекаться с другими локальными или внешними
> фунциями. Можно ввести стадию разрешения, которая будет пополнять все
> ссылки (REF s.Name) до полных.
> в) В s.ModuleName можно использовать точку, которая при превращении в имя
> файла переходит в слеш.
> г) Считать ошибкой, если есть простая ссылка с именем, которое не
> определено
> ни локально, ни в одном из USEd модулей.
> д) Декларации внешних функций пополнить именем модуля, где обнаружено
> определение функции. Эти декларации вставляются на стадии разрешения,
> а изначально могут отсутствовать (см.ниже).

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

<name> ::= <simple_name> | <module_name>.<simple_name>
<module_name> ::= <level_name> | <module_name>.<level_name>

При этом алгоритм следующий: если парсер встретил объявление имени -
то имя полностью раскрывается со всеми префиксами модулей и помещается в
таблицу. Если же имя встретилось в момент использования, то оно ищется
в таблице, но не по полному совпадению, а по совпадению с "хвостом".
Если таких совпадений несколько - то ругаться, что имя слабо
специфицировано. Получается как в Java или C++... Тогда если в
абстрактном синтаксисе оставить только полностью специфицированные имена
(а оно так и должно быть), то в принципе можно обойтись и без USE
(а также и без linkage-спецификаторов - ведь для каждого имени будет
известен модуль, где оно определено).
А при компиляции в какой-то формат для динамической загрузки можно,
если что, создавать хэш-таблицу нужных модулей. Кроме того так мы не
потянем за собой никаких ненужных модулей если кто-то по ошибке
подключил их с помощью $use.

> > 4) Описания определений всех объектов изменены в соответствии с 3).
>
> Вспомним философское замечание в начале письма. Данное изменение
> предполагает, что поиск внешних определений произведен на стадии
> до формирования АС, то есть парсером. Я не уверен, что это правильно.
> Можно ли услышать аргументацию за это?
> Мне лично кажется, что парсеру следовало поручить только обработку
> отдельного файла,
> а разрешение внешних имен выполнить как этап обработки в рамках АС.

Дело то в том, что модуль может и не существовать в виде АС,
а например будет только в откомпилированном виде + include file.
И что тогда делать? Парсер абстрактного синтаксиса не должен иметь
дело с синтаксисом include file'а конкретного рефала. Здесь есть некая
аналогия с .class-файлами в той же Java - там все имена уже полностью
специфицированы.

> При разрешении имен ведь нужно будет обращаться к интерфейсам других
> модулей, то есть опять же к парсеру от них. (А если интерфейсы не отделены,
> то и к парсеру от самих модулей). А что разрешатель будет иметь
> как исходый материал для своей работы?
> Если же парсер сделать только считывающим один файл, то разрешение имен
> тогда
> формализуется как этап обработки АС-терма, пополняющий его информацией.
> Для некоторых реализаций (компиляторов) он будет не нужен (как например
> для Рефала-6, с учетом его виртуального кода).
>
> > 5) Добавлен оператор FLUSH - см. мое письмо от 26 ноября в 16:14.
> > В принципе возможна альтернатива - результаты по умолчанию
> > замещаются, но есть оператор CONC.
> Я не понимаю, зачем он нужен. Давайте лучше введем расширение для
> t.ResultTerm:
>
> t.ResultTerm ::= ...
> | t.Block
>
> А Flush пусть всегда присутствует "по умолчанию". Если же нужно
> сконкатенировать
> предыдущий результат со следующим t.Result или t.Block, то сделать это надо
> явно.

Можно и так - я абсолютно не возражаю, наверное так даже лучше.

> (Возникает вопрос, а как вставить непрозрачный блок? Ответ: поставить
> NOFAIL,
> но не перед блоком, а перед всем результатным выражением.)
>
> > 6) NOT и ITER сохранены как есть. С моей точки зрения их раскрытие
> > слишком далеко двигает нас в сторону виртуального кода и может
> > привести к менее удобному представлению при компиляции в
> > императивные языки.
> Это нормально. Но не отменяет возможности на ранней стадии компиляции
> устранить NOT и ITER путем их раскрытия в АС же. Я не вижу почему эти
> раскрытия специфичны для какого-то одного типа реализации. Полагаю,
> они универсальны.

Я не против возможных расширений, но мне существенно не нравится
использование
LABEL в раскрытии ITER. Я бы еще согласился на

t.Label ::= (LABEL s.LabelName e.Sentence)

чтобы получились помеченные предложения, но не LABEL как
абстрактная метка.

> > 7) Немного изменены прагмы - но это не существенно.
> > 8) В конце приведен вариант синтаксиса, в котором есть нераскрытые
> > константы.
> Это хорошо. Неясно теперь, как используются константы в теле программы.
> Например, можно как (REF name), имея в виду, что такая конструкция всегда
> подразумевает ее замену на значение константы по имени name. В случае
> фукнций
> и объектов следует считать, что строятся автоматически определения
> констант,
> значениями которых являются настоящие символы-ссылки.
> Однако, обращаю внимание, что значением константы в общем случае будет
> не обязательно символ, и даже не обязательно терм. Но всегда - объектное
> (в смысле - ground) выражение, которое может быть всюду, включая жесткий
> образец.

Как я уже писал - я бы ограничил константы до терма и ввел define'ы,
которые раскрываются сразу - на самом деле этого хватает для всего.
Я думаю, на первых порах можно константы сразу раскрывать, а позже
эту часть синтаксиса довести до ума.

> Да, это расширение из Рефала-6. Он означает, что выражение должно быть
> вычислено в момент загрузки. Вычисляется ради побочного эффекта,
> значение игнорируется. Есть одна тонкость: момент вычисления определяется
> положением среди других элементов. При этом нет гарантии, что нижеследующие
> определения функций уже загружены и могут выполняться. Также уже должны
> быть загружены целиком другие модули, которые используются из данного.
> А это, в частности, означает, что в графе использований модулями друг друга
> не должно быть циклов.
> Вообще, я думаю, это полезная конструкция, посколку позволяют делать
> модули,
> которые содержат в себе свою инициализацию (содержимого ящиков, например),
> и не требуют от пользователя вызывать инициализацию явно.
> Кроме того, такие модули могут представлять самодостаточные программы, не
> требующие указывать их входные точки (GO, Main, и т.п.).

Это все понятно и хорошо, правда проблем - не оберешься (см. мое
следующее
письмо).

> А теперь несколько новых замечаний-дополнений.
>
> 1. Для объектов типов BOX, STRING, VECTOR и, возможно, TABLE - вести
> понятие начального значения:
>
> t.Object ::= (s.Linkage s.ObjectType s.ObjectName e.InitialValue)
>
> e.InitialValue ::= e.ResultExpression
>
> (ограничения - те же, что и для initializer'а.

Я уже думал над этим. Только непонятно, кто будет проверять, что
начальное значение, скажем для VECTOR имеет корректный формат?
И еще - начальное значение возможно только для s.IntLinkage.

> 2. PragmaTrace. Отсутствует traceAll. Преднамеренно?

Да. TraceAll - это Trace с пустым списком.

> 3. В последнем письме от 17.12 ты предлагаешь разделить декларацию и
> определения.
> Мне кажется, это тоже можно вводить как стадию обработки в рамках АС. Но
> может
> компилятору это и не требуется?

Компилятору в момент использования функции надо знать ее форматы.
Если не разносить декларацию и определение, то потребуется два прохода.

> Надеюсь, не слишком утомил?

Конечно, нет :-))

Всего доброго,
Андрей.



This archive was generated by hypermail 2b25 : Mon Oct 25 2004 - 21:24:58 MSD