0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Boost Spirit V2のSpirit.Qiについて少し調べた

Posted at

Spirit V2は、Spirit.Qi, Spirit.Karma, Spirit.Lexの三つ巴で紹介されることが多いが、Spirit.Karma, Spirit.Lexは使ったことがないので、Spirit.Qiを調べることにする。

Spirit.Qiは、単純に言うとパーサーである。

さらに端的には、qi::parseとqi::phrase_parseの2つがある。

qi::phrase_parseは、qi::ruleやqi::grammerで拡張可能であり、この時になると、EBNF然にかけるSpirit.Qiが本領を発揮するらしい。(-ω- )o<

+c++ qi::parse(it, str.end(), int_ % ',', result) && it==str.end(); +

↑ 1文字(この場合は整数)のパース

+c++ qi::phrase_parse(it, str.end(), +( "x:" >> double_ >> "y:" >> double_ ), +

↑ 2文字以上のパース
+(...) の「+」は、一文字以上の文字の繰り返しという意味。

コードを見てみる。。。

+c++ qi::parse(it, str.end(), int_ % ',', result) && it==str.end(); +

 1#include <iostream>
 2#include <string>
 3#include <vector>
 4#include <boost/fusion/tuple.hpp>
 5#include <boost/spirit/include/qi.hpp>
 6#include <boost/spirit/include/phoenix.hpp>
 7using namespace std;
 8using namespace boost;
 9using namespace boost::spirit;
10
11bool parse_csv( const string& str, std::vector<int>& result )
12{
13  string::const_iterator it = str.begin();
14  return qi::parse(it, str.end(), int_ % ',', result) && it==str.end();
15}
16
17int main()
18{
19  {
20    std::vector<int> result;
21    if( parse_csv( "4,2,7", result ) )
22      cout << result.size() << " integers parsed" << endl;
23    else
24      cout << "error" << endl;
25  }
26  {
27    std::vector<int> result;
28    if( parse_csv( "9 6 5", result ) ) 
29      cout << result.size() << " integers parsed" << endl;
30    else
31      cout << "error" << endl;
32  }
33}

実行してみる。。。


$ ./a.out 
3 integers parsed
error

+c++ qi::phrase_parse(it, str.end(), +( "x:" >> double_ >> "y:" >> double_ ), +

コードを見てみる。。。

 1#include <iostream>
 2#include <string>
 3#include <vector>
 4#include <boost/fusion/tuple.hpp>
 5#include <boost/spirit/include/qi.hpp>
 6#include <boost/spirit/include/phoenix.hpp>
 7using namespace std;
 8using namespace boost;
 9using namespace boost::spirit;
10
11bool parse_points( const string& str, std::vector< fusion::tuple<double,double> >& result )
12{
13  string::const_iterator it = str.begin();
14  return qi::phrase_parse(it, str.end(),
15                          +( "x:" >> double_ >> "y:" >> double_ ),
16                          ascii::space,
17                          result
18                          ) && it==str.end();
19}
20
21int main()
22{
23  std::vector<int> result;
24  {
25    std::vector< fusion::tuple<double,double> > result;
26    if( parse_points( "x: 1 y: 2.0 x: 3 y: -4.5", result ) )
27      cout << result.size() << " points parsed" << endl;
28    else
29      cout << "error" << endl;
30  }
31}

実行してみる。。。


$ ./a.out 
2 points parsed
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?