Я использую код обработки ошибок Spirit из статьи «Диспетчеризация при сбоях точек ожидания» по адресу http://boost -spirit.com / home / 2011/02/28 / диспетчеризация по точке ожиданияfailures / comment-page-1 / , последний пример там.Мои классы «Diagnostics» и «Error_handler_impl» в значительной степени совпадают с классами, приведенными в статье, но я могу опубликовать их, если кто-то сочтет это необходимым.
В приведенном ниже коде обсуждается правило запуска
comma = lit(',');
comma.name(",");
start = lit("begin") >> ident > comma >> ident;
имеет точку ожидания после ключевого слова begin.В соответствии со статьей я ожидал, что пропущенная запятая приведет к тому, что обработчику ошибок будет передано значение qi :: _ 4, равное «,», которое является именем правила запятой.Вместо этого он передает «sequence», заставляя обработчик ошибок печатать сообщение по умолчанию, а не информативное «Отсутствие запятой после ключевого слова begin».
Идея, что мне не хватает?
template <typename Iterator, typename Skipper = ascii::space_type>
class Grammar1 : boost::spirit::qi::grammar<Iterator, Skipper>
{
public:
typedef boost::spirit::qi::rule<Iterator, Skipper> rule_nil_T;
typedef boost::spirit::qi::rule<Iterator, string()> rule_str_T;
// structs from Rob Stewart's above-mentioned article
diagnostics<10> d1;
boost::phoenix::function<error_handler_impl> error_handler;
rule_str_T ident;
rule_nil_T comma;
rule_nil_T start;
Grammar1(void) : Grammar1::base_type(start)
{
ident %= lexeme [ qi::raw [ (qi::alpha | '_') >> *(qi::alnum | '_') ] ];
comma = lit(',');
comma.name(",");
start = lit("begin") >> ident > comma >> ident;
d1.add(",", "Missing comma after begin keyword");
on_error<fail>(start,
error_handler(ref(d1), _1, _2, _3, _4));
}
~Grammar1(void) { };
void parseInputFile(Iterator itr, Iterator itr_end)
{
bool r = phrase_parse(itr, itr_end, start, ascii::space);
if (r && itr == itr_end)
{
std::cout << "Parsing succeeded\n";
} else
{
string rest(itr, itr_end);
std::cout << "stopped at: \": " << rest << "\"\n";
}
}
};