![]() |
![]() ![]() ![]() ![]() ![]() |
![]() |
About Tokens and Token ValuesBoost , Spirit 2.5.2 , Lexer Primitives
|
![]() | Note |
---|---|
Если лексический анализатор используется в сочетании с парсеромSpirit.Qi, сохраненное значение токена< |
Вот прототип шаблона<lex::lexertl::token<>
>:
template < typename Iterator = char const*, typename AttributeTypes = mpl::vector0<>, typename HasState = mpl::true_ > struct lexertl_token;
where:
Это тип итератора, используемого для доступа к основному входному потоку. В этом есть доля истины<char
const*
>.
Это либо последовательность mpl, содержащая все типы атрибутов, используемые для определений токенов, либо тип<omit
>. Если последовательность mpl пуста (что является по умолчанию), все экземпляры токенов будут хранить<boost::iterator_range
><<Iterator>
>, указывающие на начало и конец совпадающего раздела во входном потоке. Если тип<omit
>, то генерируемые токены вообще не будут содержать значения токена (атрибута).
Это либо<mpl::true_
>, либо<mpl::false_
>, что позволяет контролировать, будут ли генерируемые экземпляры токенов содержать состояние лексера, в котором они были созданы. По умолчанию mpl::true_, поэтому все экземпляры токенов будут содержать состояние лексера.
Обычно во время строительства экземпляр токена всегда содержит<boost::iterator_range
>в качестве значения токена, если он не был определен с использованием типа значения токена<omit
>. Затем этот диапазон итераторов преобразуется в запрашиваемый тип значения токена (атрибут), когда он запрашивается впервые.
Определения токенов (представленные шаблоном<lex::token_def<>
>) обычно используются как часть определения лексического анализатора. В то же время экземпляр определения токена может использоваться в качестве парсерного компонента.Дух.Qi.
Прототип шаблона этого класса показан здесь:
template< typename Attribute = unused_type, typename Char = char > class token_def;
where:
Это тип значения токена (атрибута), поддерживаемый экземплярами токена, представляющими этот тип токена. Этот тип атрибута подвергается воздействиюБиблиотека Spirit.Qi, когда это определение токена используется в качестве парсерного компонента. Тип атрибута по умолчанию<unused_type
>, что означает, что экземпляр токена содержит<boost::iterator_range
>, указывающий на начало и конец сопоставленного раздела во входном потоке. Если<omit
>, то [[<omit
>], то [[[[[]]], [[[[]]]], [[[[[]]]], [[[[[]]]]], [[[[[[]]]]], [[[[[[]]]]]], [[[[[[]]]]]], [[[[[[[]]]]]][[[[[[[]]]]]][[[[[[]]]]]][[[[[]]]]]][[[[[[]]]]]][[[[[[]]]]]][[[[[]]]]]][[[[[[]]]]]][[[[[[[]]]]]]][[[[[[]]]]]][[[[[[[]]]]]]][[[[[[]]]]]]]][[[[[[[[]]]]]]] Любой другой тип будет использоваться непосредственно как тип значения токена.
Это тип значения итератора для базовой входной последовательности. Недостаток<char
>.
Семантика параметров шаблона для типа токена и типа определения токена очень похожи и взаимозависимы. Как правило, вы можете думать о типе определения токена как о средстве определения всего, что связано с одним конкретным типом токена (например,<identifier
>или<integer
>). С другой стороны, тип токена используется для определения общих свойств всех экземпляров токенов, генерируемых библиотекойSpirit.Lex.
![]() | Important |
---|---|
Если вы не перечислите какие-либо типы значений токена в декларации определения типа токена (что приводит к использованию по умолчанию< Но как только вы укажете хотя бы один тип значения токена при определении типа токена, вам нужно будет перечислить все типы значений, используемые для< |
lex::lexertl::token<>
Начнем с некоторых примеров. Мы ссылаемся на один из примеровSpirit.Lex(для полного исходного кода этого примера см.example4.cpp).
Первый фрагмент кода показывает выдержку из класса определения токена, определение пары типов токенов. Некоторые из типов токенов не выставляют специального значения токена<if_
>,<else_
>и<while_
>. Их значение токена всегда будет удерживать диапазон итератора согласованной входной последовательности. Определения токенов для<identifier
>и целого числа<constant
>специализированы для раскрытия явного типа токена каждый:<std::string
>и<unsigned
int
>.
// these tokens expose the iterator_range of the matched input sequence lex::token_def<> if_, else_, while_; // The following two tokens have an associated attribute type, 'identifier' // carries a string (the identifier name) and 'constant' carries the // matched integer value. // // Note: any token attribute type explicitly specified in a token_def<> // declaration needs to be listed during token type definition as // well (see the typedef for the token_type below). // // The conversion of the matched input to an instance of this type occurs // once (on first access), which makes token attributes as efficient as // possible. Moreover, token instances are constructed once by the lexer // library. From this point on tokens are passed by reference only, // avoiding them being copied around. lex::token_def<std::string> identifier; lex::token_def<unsigned int> constant;
Поскольку парсеры, генерируемыеSpirit.Qi, полностью приписываются, любойSpirit.Qiпарсерный компонент должен выставлять определенный тип в качестве своего парсерного атрибута. Естественно, что<lex::token_def<>
>раскрывает тип значения токена в качестве своего атрибута парсера, обеспечивая плавную интеграцию сSpirit.Qi.
Следующий фрагмент кода показывает, как задаются требуемые типы значений токенов при определении типа токена для использования. Все типы значений токена, используемые по меньшей мере для одного из определений токена, также должны быть повторно повторены для определения токена.
// This is the lexer token type to use. The second template parameter lists // all attribute types used for token_def's during token definition (see // calculator_tokens<> above). Here we use the predefined lexertl token // type, but any compatible token type may be used instead. // // If you don't list any token attribute types in the following declaration // (or just use the default token type: lexertl_token<base_iterator_type>) // it will compile and work just fine, just a bit less efficient. This is // because the token attribute will be generated from the matched input // sequence every time it is requested. But as soon as you specify at // least one token attribute type you'll have to list all attribute types // used for token_def<> declarations in the token definition class above, // otherwise compilation errors will occur. typedef lex::lexertl::token< base_iterator_type, boost::mpl::vector<unsigned int, std::string> > token_type;
Чтобы избежать токена, чтобы иметь значение токена вообще, можно использовать специальный тег<omit
>:<token_def<omit>
>и<lexertl_token<base_iterator_type,omit>
>.
Статья About Tokens and Token Values раздела Spirit 2.5.2 Lexer Primitives может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.
:: Главная :: Lexer Primitives ::
реклама |