Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Diploma_All

.pdf
Скачиваний:
20
Добавлен:
05.06.2015
Размер:
1.37 Mб
Скачать

Важно, что объект «глиф» содержит определение метода Draw(Graphics g), командующий глифу нарисовать себя. Таким образом реализуется принцип инкапсуляции — объект сам «знает», как рисовать себя; классам, использующим глиф, нет необходимости заново указывать ему, как это делать. Единственное, что требуется от таких классов — передать методу Draw() в

качестве параметра объект типа System.Drawing.Graphics, представляющий собой «поверхность» рисования GDI+. В частности — это поверхность основной панели для рисования, определенной в главной форме приложения.

Поэтому для того, чтобы нарисовать все объекты, достаточно у каждого из них вызвать метод Draw():

public void Render(Graphics g)

{

foreach (DrawnObject dObj in DrawnObjects)

{

dObj.Draw(g);

}

}

На рисунке 2.9, показано, как выглядит иерархия блоков элементов в геометрическом представлении для того же случая, что и на рисунке 2.8.

Рисунок 2.9. Геометрическое представление блоков иерархии

31

Текстовое представление

Завершающим этапом редактирования параметров элементов является создание выходного файла в формате SPICE. За вывод SPICE-элементов в текстовом виде отвечает функция PrintHierarchy():

public string PrintHierarchy()

{

SpiceElement[] spiceElements = GetSpiceElements(); StringBuilder output = new StringBuilder();

foreach (SpiceElement element in spiceElements)

{

output.AppendLine(element.ToString());

}

return output.ToString();

}

Также как и в случае с отображением глифов, каждый объект типа SpiceElement умеет отображать себя в текстовом виде путем переопределения стандартной функции ToString(). Каждый такой объект отображает себя в синтаксически (SPICE) правильной форме.

Текстовое представление иерархии можно посмотреть на вкладке «Text» в основном окне приложения.

На рисунке 2.10 представлен снимок экрана, иллюстрирующий представление иерархии элементов в текстовом виде — в формате SPICE.

Рисунок 2.10. Текстовое представление иерархии

По нажатию кнопки «Save» в меню «File» иерархия в текстовом виде экспортируется в файл на жестком диске, указанный пользователем. Таким образом, текстовое представление на вкладке «Text» является своего рода «предпросмотром» данных, выводимых в файл.

32

2.3.4 Редактирование параметров элементов

Редактирование параметров осуществляется посредством изменения модели. Поскольку каждый глиф и узел объекта TreeView содержат информацию о соответствующем им узле в модели, то редактирование параметров легко осуществимо. Для того, чтобы получить доступ к окну редактирования параметров нужно нажать правой кнопкой мыши на на блоке в геометрическом представлении или узле в объекте TreeView. Откроется контекстное меню с пунктом «Edit parameters...», нажав на который появится диалог редактирования параметров.

Рисунок 2.11. Диалоговое окно редактирования параметров элемента

Встроке заголовка отображается имя текущего редактируемого элемента, ниже выводится имя модели, которая используется элементом. Под именем модели следуют текстовые поля в которых отображаются текущие значения соответствующих параметров.

Внесенные изменения сохраняются по нажатию на кнопку «Save». Эти изменения вносятся в модель — исходную иерархию, на основании которой строятся представления (view). Изменения тут же можно увидеть в текстовом представлении редактируемых элементов.

Внастоящей работе была продемонстрирована возможность редактирования двух наиболее часто изменяемых при верификации топологии параметров МОП-транзисторов: длины l и ширины w канала. Однако в промышленном варианте программы возможно редактирование целого набора параметров в зависимости от используемой модели. Возможно использование базы данных моделей,

вкоторой будут содержаться имена и возможные значения их параметров. В общем виде возможно редактирование любого количества параметров — всех

33

найденных для данного элемента в исходном плоском файле нетлиста. Это достижимо динамическим созданием элементов управления в зависимости от количества найденных параметров.

Вводимые значения проверяются на корректность механизмом регулярных выражений и при неправильном формате изменяемого значения параметра, интерфейс пользователя не позволяет сохранять подобные изменения. Регулярные выражения были сконструированы на основе тех, что использовались при лексическом анализе входного файла, описанном в разделе «Лексический анализ».

2 . 4 Анализ входного файла

2.4.1 Постановка задачи

Разработанный программный продукт ориентирован на работу с плоским нетлистом в формате SPICE в качестве входного файла. По ТЗ программа должна уметь анализировать входной файл и получать информацию о содержащихся в нем SPICE-элементов. Программа должна уметь распознавать разные типы элементов, однако для демонстрации возможностей мы ограничились транзисторами, резисторами и конденсаторами.

Ниже приведен типичный пример определения SPICE-элемента в плоском нетлисте, сгенерированном программой верификации топологии:

m_I1|I127|I3|I2|MmM1 I1|I127|I3|N_3 I1|I127|I3|N_1

+vdd vdd p l=0.18u w=0.9u ad=0.24525p as=0.544828p

+pd=1.445u ps=2.71416u

Задача программы при анализе такого входного файла заключается в распознавании такой строчки как определения SPICE-элемента типа «МОП-транзи- стор» и конвертирования такого текстового представления в объектно-ориенти- рованное, другими словами, в объект типа SpiceElement.

2.4.2 Теория компиляторов

При компиляции анализ состоит из трех фаз:

1.линейный анализ, при котором поток символов исходной программы считывается слева направо и группируется в токены (token), пред-

34

ставляющие собой последовательности символов с определенным совокупным значением.

2.иерархический анализ, при котором символы или токены иерархически группируются во вложенные конструкции с совокупным значением;

3.семантический анализ, позволяющий проверить, насколько корректно совместное размещение компонентов программы.

Вкомпиляторах линейный анализ называется лексическим, или сканированием, а программы его осуществляющий — лексическими анализаторами или

сканерами.

Иерархический анализ называется разбором (parsing), или синтаксическим анализом, который включает группирование токенов исходной программы в грамматические фразы, используемые компилятором для синтеза вывода. Обычно грамматические фразы исходной программы представляются в виде дерева.

Впроцессе семантического анализа проверяется наличие семантических ошибок в исходной программе и накапливается информация о типах для следующей стадии — генерации кода. При семантическом анализе используются иерархические структуры, полученные во время синтаксического анализа для идентификации операторов и операндов выражений и инструкций.

Разделение анализа на лексический и синтаксический достаточно произвольно. Обычно оно используется для упрощения анализа в целом.

Вцелом процесс анализа входного текстового файла по строкам выглядит как показано на рисунке 2.12:

35

Входная строка

Парсер

Лексический анализ

(выделение токенов)

Токены

Синтаксический анализ

(создание дерева разбора)

Дерево разбора

Компилятор/ интерпретатор

Вывод

Рисунок 2.12: Процесс анализа строки входного файла

2.4.3 Выбор инструментальных средств для решения задачи анализа входного файла

Для решения поставленной задачи требуется создать синтаксический анализатор файлов в формате SPICE (парсер).

Надо заметить, что создание собственного парсера с нуля нетривиальна и требует специальных знаний в области теории компиляторов. Намного практичнее будет использовать специальные инструменты, облегчающие их создание.

Такие системы получили названия компиляторов компиляторов, генераторов компиляторов или систем написания трансляторов, которые по файлу, задаю-

щему спецификацию языка генерируют код на одном из объектно-ориентирован- ных языков, таких как C++, C#, Java, который будет способен производить син-

36

таксический анализ входного файла на заданном языке и иметь дружественный для программиста интерфейс.

Типичный генератор компиляторов состоит из нескольких компонентов, которые могут использоваться отдельно:

1.Генераторы синтаксических анализаторов. Эти генераторы произво-

дят синтаксические анализаторы, обычно по входной информации, основанной на контекстно-свободной грамматике. В первых компиляторах синтаксический анализ был весьма неэффективен и трудоемок. В настоящее время эта фаза является одной из простейших при реализации. Многие генераторы синтаксических анализаторов используют мощные алгоритмы разбора, которые слишком сложны для ручной реализации.

2.Генераторы сканеров. Этот инструментарий автоматически генерирует лексические анализаторы, как правило, с использованием спецификаций, построенных на регулярных выражениях. В основном, лексические анализаторы действуют по принципу конечного автомата.

3.Средства синтаксически управляемой трансляции. С помощью дан-

ного инструментария создаются наборы программ прохода по дереву разбора и генерации промежуточного кода. Основная идея состоит в одной или нескольких «трансляциях», связанных с каждым узлом дерева разбора; при этом каждая трансляция определяется с учетом соседних узлов дерева.

4.Автоматические генераторы кода. Эти инструменты получают на-

бор правил, которые указывают способ трансляции каждой операции промежуточного языка в определенный машинный язык.

5.Средства работы с потоком данных. Для получения оптимизирован-

ного выходного кода требуется проведение серьезного анализа потока

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

Бурное развитие таких инструментов пришлось еще на начало 1970-х годов и выделило несколько хорошо зарекомендовавших себя и проверенных временем программ, к которым относятся генератор лексических анализаторов LEX и гене-

37

ратор синтаксических анализаторов YACC («Yet another compiler-compiler» —

еще один компилятор компиляторов), который доступен в UNIX и использовался при разработке сотен компиляторов и широко распространен.

Поскольку настоящая работа была выполнена на платформе .NET 2.0, то целесообразно было найти аналоги этих генераторов, генерирующих код на языке C# 2.0. И такие инструменты были найдены — это LEX-подобный генератор сканеров GPLEX (Gardens Point LEX) и YACC-подобный генератор синтаксических анализаторов GPPG (Gardens Point Parser Generator).

Термины «LEX/YACC-подобный» подразумевают использование программами тех же спецификаций языка (с добавлением своих особенностей), что и LEX/YACC, а также заимствование у них эффективных алгоритмов.

Особенности устройства и взаимодействия этих программ, а также использованные ими алгоритмы будут рассмотрены в технологическом разделе пояснительной записки. Сейчас же ограничимся описанием того, как с помощью этих инструментов была решена задача анализа входного файла на языке SPICE.

2.4.4 Лексический анализ

Программа GPLEX принимает на входе файл со спецификацией языка, построенной на регулярных выражениях и на выходе производит файл с кодом на языке C#, содержащем определение классов для сканирования входного потока.

Файл спецификации GPLEX как и для LEX состоит из трех разделов:

Объявления

%%

Правила трансляции

%%

Вспомогательные процедуры

Раздел объявлений включает объявления переменных, именованные константы (идентификаторы, используемые для представления констант), объявления используемых пространств имен, специальные объявления опций (параметров) программы и регулярные определения. Регулярные определения используются в качестве компонентов регулярных выражений в правилах трансляции.

Регулярные определения имеют стандартную нотацию, определенную в международном стандарте ISO/IEC 9945-2:2003 [6].

38

Регулярное выражение строится из более простых регулярных выражений с использованием набора правил. Для удобства записи регулярным выражениям можно давать имена и определять регулярные выражения с использованием этих имен так, как если бы это были символы.

Например,

digits [0-9]+

определяет регулярное выражение digits как последовательность одного или более символа из класса символов от «0» до «9».

Правила трансляции Lex-программы являются инструкциями типа

p1 { action1 } p2 { action2 }

. . .

pn { actionn }

где каждое p, — регулярное выражение, а actioni — фрагмент кода, описывающий выполняемые лексическим анализатором действия, если лексема соответствует шаблону pi. В GPLEX действия записываются с использованием языка программирования C#.

Третий раздел содержит различные вспомогательные процедуры, которые могут быть скомпилированы отдельно и загружены вместе с лексическим анализатором.

Ниже приведен текст входного файла GPLEX со спецификацией SPICE (МОП-транзистор), построенной на регулярных выражениях.

%namespace LexScanner %option verbose, summary

alpha [a-zA-Z] digit [0-9] alnum [a-zA-Z0-9] space [ \t] spaces {space}+

natural [1-9]{1}|[1-9]{1}{digit}+ uInteger {natural}|0

integer -?{uInteger}

float -?{uInteger}*\.{digit}+|{integer} namePrefix [CMRcmr]

nameSuffix [a-zA-Z0-9_\|]+

name {namePrefix}{1}{nameSuffix} modelName {spaces}{alpha}{nameSuffix}?

39

scale [fpnumckgtFPNUMCKGT]|meg|mil|MEG|MIL node {uInteger}|{alpha}|{alpha}{1}{nameSuffix} mnodes ({spaces}{node}){3,4}

pValue {float}{scale}? parameter {alpha}+={pValue} params ({spaces}{parameter})* rValue {float}{scale}?

%%

yylval = yytext; return (int)Tokens.NAME;

{name}

{mnodes}

yylval = yytext; return (int)Tokens.M_NODES;

{modelName}

yylval = yytext; return (int)Tokens.MODEL_NAME;

{params}

yylval = yytext; return (int)Tokens.PARAMS;

%%

 

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

resistor [Rr]{1}{nameSuffix}{spaces}{node}{spaces} {node}({spaces}{modelName})?{spaces}{rValue} ({spaces}TC({spaces})?=({spaces})?{float}(,({spaces})? {float})?)?

Однако при совпадении такой последовательности, сканер вернет нам ее целиком как строку в то время как нам нужны значения составляющих ее токенов — имя, узлы, имя модели и параметры.

Поэтому в секции правил трансляции при соответствующем совпадении возвращаются отдельно эти токены, которые будут передаваться синтаксическому анализатору для дальнейшей обработки — проверки допустимости следования одного токена за другим. Заметим, забегая вперед, что GPLEX ориентирован на работу с GPPG, поэтому имена токенов берутся из перечисления, генерируе-

мого GPPG.

Запустив GPLEX командой

gplex.exe /out:Scanner.cs pspice_grammar.lex,

где Scanner.cs — имя файла, куда записывается сгенерированный код, а pspice_grammar.lex – имя файла со спецификацией языка, получим набор классов, позволяющих осуществить лексический анализ входного файла. Из всех классов нас больше всего интересует класс Scanner, который будет передан классу Parser (сгенерированного уже GPPG) в качестве свойства.

40

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]