Пакет "bnf"

В пакет bnf входят:

  1. bnf-парсер
  2. классы узлов ast'а для bnf
  3. управляющий класс Main
  4. классы-операции
  5. динамические атрибуты дерева грамматики
  6. вспомогательные классы и интерфейсы

Устанавливать системные свойства пакета можно как в командной строке, так и в файле "bnf.properties". Установки системных свойств в строке имеют больший приоритет, чем установки в файле. Кроме того, файл вообще необязателен.


BNF-парсер.

Парсер по BNF-форме грамматики строит дерево разбора, узлы которого соответствуют узлам ast'а для BNF.


Описание грамматики с помощью BNF.

Грамматика (grammar) состоит из нескольких правил.

Правило (rule) это идентификатор ( имя нетерминала ) в левой части, оператор "::=" и выражение (expression) в правой части.

Выражение -- это список альтернатив-термов (term), разделенных знаком "|".

Терм -- это несколько факторов (factor), идущих подряд.

Фактор может быть либо идентификатором, либо текстом в двойных кавычках, либо именем лексемы в угловых скобках, либо выражением в круглых скобках, за которым может стоять один из флажков -- "*", "?" или "+".

Значение флажков следующие:

Кроме того в любом месте bnf-файла допускаются комментарии в стиле Java, а перед правилом -- javadoc-коментарии.

BNF для BNF.


Узлы ast'а для BNF.


Управляющий класс Main.

Класс Main принимает на вход имя файла с bnf-грамматикой и список имен операций (action), которые необходимо выполнить.

    Usage: Main <bnf_file> или  <?> <action_name_1> ... <action_name_n>

Именем должно быть имя объекта-операции. Все имена объектов должны быть указаны в отдельном файле в следующем формате:

    <имя объекта-операции> <полное имя класса, к которому принадлежит этот объект>

Объекты-вычислители динамических атрибутов, используемые при работе операциями, должны быть зарегистрированы в том же файле что и объекты-операции так:

    <имя атрибута> <полное имя класса, вычисляющего этот атрибут>
Путь до файла со списком имен объектов-операций и объектов-вычислителей указывается как системное свойство "bnf.alias.file". В первой строке этого файла должен быть указан общий префикс для системных свойств всех используемых объектов -- рекомендуется слово "bnf". Подробнее об этом см. здесь.

Работа происходит следующим образом:

Main читает системные свойства из файла "bnf.properties" (если такой существует), затем вызывает BNF-парсер, который создает дерево разбора заданной грамматики. Системные свойства заданные в командной строке обладают более высоким приоритетом, чем заданные в файле. Если вместо имени файла с грамматикой стоит знак вопроса, то в случае отсутствия после него имен операций будут выведены все имена, использующиеся в системе, с указанием того, чему они соответствуют (операции или вычислителю атрибутов). Если после знака вопроса идет несколько имен, то если соответствующий объект является Helper'ом, для него будет выведена вспомогательная информация, в противном случае для этого объекта будет выдано сообщение об отсутствии вспомогательной информации.

Наконец, происходит выполнение операций в порядке, указанном пользователем в командной строке. Для получения объектов-операций используется поле action_manager класса BNF.

Если свойство "bnf.alias.file" не определено, пользователь получает предупреждение, после чего работа Main'а прерывается.


Классы-операции.

Все классы-операции должны реализовать интерфейс Action:

interface Action extends Helper
{
    void process( Grammar grammar );
}

Вся содержательная работа выполняется при запуске метода process данного класса-операции. См. также Helper.

Имеющиеся классы-операции.


Динамические атрибуты.

Всякий класс-вычислитель динамического атрибута реализует интерфейс Attribute:

interface Attribute extends Helper
{
    public Object get( Node node );
}
При вызове метода get класс-вычислитель находит значение соответствующего атрибута узла node. См. также Helper.

Для управления классами-вычислителями имеется класс AttributeManager.


Вспомогательные классы.

1. Класс ClassInstanceAliasTable.

Класс ClassInstanceAliasTable входит в пакет dynamicVariables.

Этот класс предназначен для создания, хранения и использования отображений типа: строка -> объект, а также для преодоления конфликта имен системных свойств.

Конструктор класса:

    ClassInstanceAliasTable ( File file ) throws ClassInstanceAliasTableException { ... }
file -- это файл, формат которого должен быть следующим:
    <общий префикс>
    <строка без пробелов> <полное имя класса>
    ...
    <строка без пробелов> <полное имя класса>
В первой строке файла file указывается общий префикс для системных свойств объектов, которые будут создаваться данным ClassInstanceAliasTable'ом, далее задается отображение строка (имя объекта) -> имя класса. Если префикс не определен, то возбуждается исключение.

При использовании конструктора создается Hashtable: строка слева -> строка справа.

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

Для доступа к объектам ClassInstanceAliasTable имеет метод

    Object get( String name ) { ... }
возвращающий объект, соответствующий строке name. Если нужный объект еще не существует, то он будет создан. При повторном обращении будет возвращен тот же самый объект.

Если имя name неизвестно данному ClassInstanceAliasTable'у, то будет возбуждено исключение.

Метод

    String getProperty( Object object, String name_of_property ) { ... }
позволяет получить свойство с именем "префикс_для_объекта_object.name_of_property". Префиксы для объектов определяются следующим образом: объект с именем String name получает префикс "общий_префикс_для_данного_ClassInstanceAliasTable.name".

По поводу системных свойств см. также Соглашение об именах системных свойств.

Метод

    public Enumeration names()
позволяет узнать все имена, известные данному ClassInstanceAliasTable'у.

2. Класс ActionManager.

Этот класс предназначен для регистрации и использования объектов-операций.

Конструкторы класса:

    ActionManager ( String file_name ) { ... }
file_name -- это имя файла, формат которого должен быть следующим:
    <имя объекта-операции> <полное имя класса, к которому принадлежит этот объект>
При вызове конструктора создается объект класса ClassInstanceAliasTable, которому передается файл с именем file_name.

    ActionManager ( ClassInstanceAliasTable table ) { ... }
В конструкторе устанавливается ссылка на объект класса ClassInstanceAliasTable.

Для осуществления операции имеется метод:

    void process( String action_name, Grammar grammar ) { ... }
этот метод находит объект, отвечающий имени action_name, и запускает его на грамматике grammar, то есть вызывается соответствующий метод process.

3. Класс AttributeManager.

Этот класс предназначен для управления объектами-вычислителями динамических атрибутов некоторого дерева.

Конструкторы класса:

    AttributeManager ( String file_name ) { ... }
file_name -- это имя файла, формат которого должен быть следующим:
    <имя атрибута> <полное имя класса, вычисляющего этот атрибут>.
При вызове конструктора создается объект класса ClassInstanceAliasTable, которому передается файл с именем file_name.

    AttributeManager ( ClassInstanceAliasTable table ) { ... }
В конструкторе устанавливается ссылка на объект класса ClassInstanceAliasTable.

Для вычисления значения атрибута с именем name в узле node нужно воспользоваться методом

    Object get( String name, Node node ).

4. Класс BNF.

Этот класс содержит статические поля

    static ClassInstanceAliasTable class_instance_alias_table;
См. ClassInstanceAliasTable.
    static ActionManager action_manager;
См. ActionManager
    static AttributeManager attribute_manager;
См. AttributeManager

Инициализация статических полей происходит в статическом блоке: для инициализации class_instance_alias_table'а вызывается конструктор от файла, путь до которого указан как системное свойство "bnf.alias.file", для инициализации action_manager'а и attribute_manager'а вызываются соответствующие конструкторы от class_instance_alias_table'а.

5. Интерфейс Helper.

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

interface Helper
{
    void help();
}
Вся вспомогательная информация выводится при вызове метода help().


Соглашение об именах системных свойств.

Все имена свойств данного пакета начинаются с "bnf.". Об этом см. также здесь и здесь.

Есть выделенное имя "bnf.alias.file"

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


В начало документа.


Софья Зеленова
Last modified: Mon Feb 26 13:47:30 MSK 2001