Научная статья на тему 'Язык описания структурированных данных Tabula'

Язык описания структурированных данных Tabula Текст научной статьи по специальности «Компьютерные и информационные науки»

CC BY
123
22
i Надоели баннеры? Вы всегда можете отключить рекламу.
Ключевые слова
ЯЗЫК ОПИСАНИЯ ДАННЫХ / ИЕРАРХИЧЕСКАЯ МОДЕЛЬ / УПОРЯДОЧЕННЫЕ ДЕРЕВЬЯ / DATA DESCRIPTION LANGUAGE / HIERARCHICAL MODEL / ORDERED TREES ESTIMATE

Аннотация научной статьи по компьютерным и информационным наукам, автор научной работы — Ершов H. М.

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

i Надоели баннеры? Вы всегда можете отключить рекламу.
iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.
i Надоели баннеры? Вы всегда можете отключить рекламу.

Текст научной работы на тему «Язык описания структурированных данных Tabula»

14. Vasieek О., Fong G. Term structure modeling using exponential splines // J. Finance. 1982. 37. N 2. P. 339-348.

15. Fisher M., Nychka D., Zervos D. Fitting the term structure of interest rates with smoothing splines // Working Paper. Finance and Economics Discussion Series. Washington, DC: Federal Reserve Board, 1995. N 95-1.

16. Adams K., Van Deventer D. Fitting yield curves and forward rate curves with maximum smoothness // J. Fixed Income. 1994. 1. N 4. P. 52-62.

17. Waggoner D. Spline methods for extracting interest rate curves from coupon bond prices // Federal Reserve Bank of Atlanta Working Paper 97-10. 1997. P. 1-23.

18. Лапшин В. А. Об определении временной структуры процентных ставок // Сб. статей молодых ученых факультета ВМиК МГУ. Вып. 3. М.: МАКС Пресс, 2006. С. 92-98.

19. Тихонов А.Н., Арсенин В.Я. Методы решения некорректных задач. М.: Наука, 1979.

Поступила в редакцию 29.04.09

УДК 519.682,004.622

H.М. Ершов1

ЯЗЫК ОПИСАНИЯ СТРУКТУРИРОВАННЫХ ДАННЫХ TABULA

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

Ключевые слова: язык описания данных, иерархическая модель, упорядоченные деревья.

I. Введение. Язык Tabula предназначен для описания структурированных данных. Под данными понимается набор именованных записей, содержащих список значений — атрибутов. Под структурированностью — иерархическая (древовидная) упорядоченность записей. Областью применения языка Tabula является прежде всего подготовка пользователем входных данных для программ. Также этот язык может использоваться для обеспечения взаимодействия (по данным) разных программ.

Примерами простейших языков описания структурированных данных являются язык описания ini-файлов, используемый в ОС Windows, и сходный с ним язык описания входных данных (namelists) в языке Фортран [1]. В обоих случаях данные представляются множеством пар имя-значение, разбитыми на секции. Таким образом, используется двухуровневая иерархия. Записи нижнего уровня характеризуются уникальным (внутри секции) именем.

Стандартом де-факто для описания более сложно структурированных данных является язык XML [2]. Важнейшим отличием XML от языка, предлагаемого в настоящей статье, является то, что XML — это язык разметки текста. Поэтому при использовании XML в качестве языка описания данных, как правило, не используются его свойства, связанные именно с разметкой текста. Недостатком языка XML с точки зрения обеспечения пользовательского интерфейса (пользователь-программа) является его сложная для человеческого восприятия структура, основанная на системе открывающих-закрывающих тегов. Другим минусом является то, что все атрибуты тегов должны быть именованными, т. е. при необходимости хранения данных векторного типа приходится каждому элементу вектора давать свое собственное имя либо сохранять весь вектор внутри одного атрибута, перекладывая вопрос выделения элементов вектора на пользовательскую программу.

С целью преодоления указанных недостатков языка XML был разработан ряд языков, решающих тем или иным образом перечисленные проблемы. Большую часть в этом ряду занимают так называемые языки-адаптеры (PYX, SOX, SLiP, SXML и др.), которые полностью сохраняют семантику языка XML, но используют более простую (визуальную) структуру, основанную либо на табуляции, либо на

1 Факультет ВМиК МГУ, с.н.с., к.ф.-м.н., e-mail: ershovnmQgmail.com.

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

К другой группе относятся языки, использующие принципиально отличные от XML схемы представления данных. Наиболее характерным примером такого рода языка является язык YAML [4]. Этот язык предоставляет гибкие возможности упорядочивания данных, основанные на использовании стандартных структур данных — списков, словарей и деревьев. Другой отличительной особенностью этого языка является типизация: YAML поддерживает основные числовые, строковые, логические и другие типы значений. Вместе с тем сложность используемых данным языком механизмов сказывается на легкости восприятия текстов, записанных на YAML, что затрудняет его применение в качестве пользовательского интерфейса — организации входных/выходных данных для программ.

Описываемый в настоящей статье язык Tabula также направлен на преодоление вышеуказанных недостатков языка XML. В качестве метода структуризации данных предлагается использовать механизм табуляции, хорошо зарекомендовавший себя в языке программирования Python [5]. Данные представляют собой набор записей, упорядоченный в древовидную структуру. При этом каждая отдельная запись может содержать атрибуты двух типов — именованные, образующие словарь, и неименованные, образующие список. Все имена записей, ключи и значения атрибутов представляются единой синтаксической конструкцией — последовательностью произвольных символов (за исключением небольшого количества специальных символов), возможно заключенных в кавычки.

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

2. Модель данных. В основу языка Tabula положена следующая иерархическая модель данных. Все данные представляются в виде набора записей. Каждая запись характеризуется именем и набором атрибутов. Имя записи не обязано быть уникальным. Атрибуты записи могут быть именованными и неименованными. Именованные атрибуты имеют ключ, уникальный внутри данной записи. Значением атрибута является строка символов. Доступ к именованным атрибутам осуществляется по ключу, к неименованным — по их номеру (позиции) среди других неименованных атрибутов.

Пример организации данных в рассматриваемой модели

Совокупность всех записей образует иерархическую структуру: каждая запись может содержать список вложенных записей. Внутри этого списка доступ к отдельным записям в общем случае производится по их номеру (позиции), так как имена записей не обязаны быть уникальными, поэтому не могут служить ключом. На самом верхнем уровне иерархии все данные представлены одной записью, имеющей стандартное имя ТАВиЬА_Б0СиМЕ1\ПГ и пустой список атрибутов. Пользуясь стандартной терминологией теории структур данных, предлагаемая модель данных является упорядоченным деревом [6]. Пример графового представления данных в рассматриваемой модели показан на рисунке.

3. Описание языка. Каждая запись в стандартном режиме занимает в языке Tabula ровно одну строку и имеет следующую структуру: имя список-атрибутов. Список атрибутов содержит атрибуты данной записи, разделенные точкой с запятой. Именованные атрибуты имеют структуру ключ = значение, неименованные — просто значение. Имя записи, ключ и значение атрибута представляют собой последовательность символов, которую будем называть словом. Словом является последовательность любых символов, заключенная в один из шести вариантов кавычек — одинарных и тройных кавычек, одинарных и тройных апострофов, одинарных и тройных обратных апострофов:

"слово........слово......

5 слово5 ' ' 'слово5 5 5 'слово' ' ' 'слово'''

Причем строка, заключенная в одинарные кавычки, не может содержать кавычек (одинарных или тройных) того же типа, а строка, заключенная в тройные кавычки, не может содержать тройных кавычек того же типа. Если возникает необходимость включения всех видов кавычек в одно слово, то в этом случае можно их экранировать с помощью символа обратной косой черты: V и V (а также \\ для включения символа обратной косой черты). Слово может содержать символы перевода на новую строку, что позволяет, например, сохранять в атрибутах многострочные тексты (например, тексты программы). Если слово не содержит никаких кавычек, пробелов, точек с запятой, знаков равенства, решеток (#) и символов перевода строки, то его можно не заключать в кавычки.

Приведем несколько примеров корректных записей в языке Tabula.

1. 'Простая запись5 х=1; у=2

2. array name=A; 1; 2; 3; 5; 8; 13

3. 'just name'

4. empty ""

5. + "Вложенные 'кавычки'" = yes

6. ? ......'три' "типа" вложенных 'кавычек'......

7. multiline 'Многострочный текст'

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

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

Вложенность записей друг в друга регулируется отступами. Отступ — это подстрока, состоящая из одних пробелов, расположенная в начале строки с записью (перед ее именем). Назовем размером отступа количество пробелов в нем. Если какая-либо запись А содержит список вложенных записей, то все они должны располагаться непосредственно за ней и иметь одинаковый отступ, строго больший, чем отступ у записи А. Такой способ описания вложенных структур заимствован из языка Python.

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

section name=genray

variable name=nstop; type=int; gui=edit variable name=rho; type=real; gui=edit section name=output

variable name=mode; type=int; gui=select

choice title=on; value=l choice title=off; value=0 parameters

parameter name=nx; value=100

parameter name=R0; value=1.4e2

Язык Tabula поддерживает строчные комментарии. Комментарием считается подстрока, начинающаяся с символа решетки и заканчивающаяся концом строки, причем символ решетки не должен быть частью значения некоторого слова, ограниченного кавычками, например, в следующем фрагменте:

record # строка с комментарием record "# строка без комментария"

Первая запись не имеет атрибутов, строка с ней содержит комментарий, вторая запись имеет один неименованный атрибут, строка с этой записью не содержит комментария.

4. Описание библиотеки. Для работы с данными, описанными на языке Tabula, была разработана библиотека на языке Python. Каждая запись (и весь документ в частности) в этой библиотеке реализована в виде словаря с четырьмя полями, в которых хранятся: 1) имя записи (key); 2) список ее неименованных атрибутов (1st); 3) словарь именованных атрибутов (die); 4) список вложенных записей (body).

Все функции для работы с документами можно разбить на три группы — чтение, запись и создание документа; поиск записей в документе; доступ к элементам записи. К первой группе относится пять функций:

• load и save — читает, сохраняет документ;

• makedoc — создает и возвращает новый документ из заданного списка записей;

• maker ее — создает и возвращает новую запись с заданными полями;

• validate — проверяет корректность структуры и всех значений заданного документа.

Функции второй группы служат для доступа и модификации всех полей заданной записи. В эту группу входят следующие функции:

• getkey. setkey — получает, устанавливает имя записи;

• getlst. setist — получает, устанавливает список неименованных атрибутов;

• getlstitem, setlstitem, addlstitem, dellstitem — получает, устанавливает, добавляет, удаляет

неименованный атрибут;

• getdic, setdic — получает, устанавливает список именованных атрибутов;

• getdicitem, setdicitem, deldicitem — получает, устанавливает, удаляет именованный атрибут;

• getbody, setbody — получает, устанавливает список вложенных записей;

• getbodyitem, setbodyitem, addbodyitem, delbodyitem — получает, устанавливает, добавляет,

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

Функции из третьей группы связаны с поиском нужных записей в документе. Все они оперируют понятием пути в документе. Так как графовым представлением документа является дерево, то для адресации конкретной записи в этом документе можно использовать путь, составленный из имен тех записей (начиная с корня), в которые вложена данная запись. Имена записей в пути разделяются символом /. Проблема заключается в том, что имена записей не являются уникальными, т.е. в общем случае заданный путь может адресовать несколько записей. Поэтому считается, что при поиске записи на каждом уровне вложенности выбирается первая запись с указанным в пути именем. Например, для документа, представленного на рисунке, путь section/variable указывает на запись с атрибутом name='nstop\ А путь section/variable/choice не адресует никакой записи, так как запись, соответствующая первым двум элементам пути section/variable, не содержит в себе записи с именем choice.

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

и (через знак равенства) его значение, то из списка записей будет выбрана первая запись с заданным именем и заданным атрибутом (ключ и значение). Аналогично после имени записи можно через символ решетки # указать номер неименованного атрибута и (через знак равенства) его значение. Неименованные атрибуты индексируются с нуля. Таким образом, путь section/variable :name=rho указывает на запись с именем variable, содержащую именованный атрибут с ключом name и значением rho, и вложенную в запись с именем section. А чтобы адресовать вторую запись с именем choice, надо использовать, например, путь

section :name=output/variable/choice:value=0.

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

• getrec и getreclist — ищет (вышеописанным способом) и возвращает запись (список записей) в заданном документе по заданному пути;

• addrec и delrec — добавляет/удаляет запись, соответствующую заданному пути.

5. Заключение. Мотивацией к созданию нового языка описания данных послужила разработка системы удаленного запуска больших вычислительных кодов, использующая протокол HTTP. Большая часть входных данных (конфигурационные файлы) в этой системе формируется либо администратором системы, либо авторами-разработчиками самих кодов. Это предопределило список требований к языку описания этих данных: простой, но достаточно мощный синтаксис, легко воспринимаемая структура, отсутствие ограничений на имена и значения данных, на их количество, на сложность (глубину) структуры. Были проанализированы имеющиеся средства описания сложно структурированных данных. На основании проведенного анализа было принято решение создать новый язык. В основу языка была положена иерархическая (древовидная) структура данных, аналогичная структуре данных в XML, но без средств разметки. В качестве метода структуризации данных было решено использовать механизм табуляций, с успехом применяющийся, например, в языке Python. Библиотека для работы с этим языком была написана на языке Python, так как вышеупомянутая система запуска кодов писалась именно на этом языке. Интерфейс библиотеки разрабатывался с учетом того, чтобы в будущем его можно было легко перенести на другие языки, прежде всего на С++. Библиотека является достаточо компактной, весь ее код занимает чуть больше 600 строк (около 20 килобайт).

Язык Tabula представляет собой удобное средство подготовки разнообразных входных данных для различных программных систем. Кроме того, он может служить и для организации взаимодействия (по данным) между различными модулями одной и той же программной системы или между различными программными системами. В будущем предполагается развитие надстройки над языком Tabula, включая другие (например, потоковые) версии библиотеки, средств визуализации, средств проверки правильности документов и так далее.

СПИСОК ЛИТЕРАТУРЫ

1. Chapman S. J., Chapman S. Fortran 90/95 for Scientists and Engineers. McGraw-Hill, 2003.

2. Harold E.R., Means W.S. XML in a Nutshell. O'Reilly, 2004.

3. Dumb ill E. XML Watch: Exploring alternative syntaxes for XML. IBM developer Works. Oct. 2002. URL: http://www-128.ibm.com/developerworks/xml/library/x-syntax.html.

4. Mertz D. XML Matters: YAML Improves on XML. YAML Ain't Markup Language. IBM developer Works, XML zone. Oct. 2002. URL: http://www-106.ibm.com/developerworks/library/x-matters23.html.

5. Сузи P. Язык программирования Python. M.: ООО "ИНТУИТ.ру", 2007.

6. Кнут Д. Искусство програмирования. Т. 1. Основные алгоритмы. М.: Издательский дом "Вильяме", 2000.

Поступила в редакцию 01.12.08

i Надоели баннеры? Вы всегда можете отключить рекламу.