|
||||
Меню:
Главная
Форум
Литература: Программирование и ремонт Импульсные блоки питания Неисправности и замена Радиоэлектронная аппаратура Микросхема в ТА Рубрикатор ТА Кабельные линии Обмотки и изоляция Радиоаппаратура Гибкие диски часть 2 часть 3 часть 4 часть 5 Ремонт компьютера часть 2 Аналитика: Монтаж Справочник Электроника Мощные высокочастотные транзисторы 200 микросхем Полупроводники ч.1 Часть 2 Алгоритмические проблемы 500 микросхем 500 микросхем Сортировка и поиск Монады Передача сигнала Электроника Прием сигнала Телевидиние Проектирование Эвм Оптимизация Автомобильная электроника Поляковтрансиверы Форт Тензодатчик Силовые полевые транзисторы Распределение частот Резисторные и термопарные Оберон Открытые системы шифрования Удк |
[24] val eq = op = fun f(x) = x >structure S = type t = int val eq = fn : int*int -> bool val f = fn : a -> a - structure S = I(S); >structure S = type t = int val eq = fn : int*int -> bool end Обратите внимание на то, что компонента f структуры S отсутствует в Упражнение 3.4.1 Преобразуйте вашу реализацию множеств на основе упорядоченных списков в форму, в которой функции равенства и порядка передаются в качестве аргументов функтору, строящему структуру для работы с множествами. Этим завершается наше введение в модульную систему ML. Нам осталось обсудить одну важную идею - соиспользование. Это мы обсудим несколько позже, после того, как рассмотрим примеры использования модулей в программировании. 3.5 Модульная система в реальной практике В этом разделе мы проиллюстрируем возможности использования модульной системы для построения программ. Мы рассмотрим (в общих чертах) разработку синтаксического анализатора, преобразующего входную строку в абстрактное дерево синтаксического разбора и заносящего некоторую информацию о символах во входной строке в таблицу символов. Программа будет состоять из четырех модулей: один будет содержать собственно синтаксический анализатор, второй - процедуры работы с деревом синтаксического разбора, третий - процедуры работы с таблицей символов и четвертый - сканер. Вот сигнатуры этих модулей: signature SYMBOL = sig type symbol val mksymbol : string -> symbol val eqsymbol : symbol*symbol -> bool end; signature ABSTSYNTAX = sig structure Symbol : SYMBOL type term val idname : term -> Symbol.symbol end; signature SYMBOLTABLE = sig structure Symbol : SYMBOL type entry type table val mktable : unit -> table val lookup : Symbol.symbol * table -> entry end; signature PARSER = sig structure AbstSyntax : ABSTSYNTAX structure SimbolTable : SYMBOLTABLE val symtable : Symboltable.table val parse : string -> AbstSyntax.term end; Разумеется, эти сигнатуры идеализированы и предельно сокращены, но все же они достаточно правдоподобны, чтобы служить в качестве убедительного и информативного примера. Обратите внимание на иерархическую организацию этих структур. Поскольку собственно синтаксический анализатор существенно использует функции работы и с деревом синтаксического разбора, и с таблицей символов, соответствующие структуры должны быть явно включены в него как подструктуры. Аналогично, и модуль работы с деревом синтаксического разбора, и модуль доступа к таблице символов используют сканер как подструктуру. Теперь давайте посмотрим, как на основе этого мы можем построить синтаксический анализатор. Отложив на время вопросы выбора алгоритма и представления, мы можем написать следующие структуры: structure Symbol: SYMBOL = struct datatype symbol = symbol of string * ... fun mksymbol(s) = symbol(s, ...) fun eqsymbol(syml,sym2) = ... end; structure AbstSyntax : ABSTSYNTAX = struct structure Symbol : SYMBOL = Symbol datatype term = ... fun idname(term) = ... end; structure SymbolTable : SYMBOLTABLE = struct structure Symbol: SYMBOL = Symbol type entry = ... type table = ... fun mktable() = ... fun lookup(sym, table) = ... end; structure Parser: PARSER = struct structure AbstSyntax : ABSTSYNTAX = AbstSyntax structure SymbolTable : SYMBOLTABLE = SymbolTable val symtable = SymbolTable.mktable(); fun parse(str) = ... SymbolTable.lookup(AbstSyntax.idname(t).symtable)... Обратите внимание на то, что в последней строке структуры Parser мы записали применение функции SymbolTable. lookup к результату функции AbstSyntax.idname. Это применение корректно с точки зрения согласования типов только благодаря тому, что структуры AbstSyntax и SymbolTable включают одну и ту же структуру Symbol. Если бы было две структуры, сопоставимые с сигнатурой SYMBOL, и одна из них была использована в структуре SymbolTable, а другая - в структуре AbstSyntax, в упомянутой строке возникла бы ошибка несоответствия типов. Имейте это в виду при чтении дальнейшего. Организация нашего синтаксического анализатора пока кажется вполне удовлетворительной - по крайней мере до тех пор, пока мы рассматриваем статическую структуру программы. Но если мы предположим, что имеются еще многочисленные структуры, и каждая из них содержит несколько тысяч строк кода, то тогда предложенная структура окажется не совсем удобной. Предположим, например, что мы нашли ошибку в структуре SymbolTable и исправили ее. Теперь нам нужно собрать синтаксический анализатор заново. Это потребует перекомпиляции всех приведенных выше структур (а также, возможно, и других связанных с ними). Ясно, что нужна какая-то возможность раздельной компиляции и последующего связывания скомпилированных модулей. То, что нам нужно - это возможность отдельно скомпилировать один модуль и затем связать модули в единую программу. Эта идея, разумеется, не нова; новым, однако, является то, как эта проблема решается в ML. |
Среды: 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 | ||