Заметки о упражнении GDL

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

      <:ROOT2>
    *PFeature : InputTray    <:INPUTTRAY_FEATURE>
        *POption : Lower    <:INPUTTRAY_OPTION2>
            *Capacity    <:TRAY_CAPACITY>
            *Command    <:ACOMMAND>
            *Name    <:INPUTTRAY_OPT_NAME>
        *POption : Upper    <:INPUTTRAY_OPTION2>
            *Capacity    <:TRAY_CAPACITY>
            *Command    <:ACOMMAND>
            *Name    <:INPUTTRAY_OPT_NAME>
        *DefaultOption    <:DEFAULT_OPT>
        *Name    <:NAME>
    *PFeature : PaperSize    <:PAPERSIZE_FEATURE>
        *POption : Custom    <:CUST_PAPERSIZE_OPTION>
            *MinSize    <:MIN_SIZE>
            *MaxSize    <:MAX_SIZE>
            *Command    <:ACOMMAND>
            *Name    <:PAPER_SIZE_OPT_NAME>
        *POption : OEMName_Special_size    <:OEM_PAPERSIZE_OPTION>
            *OEM_Info    <:OEM_INFO>
            *PaperSize    <:PAPERDIMENSIONS>
            *Command    <:ACOMMAND>
            *Name    <:PAPER_SIZE_OPT_NAME>
        *POption : A4    <:PREDEFINED_PAPERSIZE_OPTION>
            *PaperSize    <:PAPERDIMENSIONS>
            *Command    <:ACOMMAND>
            *Name    <:PAPER_SIZE_OPT_NAME>
        *POption : Legal    <:PREDEFINED_PAPERSIZE_OPTION>
            *PaperSize    <:PAPERDIMENSIONS>
            *Command    <:ACOMMAND>
            *Name    <:PAPER_SIZE_OPT_NAME>
        *POption : Letter    <:PREDEFINED_PAPERSIZE_OPTION>
            *PaperSize    <:PAPERDIMENSIONS>
            *Command    <:ACOMMAND>
            *Name    <:PAPER_SIZE_OPT_NAME>
        *DefaultOption    <:DEFAULT_OPT>
        *Name    <:NAME>
    *PFeature : random    <:PFEATURE >
        *POption : First    <:GENERIC_OPTION>
            *Command    <:ACOMMAND>
            *Name    <:NAME>
        *DefaultOption    <:DEFAULT_OPT>
        *Name    <:NAME>

Записи *Name и *POption сопоставляются с несколькими шаблонами, каждый из которых имеет разную семантику. Например, *Name сопоставляется с NAME, INPUTTRAY_OPT_NAME или PAPER_SIZE_OPT_NAME. *POption сопоставляется с GENERIC_OPTION, PREDEFINED_PAPERSIZE_OPTION, CUST_PAPERSIZE_OPTION, OEM_PAPERSIZE_OPTION или INPUTTRAY_OPTION2. Если структура шаблона определена правильно, средство синтаксического анализа, следуя правилам шаблонизации, найдет наиболее подходящий шаблон.

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

Ответы на упражнения, которые отображаются, не являются уникальными. Например, можно получить шаблоны MIN_SIZE и MAX_SIZE из PAPERDIMENSIONS следующим образом.

*Template:  MIN_SIZE
{
    *Name: "*MinSize"
    *Inherits: PAPERDIMENSIONS
}
*Template:  MAX_SIZE
{
    *Name: "*MaxSize"
    *Inherits: PAPERDIMENSIONS
}

Обратите внимание, что шаблоны PAPER_SIZE_OPT_NAME и INPUTTRAY_OPT_NAME наследуются от шаблона NAME и также переопределяют запись *Name.

Результат переопределения записи *Name заключается в скрытии этих производных шаблонов из дерева наследования, устанавливаемого базовыми шаблонами.

Как правило, если шаблон объявляет NAME как *Member, это объявление подразумевает, что все шаблоны, производные от NAME, также являются *Member. Однако производные шаблоны с переопределенными записями *Name исключены из подразумеваемого списка членов производных шаблонов. Без этого исключения вводы данных, которые изначально сопоставлены с NAME шаблона (например, *Имя, отображаемое в *Pfeature), будут сопоставлены с INPUTTRAY_OPT_NAME, что является ошибкой.

Если на этапе первоначальной разработки схемы вы ожидаете специализации NAME в PAPER_SIZE_OPT_NAME и INPUTTRAY_OPT_NAME, получится другая реализация схемы, если просто удалить NAME из списка членов GENERIC_OPTION. Это изменение устранит необходимость в переопределении *Name. Дальнейшая доработка дизайна предполагает, что NAME, PAPER_SIZE_OPT_NAME и INPUTTRAY_OPT_NAME будут наследоваться от общего виртуального шаблона, поскольку это более точно отражает отношения между этими ключевыми словами.