Я анализирую текстовый файл, возможно, размером несколько ГБ, состоящий из следующих строк:
11 0.1
14 0.78
532 -3.5
В основном, один int и один float на строку.Интты должны быть упорядоченными и неотрицательными.Я хотел бы убедиться, что данные соответствуют описанию и вернули мне минимальное и максимальное значения int в диапазоне.Вот что я придумал:
#include <iostream>
#include <string>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/std_pair.hpp>
namespace px = boost::phoenix;
namespace qi = boost::spirit::qi;
namespace my_parsers
{
using namespace qi;
using px::at_c;
using px::val;
template <typename Iterator>
struct verify_data : grammar<Iterator, locals<int>, std::pair<int, int>()>
{
verify_data() : verify_data::base_type(section)
{
section
= line(val(0)) [ at_c<0>(_val) = _1]
>> +line(_a) [ _a = _1]
>> eps [ at_c<1>(_val) = _a]
;
line
%= (int_ >> other) [
if_(_r1 >= _1)
[
std::cout << _r1 << " and "
<< _1 << val(" out of order\n")
]
]
;
other
= omit[(lit(' ') | '\t') >> float_ >> eol];
}
rule<Iterator, locals<int>, std::pair<int, int>() > section;
rule<Iterator, int(int)> line;
rule<Iterator> other;
};
}
using namespace std;
int main(int argc, char** argv)
{
string input("11 0.1\n"
"14 0.78\n"
"532 -3.6\n");
my_parsers::verify_data<string::iterator> verifier;
pair<int, int> p;
std::string::iterator begin(input.begin()), end(input.end());
cout << "parse result: " << boolalpha
<< qi::parse(begin, end, verifier, p) << endl;
cout << "p.first: " << p.first << "\np.second: " << p.second << endl;
return 0;
}
Что я хотел бы знать, это следующее:
- Есть ли лучший способ сделать это?Я использовал унаследованные и синтезированные атрибуты, локальные переменные и немного феникса вуду.Это замечательно;изучение инструментов - это хорошо, но я не могу не думать, что может быть гораздо более простой способ достичь того же: / (в PEG-парсере, который ...)
- Как это можно сделать без локальной переменной дляпример?
Дополнительная информация: У меня есть другие форматы данных, которые анализируются одновременно, и поэтому я хотел бы сохранить возвращаемое значение в качестве атрибута синтаксического анализатора.На данный момент это std :: pair, другие форматы данных при анализе разбираются, например, со своими собственными std :: pair, и именно эти я хотел бы вставить в std :: vector.