![]() |
![]() ![]() ![]() ![]() ![]() |
![]() |
Warming upBoost , Spirit 2.5.2 , Tutorials
|
![]() | Note |
---|---|
Когда мы объединяем парсеры, мы в конечном итоге получаем «большой» парсер, но это все еще парсер. Парсеры могут становиться все больше и больше, гнездясь все больше и больше, но когда вы склеиваете два парсера вместе, вы в конечном итоге получаете один больший парсер. Это важная концепция. |
Создайте парсер, который будет принимать нулевые или более числа с плавающей точкой.
*double_
Это похоже на Kleene Star с регулярным выражением, хотя синтаксис может показаться немного странным для программиста C++, который не привык видеть перегруженного оператора<*
>. На самом деле, если вы знаете регулярные выражения, это может выглядеть странно, так как звезда находится перед выражением, которое она изменяет. С'ест ла Ви. Обвиняем его в том, что мы должны работать с синтаксическими правилами C++.
Любое выражение, которое оценивается парсером, может быть использовано со звездой Клин. Имейте в виду, что правила приоритета оператора C++ могут потребовать, чтобы вы помещали выражения в скобки для сложных выражений. Звезда Клин также известна как закрытие Клин, но мы называем ее звездой в большинстве мест.
Этот пример создаст парсер, который принимает список чисел, ограниченный запятой.
double_ >> *(char_(',') >> double_)
Уведомление<char_(',')
>. Это буквальный парсер символов, который может распознать запятую<','
>. В этом случае звезда Клин изменяет более сложный парсер, а именно тот, который генерируется выражением:
(char_(',') >> double_)
Обратите внимание, что это тот случай, когда скобки необходимы. Звезда Клин содержит полное выражение выше.
Мы закончили с определением парсера. Итак, следующий шаг теперь заключается в том, чтобы использовать этот парсер для выполнения своей работы. Есть несколько способов сделать это. Сейчас мы используем функцию<phrase_parse
>. Одна перегрузка этой функции принимает четыре аргумента:
В нашем примере мы хотим пропустить пробелы и вкладки. Другой парсер, названный<space
>, включен в репертуар Духа предопределенных парсеров. Это очень простой парсер, который просто распознает белое пространство. Мы будем использовать<space
>как наш пропуск парсер. Пропуск парсера - это тот, кто отвечает за пропуск символов между парсерными элементами, такими как<double_
>и<char_
>.
Хорошо, теперь давайте разберемся!
template <typename Iterator> bool parse_numbers(Iterator first, Iterator last) { using qi::double_; using qi::phrase_parse; using ascii::space; bool r = phrase_parse( first,last,
double_ >> *(',' >> double_),
space
); if (first != last) // fail if we did not get a full match return false; return r; }
Функция парса возвращается<true
>или<false
>в зависимости от результата парса. Первый итератор передается по ссылке. При успешном анализе этот итератор переставляется в правильную позицию, потребляемую парсером. Если это будет равно<last
>, то у нас будет полный матч. Если нет, то у нас частичный матч. Частичное совпадение происходит, когда парсер способен анализировать только часть входа.
Обратите внимание, что мы включили парсер непосредственно в призыв к разбору. При вызове парса выражение оценивает в временный, безымянный парсер, который передается в функцию парса, используется, а затем уничтожается.
Здесь мы решили сделать парсер общим, сделав его шаблоном, параметризованным по типу итератора. При этом он может принимать данные, поступающие из любой последовательности, соответствующей STL, до тех пор, пока итераторы соответствуют переднему итератору.
You can find the full cpp file here: ../../example/qi/num_list1.cpp
![]() | Note |
---|---|
< Внимательный читатель может заметить, что выражение парсера имеет< Проблема с пропуском< |
Наконец, обратите внимание, что мы тестируем на полное совпадение (т.е. парсер полностью парсировал вход), проверяя, равен ли первый итератор после парсинга конечному итератору. Вы можете вычеркнуть эту часть, если будут разрешены частичные матчи.
Статья Warming up раздела Spirit 2.5.2 Tutorials может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.
реклама |