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 Semantic Actionで各行の文字列を数える

Posted at

本当は、セマンティックアクションでトークンを切り出すプログラムを作りたかったのだが、(*´Д`)
Semantic Actionで各行の文字列をカウントするプログラムを作った。

↓セマンティックアクションの部分。


    14    struct MyAction
    15    {
    16        template
    17          void operator()( Ite i1, Ite i2 ) const
    18            { cout << "# of characters: " << i2 - i1 << endl    
    19                   << "string: " << string(i1,i2) << endl; }
    20    };

29行目で、任意の文字が続いたらMyAction()を呼び出す。


    27          definition( const Abc& self )
    28          {
    29            r = (*anychar_p)[MyAction()];
    30            // r_list = r % +blank_p;                                                                                                                                                 
    31            // r = (+alnum_p)[MyAction()] % ',';                                                                                                                                      
    32            //r = (+alnum_p >> blank_p)[MyAction()]; //' '; // blank_p;                                                                                                               
    33            // r = 'a' >> (*ch_p('b'))[MyAction()] >> 'c';                                                                                                                            
    34          }

コードを見てみる。。。

 1#include <iostream>
 2#include <string>
 3#include <vector>
 4#include <fstream>
 5
 6#include <boost/spirit.hpp>
 7#include <boost/lambda/lambda.hpp>
 8#include <boost/lambda/bind.hpp>
 9using namespace std;
10using namespace boost::spirit;
11
12struct Abc : grammar<Abc>
13{
14    struct MyAction
15    {
16        template<typename Ite>
17          void operator()( Ite i1, Ite i2 ) const
18            { cout << "# of characters: " << i2 - i1 << endl    
19                   << "string: " << string(i1,i2) << endl; }
20    };
21
22    template<typename ScannerT>
23      struct definition
24      {
25          typedef rule<ScannerT> rule_t;
26          rule_t r; rule_t r_list;
27          definition( const Abc& self )
28          {
29            r = (*anychar_p)[MyAction()];
30            // r_list = r % +blank_p;                                                                                                                                                 
31            // r = (+alnum_p)[MyAction()] % ',';                                                                                                                                      
32            //r = (+alnum_p >> blank_p)[MyAction()]; //' '; // blank_p;                                                                                                               
33            // r = 'a' >> (*ch_p('b'))[MyAction()] >> 'c';                                                                                                                            
34          }
35          const rule_t& start() const { return r; }
36      };
37};
38
39/*                                                                                                                                                                                    
40int main()                                                                                                                                                                            
41{                                                                                                                                                                                     
42    for( string line; cout<<"# ", getline(cin, line); )                                                                                                                               
43        if( parse( line.begin(), line.end(), Abc() ).full );                                                                                                                          
44    return 0;                                                                                                                                                                         
45}                                                                                                                                                                                     
46*/
47
48#include <typeinfo>
49int main(int argc, char* argv[]){
50    using namespace std;
51
52    if(argc != 2){
53        cerr << "wrong # of args." << endl;
54        cerr << "./spirit_file_read input.txt" << endl;
55        return 1;
56    }
57
58    ifstream ifs(argv[1], ios::in);
59    if(!ifs){
60        cerr << "Error: file not opened." << endl;
61        return 1;
62    }
63
64    string tmp;
65    string str;
66
67    int counter = 0;
68
69    Abc parser;
70
71    while(getline(ifs, tmp)){
72
73        cout << "line:" << counter << ":" << tmp << endl;
74
75        parse_info<string::const_iterator> info =
76        parse( tmp.begin(), tmp.end(), Abc() );
77        cout << (info.full ? "OK" : "") << endl;
78
79        counter++;
80    }
81
82    ifs.close();
83    return 0;
84}

今回はこのようなファイルを処理してみる。

 1int main
 2FILE* fp = fopen(FILENAME, "r");
 3if (fp == NULL)
 4    exit(EXIT_FAILURE);
 5char* line = NULL;
 6size_t len = 0;
 7while ((getline(&line, &len, fp)) != -1) {
 8    // using printf() in all tests for consistency                                                                                                                                    
 9    printf("%s", line);
10}
11fclose(fp);
12if (line)
13free(line);

実行してみる。。。


$ g++ spirit_file_read_3.cpp -lboost_system
In file included from spirit_file_read_3.cpp:6:0:
/usr/include/boost/spirit.hpp:18:4: warning: #warning "This header is deprecated. Please use: boost/spirit/include/classic.hpp" [-Wcpp]
 #  warning "This header is deprecated. Please use: boost/spirit/include/classic.hpp"
    ^~~~~~~
$ ./a.out getline.c
line:0:int main
# of characters: 8
string: int main
OK
line:1:FILE* fp = fopen(FILENAME, "r");
# of characters: 32
string: FILE* fp = fopen(FILENAME, "r");
OK
line:2:if (fp == NULL)
# of characters: 15
string: if (fp == NULL)
OK
line:3:    exit(EXIT_FAILURE);
# of characters: 23
string:     exit(EXIT_FAILURE);
OK
line:4:char* line = NULL;
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?