![]() |
![]() ![]() ![]() ![]() ![]() |
![]() |
SubrulesBoost , ,
Дух реализуется с использованием шаблонов выражения. Это очень мощная техника. Наряду с его мощью возникают некоторые осложнения. Мы почти считаем само собой разумеющимся, что когда мы пишемi | j >>k, гдеi,jиkявляются целыми числами, результат все еще является целым числом. Тем не менее, с шаблонами выражения, то же самое выражениеi | j >>k, гдеi,jиkимеют типT, в результате получается сложный составной тип [см.Основные понятия]. Духовные выражения, представляющие собой комбинации примитивов и композитов, дают бесконечное множество новых типов. Одна из проблем заключается в том, что C++ не предлагает простой возможности для вывода типа произвольно сложного выражения, которое дает сложный тип. При этом легко написать:
Шаблоны выражения дают бесконечный запас типов. Без правилав C++ нет простого способа сделать это, еслиi,jиkявляются парсерами Духа:
Еслиi,jиkявляютсяобъектамиchlit< >, мы хотим:
Мы намеренно отформатировали объявление типа, чтобы сделать его понятным. Попробуйте это с более сложным выражением. Хотя это может быть сделано, явное изложение типа шаблона выражения Духа утомительно и подвержено ошибкам. Правая сторона (rhs) должна отражать тип левой стороны (lhs).
К счастью, на помощь приходят правила. Правила могут фиксировать тип выражения, присвоенного ему. Таким образом:
Это может быть не очевидно, но за кулисами простые правила фактически реализуются с использованием указателя на полиморфный абстрактный класс во время выполнения, который содержит динамический тип парсера, назначенного ему. Когда выражение Духа приписывается правилу, его тип инкапсулируется в конкретный подкласс абстрактного класса. Функция виртуального разбора делегирует разбор инкапсулируемому объекту. Однако правила имеют недостатки:
Static rules: subrulesПодправило является полностью статичной версией правила. Подправило не имеет недостатков, перечисленных выше.
Первый параметр шаблона дает подправилу идентификационный тег. Как правило, есть параметр шаблона ContextT, который по умолчанию< Выше представлен публичный API. ПослеContextTможет быть больше параметров шаблона. Все, что послеContextTпараметра не должно беспокоить клиента и предназначено исключительно для внутреннего использования. Помимо нескольких незначительных различий, подправило следует за использованием и синтаксисом правила. Вот грамматика калькулятора с использованием подправил:
Подправило как эффективная версия правила. Оптимизация компилятора, такая как агрессивное наложение, помогает уменьшить размер кода и значительно повысить производительность. Однако подправило не является панацеей. Подправила сильно толкают компилятор C++ на колени. Например, текущие компиляторы имеют предел глубины рекурсии, который не может быть превышен. Даже не думайте о написании полной паскалевой грамматики, используя только подправила. Грамматика, использующая подправила, представляет собой одно выражение C++. Современные компиляторы C++ не очень хорошо справляются со сложными выражениями. Наконец, для того, чтобы стать держателем подправил, по-прежнему необходимо четкое правило. Приведенный выше код является хорошим примером рекомендуемого способа использования подправил. Обратите внимание на иерархию. У нас есть грамматика, которая инкапсулирует весь калькулятор. Правило старта — это простое правило, которое содержит набор подправил. Подправила, в свою очередь, определяют фактические детали грамматики.
Эта установка обеспечивает хороший баланс. Подзаконные акты выполняют всю работу. У каждой грамматики есть только одно правило:первое. Правило используется только для того, чтобы удерживать подправила и делать их видимыми для грамматики. The subrule definitionКак и правило, выражение после назначения оператора=определяет подправило: identifier = expression В отличие от правил, подправила могут быть определены только один раз. Переопределение подправила является незаконным и приведет к составлению заявления о времени. Separators [ , ]При этом правила прекращаются полуколоном';'. Подправила не прекращаются, а разделяются запятой:',. Как и заявления Паскаля, последнее подправило в группе может не иметь запятой. a = ch_p('a'), b = ch_p('b'), c = ch_p('c'), // BAD, trailing comma < >Стартовое правилоВ отличие от правил, парсинг исходит из начального подправила. Первое (самое верхнее) подправило в группе подправил называетсястартовым подправилом. В приведенном выше примеревыражениеявляется начальным подправилом. При вызове группы подправил первым называется выражение начального подправила. IDsКаждое подправило имеет соответствующий идентификатор; интегральную константу, которая однозначно определяет подправило. Приведенный выше пример имеет четыре подправила. Они объявляются как:
AliasesМожно иметь подправила с аналогичными идентификаторами. Подправило с аналогичным идентификатором будет псевдонимом другого. Оба подправила могут использоваться взаимозаменяемо.
Groups: scope and nestingСфера действия подправила и его определение — это замкнутая группа, обычно (и по соглашению), заключенная в скобки. Идентификаторы за пределами области не видны напрямую. Внутренние подгруппы могут быть вложены путем включения каждой подгруппы в другой набор скобок. Каждая группа уникальна и действует самостоятельно. Следовательно, хотя это может быть нецелесообразно, подправило в группе может иметь тот же идентификатор, что и подправило в другой группе, поскольку обе группы независимы друг от друга.
Подправила должны быть уникальными только в группе. Грамматика — это неявная группа. Кроме того, даже подправила в грамматике могут иметь одинаковые идентификаторы без столкновения, если они находятся внутри группы. Подправила могут быть явно сгруппированы с использованием скобок. Парентезированные группы имеют уникальные области применения. В приведенном выше коде группа внешних подправил определяет подправилаaиb, в то время как группа внутренних подправил определяет подправилаcиd. Обратите внимание, что определениеbявляется внутренним подправилом.
Copyright © 1998-2003 Joel de Guzman
< Статья Subrules раздела может быть полезна для разработчиков на c++ и boost. Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта. :: Главная :: ::
|
|||||||||||||||||||
©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007 |