![]() |
![]() ![]() ![]() ![]() ![]() |
![]() |
SymbolsBoost , ,
Этот класс символов реализует таблицу символов. В таблице символов содержится словарь символов, где каждый символ представляет собой последовательность CharTs (achar,wchar_t,int, перечисление и т. д.). Класс шаблонов, параметризованный по типу символов (CharT), может эффективно работать с 8, 16, 32 и даже 64-битными символами. Изменяемые данные типа T связаны с каждым символом. Традиционно управление таблицей символов поддерживается отдельно вне грамматики BNF посредством семантических действий. Вопреки стандартной практике, символ таблицы символов Духасимволовявляется парсером. Пример, который может быть использован в любом месте спецификации грамматики EBNF. Это пример динамического парсера. Динамический парсер характеризуется способностью изменять свое поведение во время выполнения. Изначально пустой символ ничего не соответствует. В любое время могут добавляться символы, тем самым динамически изменяя его поведение. Каждая запись в таблице символов имеет связанный с ней изменяемый слот данных. В связи с этим можно рассматривать таблицу символов как ассоциативный контейнер (или карту) пар ключ-значение, где ключи являются струнами. Класс символов ожидает двух параметров шаблона (на самом деле есть третий, см. детализацию). Первый параметрTопределяет тип данных, связанных с каждым символом (по умолчаниюint), и второй параметр.CharTопределяет тип символов символов (по умолчаниюChar). template < typename T = int, typename CharT = char, typename SetT = impl::tst<T, CharT> > class symbols;
Вот некоторые примеры деклараций: symbols<> sym; symbols<short, wchar_t> sym2; struct my_info { int id; double value; }; symbols<my_info> sym3; После объявления таблиц символов символы могут быть добавлены статически с использованием конструкции: sym = a, b, c, d ...; гдесим— таблица символов, аа.ди т.д. — строки. Простой пример: sym = "pineapple", "orange", "banana", "apple", "mango"; Обратите внимание, что неправильно добавлять один и тот же символ несколько раз в таблицу символов, хотя вы можете изменять значение, связанное с символом. Теперь мы можем использовать сим в грамматике. Пример: fruits = sym >> *(',' >> sym); Альтернативно, символы могут быть добавлены динамически через элемент функторадобавить(см.символ_вставканиже). Член функторадобавитьможет быть присоединен к парсеру в качестве семантического действия, принимающего в начале/конце пары: p[sym.add] где p - парсер (а сим - таблица символов). При успехе соответствующая часть ввода добавляется в таблицу символов. Добавитьтакже можно использовать для непосредственного инициализации данных. Примеры: sym.add("hello", 1)("crazy", 2)("world", 3); Предположим, конечно, что слот данных, связанный ссимом, является целым числом. Данные, связанные с каждым символом, могут быть изменены в любое время. Наиболее очевидный путь, конечно, черезсемантические действия. Функция или функтор, как обычно, могут быть прикреплены к таблице символов. В таблице символов предполагается функция или функтор, совместимый с подписью: Подпись для функций:
Подпись для функторов:
ГдеT— тип данных таблицы символов (42] Tв списке параметров шаблона). Когда таблица символов успешно соответствует чему-либо из входных данных, данные, связанные с соответствующей записью в таблице символов, сообщаются семантическому действию. Symbol table utilitiesИногда можно захотеть иметь дело непосредственно со столом символов. Предоставляются некоторые символьные столовые утилиты. Добавить template <typename T, typename CharT, typename SetT> T* add(symbols<T, CharT, SetT>& table, CharT const* sym, T const& data = T()); Добавляет символсим(струна C) в таблицу символовтаблицуплюс дополнительные данныеданные, связанные с символом. Возвращает указатель к данным, связанным с символом илиNULL, если добавление не удалось (например, когда символ уже добавлен ранее). template <typename T, typename CharT, typename SetT> T* find(symbols<T, CharT, SetT> const& table, CharT const* sym); Найден символсим(струна C) из таблицы символовтаблицы. Возвращает указатель на данные, связанные с символом илиNULL, если не найдено symbol_inserterКласс символов содержит экземпляр этого класса, названного, добавить. Это можно назвать непосредственно так же, как функция участника, передавая в первом/последнем итераторе и необязательные данные: sym.add(first, last, data); Или, передавая в строке C и необязательные данные: sym.add(c_string, data); гдесим— таблица символов.данныеявляются необязательными. Самое приятное в этой схеме то, что она может быть каскадной. Мы видели, как это применялось выше. Вот фрагмент из парсера римских цифр // Parse roman numerals (1..9) using the symbol table. struct ones : symbols<unsigned> { ones() { add ("I" , 1) ("II" , 2) ("III" , 3) ("IV" , 4) ("V" , 5) ("VI" , 6) ("VII" , 7) ("VIII" , 8) ("IX" , 9) ; } } ones_p; Обратите внимание, что определенная пользователем структураподклассирована изсимволов. Затем во время строительства мы добавили все символы, используядобавитьсимвол_inserter.
Опять же,добавитьможно также использовать в качестве семантического действия, поскольку оно соответствует интерфейсу действия (см. семантические действия): p[sym.add] где p - парсер, конечно.
Copyright © 1998-2003 Joel de Guzman Статья Symbols раздела может быть полезна для разработчиков на c++ и boost. Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта. :: Главная :: ::
|
||||||||||||||||
©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007 |