Ну там и грамматика, вероятно, сложнее. И пример намного сильно оторванный от жизни. Вероятно из языков в качестве примера больше бы подошло какое-нибудь подмножество SQL.
Сериализация немного другая тема — там важна поддержка параметров разных типов. Если же ограничиться строчными параметрами, то на C++ это бы выглядело так:
void serialize( std::ostream & os, IniData const & data )
{
for ( IniData::const_iterator it = data.begin(); it != data.end(); ++it )
{
os << '[' << it->first << "]\n";
for ( Entries::const_iterator p = it->second.begin(); p != it->second.end(); ++p )
os << p->first << '=' << p->second << '\n';
}
}
На Haskell (правда тут на стандартный вывод, но можно и на файл переделать) printIni sl = mapM_ printSection sl
where
printSection (n, el) = putStrLn ( "[" ++ n ++ "]" ) >> mapM_ printEntry el
printEntry (k, v) = putStr k >> putStr "=" >> putStrLn v
А вы знаете аналог Boost Spirit на ПЛ/0 (хотя, честно говоря, я слышал только про ПЛ/1)?
Это не чисто академический пример. На его основе этой статьи можно, к примеру, написать парсер для текстовых запросов к своей информационной системе. Или свой DSL. Или ещё что-то.
Да, кстати, пресловутые конфиги таким образом тоже можно парсить (не обязательно ini файлы) =)
Статья просто показывает как при помощи boost spirit на основе некоторой грамматики написать парсер. Это не обязательно парсер конфигов — ini файлы просто достаточно простой пример.
Никто не спорит с тем, что сама грамматика ничего не делает. Вопрос в том, что грамматику задавать естественнее, чем описывать некоторый автомат. И в том, что обычные средства для разбора работают с грамматиками.
Конечные автоматы по определению «справляются» за один проход =)
Я согласен, что автомат тут справится, но, ИМХО, описание грамматикой намного естественнее и проще. К тому же для таких описаний есть готовые инструменты (будь это yacc или parsec).
void serialize( std::ostream & os, IniData const & data )
{
for ( IniData::const_iterator it = data.begin(); it != data.end(); ++it )
{
os << '[' << it->first << "]\n";
for ( Entries::const_iterator p = it->second.begin(); p != it->second.end(); ++p )
os << p->first << '=' << p->second << '\n';
}
}
На Haskell (правда тут на стандартный вывод, но можно и на файл переделать)
printIni sl = mapM_ printSection sl
where
printSection (n, el) = putStrLn ( "[" ++ n ++ "]" ) >> mapM_ printEntry el
printEntry (k, v) = putStr k >> putStr "=" >> putStrLn v
Это не чисто академический пример. На его основе этой статьи можно, к примеру, написать парсер для текстовых запросов к своей информационной системе. Или свой DSL. Или ещё что-то.
Да, кстати, пресловутые конфиги таким образом тоже можно парсить (не обязательно ini файлы) =)
Я согласен, что автомат тут справится, но, ИМХО, описание грамматикой намного естественнее и проще. К тому же для таких описаний есть готовые инструменты (будь это yacc или parsec).