23 июня 2009

Fast parsing

Чем вы парсите всякую "мелочёвку" типа целочисленных значений и прочее? Самописными парсерами с приправами вроде boost::tokenizer, boost::lexical_cast или даже atoi, etc.? Я обычно использовал boost::regex + lexical_cast. А тут недавно посмотрел презентацию Spirit-а с BoostCon-а, даже немного проникся. Раньше как-то я к Спириту более равнодушен был.

Описывать грамматику на C++ и потом давать компилятору [несколько минут] это компилировать - это, конечно, большой изврат. Но весьма забавно. И, говорят, работает потом очень быстро. Даже если нужно просто число распарсить - говорят быстрее всех парсит.
std::string buffer("1234");
int value = 0;

using namespace boost::spirit;
bool r = qi::parse(buffer.begin(), buffer.end(), int_, value);
assert(r && value == 1234);

14 июня 2009

Visual Studio debug visualizers

Начиная с Visual Studio 2005 можно писать свои правила для отображения значений в отладчике. Более подробнее об этом можно почитать в блоге virtualdub.

Правила для Boost-овских типов можно найти на Boost Wiki. Единственное, не нашел там то, что искал — для boost::variant. Набросал на коленке:
boost::variant<*,*,*,*,*,*,*,*,*,*,*> {
preview (
#(
#switch($c.which_)
#case 0 ( *($T1 *)&($c.storage_.data_) )
#case 1 ( *($T2 *)&($c.storage_.data_) )
#case 2 ( *($T3 *)&($c.storage_.data_) )
#case 3 ( *($T4 *)&($c.storage_.data_) )
#case 4 ( *($T5 *)&($c.storage_.data_) )
#case 5 ( *($T6 *)&($c.storage_.data_) )
#case 6 ( *($T7 *)&($c.storage_.data_) )
#case 7 ( *($T8 *)&($c.storage_.data_) )
#case 8 ( *($T9 *)&($c.storage_.data_) )
#case 9 ( *($T10 *)&($c.storage_.data_) )
)
)
children
(
#(
value:
#switch($c.which_)
#case 0 ( *($T1 *)&($c.storage_.data_) )
#case 1 ( *($T2 *)&($c.storage_.data_) )
#case 2 ( *($T3 *)&($c.storage_.data_) )
#case 3 ( *($T4 *)&($c.storage_.data_) )
#case 4 ( *($T5 *)&($c.storage_.data_) )
#case 5 ( *($T6 *)&($c.storage_.data_) )
#case 6 ( *($T7 *)&($c.storage_.data_) )
#case 7 ( *($T8 *)&($c.storage_.data_) )
#case 8 ( *($T9 *)&($c.storage_.data_) )
#case 9 ( *($T10 *)&($c.storage_.data_) )
)
)
}