本当は、セマンティックアクションでトークンを切り出すプログラムを作りたかったのだが、(*´Д`)
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;