Boost Semantic Actionからコンテナー(vector)に値を格納する


Boost Semantic Actionの関数からコンテナ(今回はベクター)にアクセスすることができる。

11std::vector<string> v;

13struct AddrParse : grammar<AddrParse>
14{
15    struct MyAction
16    {
17        template<typename Ite>
18          void operator()( Ite i1, Ite i2 ) const
19            { cout << "文字数:" << i2 - i1 << endl
20                   << " 内容:" << string(i1,i2) << endl;
21              v.push_back(string(i1,i2));
22            }
23    };
24
25    template<typename ScannerT>
26      struct definition
27      {
28          typedef rule<ScannerT> rule_t;
29          rule_t r;
30          definition( const AddrParse& self )
31          {
32            // r = 'a' >> (*ch_p('b'))[MyAction()] >> 'c';                                                                                                                            
33            r = (int_p >> '.' >> int_p >> '.' >> int_p >> '.' >> int_p)[MyAction()]; // >> +( '*' >> int_p );                                                                         
34          }
35          const rule_t& start() const { return r; }
36      };
37};

+c++
21 v.push_back(string(i1,i2));
33 r = (int_p >> '.' >> int_p >> '.' >> int_p >> '.' >> int_p)[MyAction()]; // >> +( '*' >> int_p );
+

33行目で、セマンティックアクションの関数MyAction()を呼び出し、21行目でベクトルにパースした文字列を格納している。

パース後のベクターの表示は、よくやる方法で、イテレータを使う。

+c++
103 for(auto itr = v.begin(); itr != v.end(); ++itr) {
104 cout << string(*itr) << endl;
105 }
+

コードを見てみる。。。

 1#include <iostream>
 2#include <fstream>
 3#include <sstream>
 4#include <string>
 5#include <boost/spirit.hpp>     6#include <boost/tokenizer.hpp>
 7
 8using namespace std;
 9using namespace boost::spirit;
10
11std::vector<string> v;
12
13struct AddrParse : grammar<AddrParse>
14{
15    struct MyAction
16    {
17        template<typename Ite>
18          void operator()( Ite i1, Ite i2 ) const
19            { cout << "文字数:" << i2 - i1 << endl
20                   << " 内容:" << string(i1,i2) << endl;
21              v.push_back(string(i1,i2));
22            }
23    };
24
25    template<typename ScannerT>
26      struct definition    27      {
28          typedef rule<ScannerT> rule_t;
29          rule_t r;
30          definition( const AddrParse& self )
31          {
32            // r = 'a' >> (*ch_p('b'))[MyAction()] >> 'c';                                                                                                                            
33            r = (int_p >> '.' >> int_p >> '.' >> int_p >> '.' >> int_p)[MyAction()]; // >> +( '*' >> int_p );                                                                         
34          }
35          const rule_t& start() const { return r; }
36      };
37};
38  
39std::vector < std::vector< std::string > > parse_csv(const char* filepath)
40{
41    std::vector< std::vector< std::string > > cells;
42    std::string line;
43    std::ifstream ifs(filepath);
44
45    while (std::getline(ifs, line)) {
46
47        std::vector< std::string > data;
48
49        boost::tokenizer< boost::escaped_list_separator< char > > tokens(line);
50        for (const std::string& token : tokens) {
51            data.push_back(token);
52        }
53
54        cells.push_back(data);
55    }
56
57    return cells;
58}

実行してみる(IPアドレスの値はランダムに生成)


$ g++ -o random_data random_data.cpp
$ ./random_data 3

$ cat random_data.txt 
"2019/07/02 02:02:00.839","2019/07/02 02:02:00","2019/07/02 02:02:00","841",".178.167.132","25846","iy",".215.218.225","51321","bu","8MP","VX13Gpdkt","drN","deETa","gyAY4gdZ","8","TJoPPQuOKvrxzAjCd11rpqqSqs","912","198","336","769","278","554","rand-pa1"
"2019/07/02 02:02:52.006","2019/07/02 02:02:52","2019/07/02 02:02:52","478",".40.197.93","41214","ol",".213.36.241","23907","Vu","OYF","H6zQlnN5X","yV3","P2VPw","9D3viFsS","5","cogAhSIycmvdYl7RaZNjGCsWqj","953","917","636","718","142","607","rand-pa1"
"2019/07/02 12:12:16.086","2019/07/02 12:12:16","2019/07/02 12:12:16","17",".175.225.23","15918","Hk",".156.36.246","8994","u1","Tt2","hihIKl4xd","OX5","uj8uP","hKwtE4iF","8","9EuzqcBTUrBjAago2vY5MMugKb","157","401","130","109","999","219","rand-pa1"

$ ./a.out random_data.txt 
文字数:15
 内容:255.178.167.132
line:0 255.178.167.132
文字数:14
 内容:69.215.218.225
line:0 69.215.218.225
文字数:13
 内容:104.40.197.93
line:1 104.40.197.93
文字数:13
 内容:76.213.36.241
line:1 76.213.36.241
文字数:14
 内容:120.175.225.23
line:2 120.175.225.23
文字数:13
 内容:55.156.36.246
line:2 55.156.36.246

(`ー´)b