Главная:
Рефераты
Главная
Финансы деньги и налоги
Философия
Физика и энергетика
Управление
Схемотехника
Стратегический менеджмент
Статистика
Соцобеспечение
Семейное право
Программирование компьютеры и кибернетика
Охрана окружающей среды экология
Основы права
Медицина
Криминалистика и криминология
Коммуникации и связь
Кибернетика
Качество упр-е качеством
КСЕ
Информатика ВТ телекоммуникации
Журналистика
Государство и право
Биографии
Банковское дело
Карта сайта
Рефераты. Интерактивный интерпретатор
#вычисляет угол треугольника со сторонами
#
a
,
b
и
c
между сторонами
a
и
b
(в градусах)
if
~isnum[a]|~isnum[b]|~isnum[c]
println
"Invalid arguments"
error
endif
if
(a<=0)|(b<=0)|(c<=0)
println
"Not a triangle"
error
endif
cos_alpha:=(a*a+b*b-c*c)/(2*a*b)
if
(cos_alpha>=1)|(cos_alpha<=-1)
println
"Not a triangle"
error
endif
alpha:=arccos[cos_alpha]
result
:=alpha*180/pi[]
Проектирование и реализация программы-интерпретатора
Для реализации интерпретатора было решено использовать платформу Microsoft .NET v.1.1 и язык программирования C#. Это связано с тем, что платформа .NET обеспечивает достаточно высокую производительность (быстродействие) приложений при значительном увеличении скорости разработки. Последнее обеспечивается за счет наличия удобных визуальных средств разработки, обширной и мощной стандартной библиотеки классов, использования автоматической сборки мусора, когда память из-под более неиспользуемых объектов освобождается автоматически. Язык C# же является основным языком платформы .NET, позволяющим полностью использовать все преимущества технологии Microsoft .NET, он имеет весьма гибкий синтаксис, позволяющий реализовывать достаточно сложные алгоритмы сравнительно небольшими, но легко читаемыми фрагментами кода.
В программе можно выделить две основные группы классов, две подсистемы, ответственные за логику работы интерпретатора и графический интерфейс пользователя соответственно. Поскольку первая подсистема содержит значительно большее число классов, чем вторая, было решено расположить ее в отдельном пространстве имен logic, вложенном в корневое пространство имен проекта. Классы, ответственные за графический интерфейс пользователя, расположены непосредственно в корневом пространстве имен проекта. Кроме того, в пространстве имен logic имеется два вложенных пространства имен - operators и vartypes, соответствующие двум основным иерархиям наследования в проекте - операторам программы и типам данных. Корневое пространство имен имеет имя interpr. Диаграмма пакетов проекта изображена на рис. 1.
Роль посредника между пользовательским интерфейсом и подсистемой, реализующей логику работы интерпретатора, выполняет класс Facade (фасад). Он также ответственен за создание отдельного потока для выполнения команд пользователя (вводимых с консоли). Выполнять их в том же потоке, что и обрабатывать сообщения пользовательского интерфейса нельзя так как в этом случае зациклившуюся пользовательскую функцию будет невозможно прервать. Многие методы класса Facade сводятся к простому вызову методов других классов из пространства имен logic. Этот класс в дальнейшем будет рассмотрен более подробно.
Для обработки ошибок применяется механизм структурной обработки исключений. При этом используются следующие классы пользовательских исключений (для ошибок в классах пространства имен interpr.logic):
· CalcException - ошибка по вине пользователя (синтаксическая или в вычислениях);
· SyntaxErrorException - синтаксическая ошибка, обнаруживаемая во время «компиляции», т. е. при загрузки функции или преобразования введенной команды во внутренний формат. Унаследован от CalcException;
· LineSyntaxException - синтаксическая ошибка в конкретном операторе функции. Содержит информацию об месте обнаружения (имя функции, строка).
· OtherException - ошибки, связанные с некорректной работой интерпретатора не по вине пользователя. Класс используется для отладочных целей. При нормальной работе такое исключение никогда не должно генерироваться.
· LinkedListException - ошибка в методах класса LinkedList. Унаследован от класса OtherException.
· NamespaceSerializationException - унаследован непосредственно от System.Exception. Такое исключение - генерируется если пространство имен консоли не может быть успешно восстановлено.
Соответствующая диаграмма классов изображена на рис. 2.
Можно выделить несколько групп классов в пространстве имен interpr.logic - классы, ответственные за вычисление выражений, за выполнение пользовательских функций, за преобразование текста команд и пользовательских функций во внутренний формат («компиляцию» текста программы), классы, участвующие в организации интерактивной работы интерпретатора. Эти группы классов, равно как и подсистема графического интерфейса пользователя, будут рассмотрены ниже. В пространстве имен interpr.logic также имеется один класс вспомогательного назначения - LinkedList. Он представляет двухсвязный список. В нем имеются методы и свойства добавления и чтения элементов в начале и конце списка, определения числа элементов списка. При этом, при попытке чтения из пустого списка, генерируется исключениеLinkedListException. Метод GetIterator(), существующий в двух перегруженных версиях (для первого элемента списка и для заданного индекса), возвращает объект вложенного класса LinkedList.Iterator, который представляет собой итератор, позволяющий читать элементы списка, перемещаясь по нему от начала к концу, а также двигаться в обратном направлении. Элемент списка представляется объектом частного вложенного класса Link, содержащего три поля с видимостью internal - одно для хранения значения элемента списка и два для ссылок на предыдущий и следующий элементы.
Следует также отметить интерфейс interpr.logic.IConsole, представляющий нечто, что может быть использовано для вывода текста. Он имеет два метода - void Print(string str) и void PrintLn(string str), назначение которых понятно из названия.
Основные классы пространства имен interpr.logic показаны на диаграмме на рис. 3.
Рис. 3.
Классы пространства имен
interpr
.
logic
.
Внутреннее представление и выполнение программы.
Большинство операторов реализованного языка программирования содержат выражения. Выражение представляет собой совокупность операндов и операций над ними, которая может быть вычислена, то есть на основании которой можно получить некоторое значение-результат. В языке программирования выражения представляются построенными по определенным требованиям строками. При обработке текста программы (этот процесс будет рассмотрен в следующем параграфе) строковое представление выражений переводится в представление внутреннее. В данном интерпретаторе внутреннее представление выражений использует так называемую обратную польскую запись (ОПЗ). Рассмотрим ОПЗ подробнее.
Обычная математическая запись арифметических выражений представляет собой так называемую инфиксную запись, в которой знаки операций располагаются между операндами. При этом для уточнения порядка вычисления операций используются приоритеты операций и круглые скобки. Такая форма записи удобна для человека, но неудобна для ЭВМ. Поэтому часто используют так называемую постфиксную или обратную польскую запись. В этом случае знак операции записываются после всех ее операндов, а вычисление производится по довольно простому алгоритму: выражение в ОПЗ последовательно просматриваем слева направо. Если встречаем операнд, то заносим его в стек, если же встречаем операцию, то выбираем ее операнды из стека, выполняем операцию и заносим результат в стек. В начале вычисления выражения стек пуст. Если выражение записано корректно, то при выполнении каждой операции число элементов стека будет не меньше числа ее операндов, и в конце процесса в стеке останется ровно одно значение - результат вычисления выражения. Особенностью ОПЗ является отсутствие необходимости в использовании скобок.
Например, выражение a+(b*c-d)/e в ОПЗ имеет вид abc*d-e/+. Применим к нему описанный выше алгоритм вычисления.
1. Заносим в стек a.
2. Заносим в стек b.
3. Заносим в стек c.
Состояние стека на этот момент: a, b, c - вершина.
4. Извлекаем из стека операнды операции умножения - b и c и заносим в стек результат.
Стек: a, b*c.
5. Заносим в стек d.
Стек: a, b*c, d.
6. Извлекаем из стека операнды, производим вычитание, заносим в стек результат.
Стек: a, b*c-d.
7. Заносим в стек e.
Стек: a, b*c-d, e.
8. Извлекаем из стека операнды, производим деление, заносим в стек результат.
Стек: a, (b*c-d)/e.
9. Извлекаем из стека операнды, производим сложение, заносим в стек результат.
Итого получаем в стеке a+(b*c-d)/e, что и требовалось.
Для представления выражений в интерпретаторе используется класс Expression. Он содержит обратную польскую запись выражения в виде связанного списка (однонаправленного). Звено этого списка, равно как и стека, используемого при вычислении выражения, представляется объектом вложенного класса Expression.Element, содержащим ссылки на следующее звено и на объект, реализующий интерфейс IComputable, который содержит один метод logic.vartypes.VarBase Compute() - получить значение. Вычисление значения выражения по рассмотренном выше алгоритму производится в методе VarBase Expression.Calculate(). Строка, содержащая запись выражения, обрабатывается в конструкторе этого класса. Интерфейс IComputable реализован тремя классами:
· VarBase - абстрактный класс, представляющий значение любого типа данных;
· VarName - представляет переменную по ее имени;
· Call - представляет вызов операции либо функции.
Вначале рассмотрим классы, представляющие значения различных типов. Все они являются потомками только что названного класса VarBase. Как было сказано выше, в языке существует четыре типа данных - целое число, вещественное число, строка и массив. При этом числовые и строковый типы, в противоположность массиву, называются простыми типами. Для простых значений базовым является абстрактный класс SingleVar. Целый и вещественный типы также особо выделяются как числовые, и для них существует свой базовый абстрактный класс NumVar. Наконец, каждому из четырех типов данных соответствует свой конкретный класс - IntVar, RealVar, StringVar и ArrayVar. Эта иерархия классов находится в пространстве имен interpr.logic.vartypes. Она изображена на диаграмме на рис. 4.
Страницы:
1
,
2
,
3
, 4,
5
,
6
,
7
,
8
,
9
,
10
,
11
,
12
,
13
,
14
,
15
,
16
,
17
Апрель (48)
Март (20)
Февраль (988)
Январь (720)
Январь (21)
2012 © Все права защищены
При использовании материалов активная
ссылка на источник
обязательна.