Как правильно разобрать это с духом?
-
19-08-2019 - |
Вопрос
Моя ситуация: я новичок в Spirit, я должен использовать VC6 и поэтому использую Spirit 1.6.4.
У меня есть строка, которая выглядит следующим образом:
//The Description;DESCRIPTION;;
Я хочу поместить текст DESCRIPTION
в строку, если строка начинается с //The Description;
.
У меня есть кое-что, что работает, но выглядит не очень элегантно для меня:
vector<char> vDescription; // std::string doesn't work due to missing ::clear() in VC6's STL implementation
if(parse(chars,
// Begin grammar
(
as_lower_d["//the description;"]
>> (+~ch_p(';'))[assign(vDescription)]
),
// End grammar
space_p).hit)
{
const string desc(vDescription.begin(), vDescription.end());
}
Я бы очень хотел назначить всем печатным символам до следующего ';'
, но следующее не будет работать, потому что parse(...).hit == false
parse(chars,
// Begin grammar
(
as_lower_d["//the description;"]
>> (+print_p)[assign(vDescription)]
>> ';'
),
// End grammar
space_p).hit)
Как сделать так, чтобы он попал?
Решение
Вы можете попробовать использовать confix_p
:
confix_p(as_lower_d["//the description;"],
(+print_p)[assign(vDescription)],
ch_p(';')
)
Он должен быть эквивалентен ответу Фреда .
Причина, по которой ваш код не работает, заключается в том, что print_p
жадный . Синтаксический анализатор +print_p
будет потреблять символы, пока не встретит конец ввода или непечатаемый символ. Точка с запятой пригодна для печати, поэтому (print_p - ';')
утверждает это. Ваш ввод исчерпан, переменная назначена, и совпадение не выполнено & # 8212; не осталось ничего для последней точки с запятой вашего парсера.
Ответ Фреда создает новый синтаксический анализатор <=>, который соответствует всему, что делает <=>, кроме точек с запятой. " Сопоставить все, кроме X , а затем сопоставить X " является общим шаблоном, поэтому <=> предоставляется в качестве ярлыка для создания такого синтаксического анализатора. Документация предлагает использовать его для анализа комментариев в стиле C или Pascal, но это не обязательно.
Чтобы ваш код работал, Spirit должен был распознать, что жадность <=> слишком сильно совпадает, а затем вернуться , чтобы сопоставление было меньше. Но хотя Spirit будет возвращаться назад, он не будет возвращаться к & Quot; middle & Quot; о том, что в противном случае подпарасер жадно совпадет. Он вернется к следующей & Точке выбора, & Quot; но ваша грамматика не имеет. См. исчерпывающий поиск и жадность RD в документации Spirit.
Другие советы
Вы не получите удар, потому что ';' соответствует print_p. Попробуйте это:
parse(chars,
// Begin grammar
(
as_lower_d["//the description;"]
>> (+(print_p-';'))[assign(vDescription)]
>> ';'
),
// End grammar
space_p).hit)