Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Стили и методы программирования. Учебное пособие для СПО
.pdf
операций.
Еще одну возможность, открываемую переходом к абстрактносинтаксическим определениям, можно увидеть, если определить
эквивалентность подвыражений для сложения и умножения
Здесь абстрактная эквивалентность выражает свойство самой
операции. Опыт показывает, что дальше учета ассоциативности и
коммутативности в абстрактном синтаксисе двигаться весьма опасно.
Рис. 4.1. Оператор печати
Пример на рис. 4.1
иллюстрирует вызов функции:
printf ("\nX1 = %f, X2 = %f\n", X1, X2);
Показанная на рисунке структура абстрактного синтаксиса данного
оператора показывает, как можно ликвидировать привязку конструкции
языка к конкретному синтаксису: остались только имя функции, строка и
два параметра.
Рассмотрим более сложный пример, показывающий родство
абстрактного синтаксиса традиционных языков. На рис. 4.2
показано
абстрактное представление фрагмента текста следующей программы:
. . .
if ( D > 0 )
{
D = sqrt ( D );
Пример 4.5.1. Текст некоторой программы
Стили и методы программированияНепейвода Н.Н.
61

Рис. 4.2. Представление фрагмента текста программы
1)
Язык программирования и алгоритмический язык почти всегда
являются синонимами. В данном пособии они синонимичны.
2)
Нельзя абсолютизировать это требование. Совместные вычисления
могут производиться в неизвестном программисту порядке. Более того,
автору известен случай, когда прагматика (системы Common Lisp) четко
отмечает, что в некотором случае нельзя пользоваться конкретным
линейным порядком, который система порождает, пополняя заданный
пользователем частичный порядок зависимостей, поскольку алгоритм
упорядочивания может быть в любой момент и без предупреждения
заменен. На самом деле такая прагматика часто полностью
соответствует содержательному смыслу создаваемых программ: если два
действия независимы, нельзя предполагать, что одно из них происходит
раньше другого (хотя обычно программист вынужден это предполагать
ввиду идиотизма "современных" систем). Если бы такие прагматические
замечания встречались почаще!
3)
Поскольку синтаксис порою (особенно раньше) отождествлялся с
контекстно-свободной его частью, в литературе иногда можно
встретить термин "статическая семантика " для описания контекстных
зависимостей. Вспоминая определение семантики, мы видим, что такой
Стили и методы программированияНепейвода Н.Н.
62

термин вводит в заблуждение.
4)
Даже возможная противоречивость библиотек друг другу
соответствует стилю содержательного мышления (И.Н. Скопин).
5)
Вообще говоря, данная подсказка избыточна для современных
трансляторов, поскольку распознать шаблон вида <переменная>
":=" <переменная /* та же самая */> "+" 1 и им
подобные не представляет труда не только в тех случаях, когда
<переменная> указана явно, но и тогда, когда она вычисляется
(индексирование, косвенная адресация и т. д.).
6)
Сегодня с помощью семантической прагматики выражают также
расширения модели вычислений, выводящие за рамки исходного
абстрактного исполнителя. К примеру, — системы параллельного
программирования над C++ и FORTRAN MPI и OPEN MP (И. Н.
Скопин).
7)
Модель вычислений препроцессора можно охарактеризовать
следующими свойствами. Исходные перерабатываемые данные — это
текст (любой структуры, не обязательно на языке С), в котором имеются
строки, начинающиеся с символа '#'. Такие строки представляют
команды, управляющие работой препроцессора. Например, #include
. .. заставляет препроцессор вставить некоторый файл в
перерабатываемый текст (не следует понимать это буквально — нужно
просто обеспечить соответствующий эффект). Другой пример:
#define two 2 дает указание препроцессору на то, что в
оставшейся части текста идентификатор two должен заменяться числом
2. Результат вычислений препроцессора — текст, который не содержит
его команд.
8)
Как принято в современной теории, "алгоритмически разрешимое"
далее называется просто "разрешимое".
Стили и методы программированияНепейвода Н.Н.
63

Сентенциальное программирование: Рефал
Глобальные действия и глобальные условия. Конкретизация как один из
видов отождествления. Данные и программы Рефала. Модель
вычислений. Приемы программирования и примеры программ.
Рефал — предметно-эквациональный способ определения функций на
свободном моноиде с дополнительной одноместной операцией.
(А. П. Бельтюков. Определение Рефала для чистых математиков.)
Рефал—замечательный язык!На нем можно запрограммировать все, что
угодно, если, конечно, других языков не знать.
Студент УдГУ
Сентенциальное программирование возникает тогда, когда данные
имеют четкую и достаточно сложную глобальную структуру, действия
направлены прежде всего на перестройку этой структуры, а задача в
целом соответствует инварианту:
действия глобальны, условия глобальны. (5.1)
В этом случае необходимы мощные средства распознавания глобальных
условий, которые естественно погрузить в модель вычислений языка
как атомарные средства. Программист при формулировке условий
может позволить себе не задумываться о том, как происходит их
распознавание, и сосредоточиться на самой важной части: описании
перестроек структуры.
В имеющихся сейчас двух наиболее развитых и альтернативных
системах сентенциального программирования Prolog и Рефал при
распознавании условий происходит еще и подготовка информации для
применения перестройки. Эта особенность —
подготовка информации для действий в ходе распознавания условий,
(5.2)
пожалуй, является характерной для сентенциального
Стили и методы программированияНепейвода Н.Н.
64

программирования. В частности, она отделяет те случаи, когда лучше
пользоваться сентенциальным программированем, и те случаи, когда
целесообразно событийное программирование (см. далее). Проверка
приоритетов и выбор действия с наивысшим приоритетом в качестве
активного точно так же запрятаны в атомарные действия программной
системы, но программист при проверке приоритетов не получает
никакой полезной информации для проведения выбранного действия.
В настоящее время глобальная проверка условий в системах
сентенциального программирования осуществляется путем обработки
метавыражений. Метавыражение отличается от выражения тем, что в
нем встречаются переменные. Например, если маленькими буквами
обозначаются постоянные, а большими -- переменные, то 1+а -выражение, 1+X -- метавыражение. При проверке выясняется
возможность отождествить некоторые метавыражения друг с другом
или с данными и попутно вычисляется подстановка, т. е. функция,
сопоставляющая переменным их значения. подстановка дает
необходимую для выполнения шага работы программы информацию. В
только что приведенном примере при отождествлении вместо X
должно быть подставлено а.
Такой способ работы согласуется с формулировкой глобальных условий
в логике и в теории алгоритмов, но его нельзя считать a priori
исчерпывающим. В дальнейшем могут появиться другие формы
глобальной проверки данных.
Конкретизация
Язык Рефал был создан В. Ф. Турчиным для программирования
символьных преобразований. Исходный толчок он получил от идеи
алгорифмов Маркова (см., например, теоретическое приложение к книге
[21]
), но эта идея была полностью пересмотрена в ходе работы по
созданию языка. Идейный и математический уровень проработки языка
исключительно высокий, но вопросы дизайна почти проигнорированы.
В основе языка лежит (другой по сравнению с языком PROLOG)
частный случай операции отождествления: конкретизация
метавыражения.
Стили и методы программированияНепейвода Н.Н.
65

Под конкретизацией понимается такой частный случай отождествления,
при котором переменные встречаются лишь в метавыражении и поиск
их значений происходит путем подбора без рекурсии.
Язык Рефал определен через три компонента: структуру данных, Рефал машину, обрабатывающую эти данные, и собственно конкретный
синтаксис языка.
Структура данных
Данные, обрабатываемые языком Рефал, представляют собой
последовательности атомов, структурированные несколькими
согласованными между собою видами скобок. Например, в некотором
конкретном синтаксисе такое выражение могло бы иметь вид {a+[b-
(c+d)**2]/3}*(a+d). В поле памяти Рефал -машины
задействованы два вида скобок: структурные и функциональные.
Выражения языка Рефал.
1. Атомы являются выражениями.
2. Любая последовательность выражений является выражением.
3. Выражение E, заключенное в структурные скобки, является
выражением. Атомы и выражения в структурных скобках носят
общее имя термов.
4. Если E — выражение, A — описанный в программе атом, AE,
заключенное в функциональные скобки, является выражением
(называемым функциональным выражением ). A называется
детерминативом этого выражения.
В конкретном синтаксисе Рефала функциональные скобки обозначаются
< >, структурные -- ( ). Атомы делятся на:
1. Символы (байты, простые символы).
2. Составные символы (имена, определенные в программе)
представлены идентификаторами, начинающимися с большой
буквы.
3. Целые числа без знака, меньшие 232, например, 123456789.
Стили и методы программированияНепейвода Н.Н.
66

4. Действительные числа, например, 123456789.E-5.
В поле памяти выделяется основная часть, а также стеки глобальных
данных - закопанные данные. Перед каждым шагом исполнения в
основной части поля памяти выделяется активная часть - поле зрения.
Данные в поле зрения и закопанные данные имеют общую структуру
1)
,
которая является подструктурой структуры поля памяти. Поскольку и
программа имеет практически ту же самую структуру
2)
, в ходе развития
языка появилась третья структура данных ( метаданные ), расширяющая
поле памяти.
Дадим точные определения.
Объектное выражение — выражение, не содержащее функциональных
скобок.
Минимальное функциональное выражение — выражение, имеющее
вид <E>, где E — объектное выражение.
поле памяти Рефал -машины представляет собой набор выражений,
одно из которых называется основной частью . В основной части в
любой момент, за исключением момента выдачи окончательного
результата и остановки программы, есть функциональные скобки.
Поле зрения (активная часть) поле памяти — первое из встречающихся
в основной части поля памяти минимальных функциональных
выражений.
Детерминатив — первый символ в функциональной скобке.
Детерминатив интерпретируется как имя функции, обрабатывающей
содержимое функциональных скобок. Эта функция должна определяться
статически, поэтому в ходе вычислений не могут образовываться
выражения вида < <e.1> e.2>. В подавляющем большинстве
случаев детерминатив должен быть именем, но некоторые обычные
символы, например +, также могут использоваться в качестве
детерминативов.
Пример 5.2.3. Рассмотрим пример памяти Рефал -машины в ходе
Стили и методы программированияНепейвода Н.Н.
67

вычислений.
Поле памяти:
'aaxzACDE' <Sort < Perm 'G'1.5E5 > <Perm 115 'F'> <Perm
112 -2.0E-5>><Sort AllRight Sort Perm
'QRTS'>'XZ<(')
Поле зрения выделено в поле памяти жирным шрифтом. Заметим, что в
поле памяти можно выделить данные, обработка которых уже
завершена и которые не изменятся до конца исполнения программы (те,
которые находятся вне программных скобок; в нашем случае
'aaxzACDE' и 'XZ<('). У символов, представляющих скобки, есть
'обычные' двойники, не обязательно имеющие парные и не влияющие
на структурирование выражения. Первый атом Perm стоит в позиции
функции, а последний из атомов Perm стоит в позиции данных, так что
имена функций могут формироваться
3)
динамически. При записи
программы пробелы, если они не находятся внутри символьных
констант, игнорируются, за исключением тех, которые отделяют один
символ от другого (эти пробелы просто опускаются после того, как на
этапе лексического анализа сыграли роль разделителей). И, наконец,
еще одна тонкость. 123 — это один атом, '123' — три атома,
-123.0 — опять один атом, -123 — два атома: символ '-', после
которого стоит число.
Кроме основной части поля памяти, в ходе исполнения может
появиться несколько стеков закопанных выражений, например:
Stack1 '=' 15 Stack2 '=' Perm B A
21 Perm C2 C1
-45 Perm 'X' 20
60
В принципе, несколько стеков — избыточная конструкция. Но,
поскольку здесь стеки рассматриваются как общие области памяти,
лучше в каждом модуле иметь свой стек. К сожалению, явной связи
между стеками и модулями в Рефал -программах нет.
Допустим, есть строка < AB(CD)(E)F>. Она во всех известных нам
Стили и методы программированияНепейвода Н.Н.
68

Рефал -системах представляется двунаправленным списком,
изображенным на рис. 5.1
. Этот формат представления стал
общераспространенным для Рефал -систем, начиная с реализации,
описанной в [25]
. Однако он не является обязательным.
Рис. 5.1. Реализация структуры данных Рефала
При реализации языка Рефал В. Ф. Турчин задумался, как избежать
слишком частых обращений к каким-то суррогатам возможностей
традиционных языков. Он решил заранее описать алгоритм
преобразования выражений и подобрать для него подходящую структуру
данных. Описанный им алгоритм хорошо работает с целым классом
случаев, включая те, которые заранее не предусматривались, —
отличительный признак концептуально продуманного решения. В
лекции, относящийся к языку PROLOG можно увидеть, что происходит,
если структуру данных хорошо не продумать на ранних этапах, а тем
более зафиксировать случайные промежуточные результаты как
стандарт.
Более того, описанные Турчиным алгоритм и структуры данных
являются отличной базой для точного определения семантики на базе
абстрактного синтаксиса языка Рефал.
Преобразование выражений в формат для обработки делается один раз,
при вводе информации либо при трансляции программы.
Рассмотрим конкретный синтаксис выражений.
Идентификатор — любая последовательность цифр и букв,
начинающаяся с большой буквы. Идентификатор является символьным
литералом и представляет составной символ. Символы, заключенные в
одинарные ' ' кавычки, являются символьными литералами,
представляют сами себя. Дважды повторенная кавычка представляет
Стили и методы программированияНепейвода Н.Н.
69

кавычку. Двойные кавычки " " используются для ограничения имени
составного символа, не обязательно являющегося идентификатором
4)
.
Если вне кавычек встречается символ, не являющийся скобкой, частью
идентификатора или числа, это трактуется как ошибка.
Определение метавыражения Рефала получается из определения
выражения добавлением еще одного базисного случая: переменная
является метавыражением.Переменные не могут быть
детерминативами.
Метавыражение называется образцом, если оно не содержит
функциональных скобок.
В конкретном синтаксисе обозначение переменной включает тип и
символ переменной, записываемые как тип.атом. В стандартном
Рефале имеются переменные трех типов: символьные ( s.First ),
термовые ( t.Inner ) и общие ( e.Last ).
Значением символьной переменной служит атом, термовой — терм
(символ или выражение в скобках), общей — произвольное (может
быть, пустое) объектное выражение.
Рефал развивался как язык символьных преобразований в самом
широком смысле этого слова, и поэтому в него была заложена
возможность обрабатывать собственные программы. Он предоставляет
стандартные функции метакодирования, взаимно-однозначно и
взаимнообратно преобразующие произвольное метавыражение в
объектное и наоборот. Таким образом, появляется возможность
создавать программы в ходе выполнения других программ и затем
выполнять их "на лету". Такая возможность, просто гибельная для
программ в большинстве систем и стилей программирования, в данном
случае не приводит ни к каким отрицательным последствиям из-за
уникального концептуального единства и продуманности языка
5)
.
Модель вычислений и Рефал-программа
Основные два шага в Рефал -вычислениях — конкретизация
переменных в образце в соответствии с областью зрения и подстановка
Стили и методы программированияНепейвода Н.Н.
70
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
