|
||||
Меню:
Главная
Форум
Литература: Программирование и ремонт Импульсные блоки питания Неисправности и замена Радиоэлектронная аппаратура Микросхема в ТА Рубрикатор ТА Кабельные линии Обмотки и изоляция Радиоаппаратура Гибкие диски часть 2 часть 3 часть 4 часть 5 Ремонт компьютера часть 2 Аналитика: Монтаж Справочник Электроника Мощные высокочастотные транзисторы 200 микросхем Полупроводники ч.1 Часть 2 Алгоритмические проблемы 500 микросхем 500 микросхем Сортировка и поиск Монады Передача сигнала Электроника Прием сигнала Телевидиние Проектирование Эвм Оптимизация Автомобильная электроника Поляковтрансиверы Форт Тензодатчик Силовые полевые транзисторы Распределение частот Резисторные и термопарные Оберон Открытые системы шифрования Удк |
[25] Ключевая идея состоит в том, чтобы никогда не записывать ссылки на структуры явно, а вместо этого организовывать программу в виде набора функторов, каждый из которых получает в качестве аргумента структуры, от которых он зависит (или ничего, если функтор ни от чего не зависит). После этого редактирование связей будет состоять в применении функторов. В нашем случае функторы могут выглядеть следующим образом: functor SymbolFunO : SYMBOL = struct datatype symbol = symbol of string * ... fun mksymbol(s) = symbol(s,...) fun eqsymbol(syml,sym2) = ... end; functor AbstSyntaxFun( Symbol: SYMBOL ): ABSTSYNTAX = struct structure Symbol: SYMBOL = Symbol datatype term =... fun idname(term) = ... end; functor SymbolTableFun( Symbol : SYMBOL ): SYMBOLTABLE = struct structure Symbol: SYMBOL = Symbol type entry = ... type table = ... fun mktable() = ... fun lookup(sym,table) = ... end; signature PARSER PIECES = sig structure SymbolTable : SYMBOLTABLE structure AbstSyntax : ABSTSYNTAX end; functor ParserFun( Pieces : PARSER PIECES ): PARSER = struct structure AbstSyntax : ABSTSYNTAX = Pieces.AbstSyntax structure SymbolTable : SYMBOLTALBLE = Pieces.SymbolTable val symtable = SymbolTable.mktable(); fun parse(str) = ... SymbolTable.lookup( AbstSyntax.idname(t), symtable )... end; Сигнатура PARSER PIECES содержит две компоненты, от которых зависит синтаксический анализатор, - таблицу символов и дерево синтаксического разбора. Функтор ParserFun использует эту пару для построения синтаксического анализатора. Функтор SymbolFun не имеет аргументов, поскольку он не зависит ни от чего. Программа строится из этих функторов с помощью следующей последовательности объявлений. Убедитесь, что результат будет тем же, что и ранее. structure Symbol: SYMBOL = SymbolFunO; structure Pieces: PARCER PIECES = struct structure SymbolTable: SYMBOLTABLE = SymbolTableFun(Symbol) structure AbstSyntax: ABSTSYNTAX = AbstSyntaxFun(Symbol) end; structure Parser: PARSER = ParserFun( Pieces ); Однако мы умолчали о проблеме с ParserFun. Напомним, что функция parse, определенная в Parser, является корректной с точки зрения согласованности типов только потому, что структуры SymbolTable и AbstSyntax включают одну и ту же подструктуру Symbol, и благодаря этому используют один и тот же тип символов. Но теперь в ParserFun функция parse знает только сигнатуры этих двух структур, и ничего не знает о том, как они реализованы. Поэтому ML-компилятор укажет на ошибку в ParserFun, - и наша идея использования функторов для обеспечения модульного стиля программирования оказывается под угрозой. Спасти дело помогают спецификации соиспользования. Идея состоит в том, чтобы включить в сигнатуру PARSER PIECES набор равенств, гарантирующих тот факт, что только пара совместимых вариантов структур (для работы с таблицей символов и для работы с деревом синтаксического разбора) может быть передана функтору ParserFun. Новый вариант сигнатуры PARSER PIECES будет выглядеть следующим образом: signature PARSER PIECES = sig structure SymboiTable : SYMBOLTABLE structure AbstSyntax: ABSTSYNTAX sharing SymbolTable.Symbol = AbstSyntax.Symbol end; Фраза sharing гарантирует то, что может быть использована только совместимая пара структур SymboiTable и AbstSyntax (где "совместимая" означает "использующая одну и ту же структуру Symbol"). Если теперь мы используем эту модифицированную сигнатуру, то объявление функтора ParserFun становится допустимым. В общем случае имеется две формы спецификации соиспользования - одна для типов, а другая для структур. В последнем примере мы использовали форму для структур - и обеспечили с помощью нее то, что обе компоненты параметра используют равные подструктуры. Две структуры равны тогда и только тогда, когда они получены в результате вычисления одного того же объявления структуры или применения одного и того же функтора к равным аргументам. Например, следующая попытка сформировать аргументы для функтора ParserFun будет отвергнута, поскольку она не удовлетворяет спецификации sharing: structure Pieces : PARSER PIECES = struct structure SymboiTable = SymbolTableFun( SymbolFunO ) structure AbstSyntax = AbstSyntaxFun( SymbolFunO ) end; Причина здесь в том, что каждое применение SymbolFun создает новую структуру, отличную от всех других. Другая форма спецификации соиспользования имеет дело с типами. Например, следующая версия PARSER PIECES будет вполне подходящей, если единственное, в чем должны совпадать структуры SymboiTable и AbstSyntax - это используемый ими тип symbol: signature PARSER PIECES = sig structure SymboiTable : SYMBOLTABLE structure AbstSyntax : ABSTSYNTAX sharing SymboiTable.Symbol.symbol=AbstSyntax.Symbol.symbol end; Равенство типов подобно равенству структур: два типа равны, если они получены в результате вычисления одного и того же объявления. Так, например, если два типа заданы идентичными объявлениями datatype, они будут различными. Возвращаясь к нашему примеру, посмотрим, что произойдет, если мы нашли и исправили ошибку в функторе SymbolFun. Что мы должны сделать после этого? Во-первых, конечно, необходимо перекомпилировать SymbolFun. А затем достаточно повторить приведенную выше последовательность применений функторов - но повторной компиляции всех других функторов не требуется. |
Среды: Smalltalk80 MicroCap Local bus Bios Pci 12С ML Микроконтроллеры: Atmel Intel Holtek AVR MSP430 Microchip Книги: Емкостный датчик 500 схем для радиолюбителей часть 2 (4) Структура компьютерных программ Автоматическая коммутация Кондиционирование и вентиляция Ошибки при монтаже Схемы звуковоспроизведения Дроссели для питания Блоки питания Детекторы перемещения Теория электропривода Адаптивное управление Измерение параметров Печатная плата pcad pcb Физика цвета Управлении софтверными проектами Математический аппарат Битовые строки Микроконтроллер nios Команды управления выполнением программы Перехода от ahdl к vhdl Холодный спай Усилители hi-fi Электронные часы Сердечники из распылённого железа Анализ алгоритмов 8-разрядные КМОП Классификация МПК История Устройства автоматики Системы и сети Частотность Справочник микросхем Вторичного электропитания Типы видеомониторов Радиобиблиотека Электронные системы Бесконтекстный язык Управление техническими системами Монтаж печатных плат Работа с коммуникациями Создание библиотечного компонента Нейрокомпьютерная техника Parser Пи-регулятор ч.1 ПИ-регулятор ч.2 Обработка списков Интегральные схемы Шина ISAВ Шина PCI Прикладная криптография Нетематическое: Взрывной автогидролиз Нечеткая логика Бытовые установки (укр) Автоматизация проектирования Сбор и защита Дискретная математика Kb радиостанция Энергетика Ретро: Прием в автомобиле Управление шаговым двигателем Магнитная запись Ремонт микроволновки Дискретные системы часть 2 | ||