Рефераты. Реализация высокоуровнего интерфейса вокруг базы данных Berclee DB

 





4.Основные сведения по программной системе генерации языков программирования YAPP

 

YAPP представляет собой  программную систему с использованием Perl для генерации и использования синтаксических анализаторов LALR. Фактически это коллекция модулей расширения, написанных на Perl, совместимая с форматом YACC и позволяющих  генерировать perl-код.

Пользователь  формирует файл с грамматикой, описывающей некоторый желаемый язык. Этот файл подается на вход к yapp

yapp grammar_file.yp

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

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

  use MyParser;

  $parser=new MyParser();

  $value=$parser->YYParse(yylex => \&lexer_sub, yyerror => \&error_sub);

Файл грамматики

1)                Комментарии бывают в стиле Perl # или в стиле С // , /*  */.

2)                Признаки литералов и строк.

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

Синтаксис нетерминальных символов и  символьных лексем:

[A-Za-z][A-Za-z0-9_]*.

Запрещено использование название «error» для литералов.

Структура его выглядит следующим образом (очень похожа на yacc, фактически является ее подмножеством)

Файл состоит из трех секций, разделенных %%:

   заголовок

   %%

   секция правил

   %%

   нижняя секция

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

Она содержит также декларации приоритета, представленных  %left, %right и %nonassoc(определяющ. ассоциативность).

%start указывает на правило(левую часть), выполняющееся первым.

Секция правил содержит грамматические правила:

Каждое правило состоит из слева лежащего символа (нетерминального), разделенного ':' и одним или несколькими возможными правилами, разделенными '|' и завершенными ';':

    exp:    exp '+' exp

        |   exp '-' exp

        ;

Правило справа может быть пустым

    input:  #empty

        |   input line

        ;

Для задания явного приоритета в случае неоднозначности  следует использовать директиву %prec, дающую правилу высокий приоритет.

    exp:   '-' exp %prec NEG { -$_[1] }

        |  exp '+' exp       { $_[1] + $_[3] }

        |  NUM

        ;

Примечательно, что YAPP позволяет встраивать в синтаксический анализатор семантику. Это организуется путем добавления в конце правила конструкций {…}, ограничивающих Perl-команды. Они встраиваются в синтаксический анализатор и выполняются после применения анализатором этого правила. Такой код может возвращать некоторую величину, используемую в определении следующего правила по дереву.

Переменные $_[1] , $_[n] являются параметрами и хранят значения разобранного правила.

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

5.Структура разрабатываемой программы


Идеология оболочки состоит в том, что пользователь будущей базы данных сначала описывает на специальном языке структуры данных, из которых  должны состоять таблицы в базе (то есть фактически интерфейсы) их ссылочные связи, индексы и т.п. Затем при помощи специального транслятора он получает готовый С++ код, реализующий интерфейс работы с базой данных, определенный пользователем, включая саму базу, ее таблицы, записи данных, транзакции и некоторые другие объекты. Код, генерируемый транслятором, на самом деле, является тоже оболочкой. Дело в том, что многие части транслятора имеют под собой общее основание. Эти  статические классы и функции можно выделить в библиотеку. Еще одна причина для этого – семантика самого транслятора должна быть как можно проще. И как следствие этого, сокращаются размеры генерируемых файлов.

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

Новая база данных должна располагать такими возможностями:

·                    Добавление пользовательских данных их модификация и удаление.

·                    Открытие базы в нескольких режимах: например, в нормальном многопользовательском транзакционном режиме, безопасном режиме (как правило, для монопольного доступа и используется утилитами), а также в режиме восстановления  базы данных.

·                    Импорта данных, то есть, представления данных в некотором текстовом формате, и их перемещение в пустую базу данных

·                    Экспорта данных, то есть, перемещение данных из базы, и представление их в определенном текстовом формате в файле, удобном для чтения. Является взаимно обратной операцией предыдущей.

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

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

Итак, вся оболочка состоит из следующих частей:

1.                          Собственно, базовая библиотека статических классов, для высокоуровневой работы с Berkeley, необходимая транслятору.

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

Библиотека классов

«Движок» представляет собой  библиотеку классов, которые с одной стороны являются надстройками вокруг стандартных соответствующих структур, а с другой стороны делают их интерфейс более удобным и   инкапсулируют часть работы транслятора. Основными компонентами являются:

·                    Транзакции

·                    Исключения

·                    Базовые записи

·                    Таблицы

·                    Базы данных

·                    Курсоры

Базовые записи

Базовая запись – это элементарная единица хранения в таблице. Описание ее класса:

//! базовый класс для записей с vtable pointer

class hbObj{

        Dbt   dbt;

protected:

        void dbtInit(uint s,void* d)

                {

                        dbt.set_flags(DB_DBT_USERMEM);

                        dbt.set_ulen(s);

                        dbt.set_size(s);

                        dbt.set_data(d);

                }

public:

        operator Dbt*(){return &dbt;}

        void*   getData(void)   {return dbt.get_data();};

        uint    getSize(void)   {return dbt.get_size();};


        hbObj()                                 {}

        virtual ~hbObj()                        {}

};

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

//! реальный класс, который приводится к Dbt


template <class A> class hbRec:public hbObj

{

        A data;

public:

        A* getPnt(void)         { return &data;} // если в в A массив то можно переопределить   операцию & для А

        hbRec()                                 { memset(&data,0,sizeof(A));dbtInit(sizeof(A),&data);}

        hbRec(const hbRec<A>& a):data(a.data)   { dbtInit(sizeof(A),&data);}

        hbRec(const A& a)       :data(a)        { dbtInit(sizeof(A),&data);}

        void    SetData(const A& a)             { data = a;dbtInit(sizeof(A),&data);}

        virtual ~hbRec()                        {}

};


Таблицы

Диаграмма отношений существующих  таблиц приведена ниже:

По аналогии с записями существует базовый класс таблиц hbBasetbl, который поддерживает работу со всеми стандартными типами таблиц (Hash, Btree, Queue). Фактически ее тип является ее состоянием и определяется в момент открытия.

Страницы: 1, 2, 3, 4, 5, 6, 7



2012 © Все права защищены
При использовании материалов активная ссылка на источник обязательна.