-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathboost_spirite_07_CDISM_STUDY.cpp
197 lines (176 loc) · 4.91 KB
/
boost_spirite_07_CDISM_STUDY.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#include <iostream>
#include <string>
#include <vector>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/bind.hpp>
// Qi Sample 1
#define GENERAL_TEST (0)
#define PASER_SEMANTIC_ACTIONS (1)
#define HOW_TO_USE_THE_SUM (2)
#define HOW_TO_USE_THE_DETAIL_LIST (3)
#define HOW_TO_USE_THE_FUNCTION (4)
#define HOW_TO_USE_THE_FUNCTOR (5)
#define HOW_TO_USE_THE_ARTTRIBUTE_CODE (6)
#define SELECT_ITEM (HOW_TO_USE_THE_ARTTRIBUTE_CODE)
namespace client {
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace phoenix = boost::phoenix;
//Context pass:bool
void raw_print(double & val, qi::unused_type, qi::unused_type) {
std::cout << "raw function : " << val << std::endl;
}
void print(double & val) {
std::cout << "normal iterator : " << val << std::endl;
}
struct print_object {
void operator()(double & val) const
{
std::cout << "functor call : " << val << std::endl;
}
};
struct print_object2 {
void print(double & val) const
{
std::cout << "member function :" << val << std::endl;
}
};
template<typename iterator>
bool parse_process(iterator first, iterator last) {
if (first == last) return false;
using qi::double_;
using qi::char_;
using ascii::space;
using qi::phrase_parse;
using qi::_1;
using phoenix::push_back;
auto skip_parser = space;
#if SELECT_ITEM == GENERAL_TEST
auto today_parser0 = double_ >> *(char_(',') >> double_);
//24.5
//24.5 78.9 1,2,3
#elif SELECT_ITEM == PASER_SEMANTIC_ACTIONS
//Paser Semantic Actions
auto boost_actor1 = std::cout << _1 << std::endl;
auto today_parser1 = double_[boost_actor1] % char_(',');
#elif SELECT_ITEM == HOW_TO_USE_THE_SUM
//how to sum
double sum = 0.0;
auto init_actor = (phoenix::ref(sum) = _1);
auto add_actor = (phoenix::ref(sum) += _1);
auto today_parser2 = double_[init_actor] >> *(char_(',') >> double_[add_actor]);
auto last2 = [&]() {std::cout << "sum : " << sum << std::endl; };
#elif SELECT_ITEM == HOW_TO_USE_THE_DETAIL_LIST
//how to data list
std::vector<double> datas;
auto push_back_actor = push_back(phoenix::ref(datas), _1);
auto today_parser3 = double_[push_back_actor] >> *(char_(',') >> double_[push_back_actor]);
auto last3 = [&]() {
std::cout << "data list : " << std::endl;
for (auto & mitem : datas) {
std::cout << mitem << std::endl;
}
};
#elif SELECT_ITEM == HOW_TO_USE_THE_FUNCTION
//how to use the function
auto & fn1 = raw_print;
auto & fn2 = print;
auto & today_parser4 = double_[&fn1] >> *(char_(',') >> double_[&fn2]);
auto last4 = [&]() {std::cout << std::endl; };
#elif SELECT_ITEM == HOW_TO_USE_THE_FUNCTOR
//how to use the functor
auto func_obj = print_object();
auto obj2 = print_object2();
auto mem_fn = boost::bind(&print_object2::print ,&obj2, ::_1);//바인드가 정의한 플래스홀더를 사용해야함 qi가 만든것 사용 안됨 (X)
auto today_parser5 = double_[func_obj] >> *(char_(',') >> double_[mem_fn]);
auto last5 = [&]() {std::cout << std::endl; };
#elif SELECT_ITEM == HOW_TO_USE_THE_ARTTRIBUTE_CODE
// 아래와 같은 attribute code는 최적의 코드라고 함.
// 여태 위에서 작성된 방법은 최대한 사용을 하지않도록 지양 해야함.
std::vector<double> attrs;
auto today_parser6 = double_ % char_(',');
auto last6 = [&]() {
std::cout << "attrs list: " << std::endl;
for (auto & mitem : attrs) {
std::cout << mitem << std::endl;
}
};
#else
#endif
#if SELECT_ITEM == GENERAL_TEST
bool resuit = phrase_parse(
first, last,
today_parser0,
skip_parser
);
#elif SELECT_ITEM == PASER_SEMANTIC_ACTIONS
bool resuit = phrase_parse(
first, last,
today_parser1,
skip_parser
);
#elif SELECT_ITEM == HOW_TO_USE_THE_SUM
bool resuit = phrase_parse(
first, last,
today_parser2,
skip_parser
);
#elif SELECT_ITEM == HOW_TO_USE_THE_DETAIL_LIST
bool resuit = phrase_parse(
first, last,
today_parser3,
skip_parser
);
#elif SELECT_ITEM == HOW_TO_USE_THE_FUNCTION
bool resuit = phrase_parse(
first, last,
today_parser4,
skip_parser
);
#elif SELECT_ITEM == HOW_TO_USE_THE_FUNCTOR
bool resuit = phrase_parse(
first, last,
today_parser5,
skip_parser
);
#else
bool resuit = phrase_parse(
first, last,
today_parser6,
skip_parser,
attrs
);
#endif
if (first != last) return false; //partial match deny\
#if SELECT_ITEM == HOW_TO_USE_THE_SUM
last2();
#elif SELECT_ITEM == HOW_TO_USE_THE_DETAIL_LIST
last3();
#elif SELECT_ITEM == HOW_TO_USE_THE_FUNCTION
last4();
#elif SELECT_ITEM == HOW_TO_USE_THE_FUNCTOR
last5();
#else
last6();
#endif
return true; // full match
}
}
int main()
{
std::string cmd;
while (getline(std::cin, cmd))
{
if (cmd.empty() || cmd[0] == 'q' || cmd[0] == 'Q') break;
if (client::parse_process(std::begin(cmd), std::end(cmd)))
{
std::cout << std::endl << "Parsing OK" << std::endl;
}
else
{
std::cout << std::endl << "Parsing FAIL" << std::endl;
}
}
return 0;
}