-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathboost_spirite_08_CDISM_STUDY.cpp
157 lines (138 loc) · 3.45 KB
/
boost_spirite_08_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
#include <iostream>
#include <string>
#include <vector>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/bind.hpp>
// Qi Sample 2
namespace client {
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace phoenix = boost::phoenix;
//char 를 unsigned 로 매핑한다는 의미로 사용
//이 기술 용어는 symbol table 이라 한다.
struct ones_ : qi::symbols<char, unsigned> { // first::charactor type => second::attribute
ones_() {
this->add
("I", 1)
("II", 2)
("III", 3)
("IV", 4)
("V", 5)
("VI", 6)
("VII", 7)
("VIII", 7)
("IX", 9);
}
}ones;
struct tens_ : qi::symbols<char, unsigned> { // first::charactor type => second::attribute
tens_() {
add
("X", 10)
("XX", 20)
("XXX", 30)
("XL", 40)
("L", 50)
("LX", 60)
("LXX", 70)
("LXXX", 80)
("XC", 90);
}
}tens;
struct hundreds_ : qi::symbols<char, unsigned> { // first::charactor type => second::attribute
hundreds_() {
add
("C", 100)
("CC", 200)
("CCC", 300)
("CD", 400)
("D", 500)
("DC", 600)
("DCC", 700)
("DCCC", 800)
("CM", 900);
}
}hundreds;
template<typename iterator>
struct roman : qi::grammar<iterator, unsigned()>//container parser // composite design pattern
{
roman() : roman::base_type(start, "roman grammer")
{
using qi::eps;
using qi::lit;
using qi::_val;
/*
_val is another Phoenix placeholder representing the rule's synthesized attribute
_r1 ...r10 These Phoenix placeholder refer to the Nonterminal's inherited attributes.
*/
using qi::_1;
start = eps[_val = 0] >>
(
lit('M')[_val += 1000] ||
hundreds[_val += _1] ||
tens[_val += _1] ||
ones[_val += _1]
);
}
qi::rule<iterator, unsigned()> start;
};
template<typename iterator>
bool parse_process(iterator first, iterator last) {
if (first == last) return false;
using qi::lit;
using qi::phrase_parse;
using qi::_1;
using qi::eps;//parser => 파싱 하기전에 초기화 하고 파싱 끝나고 나서도 초기화에 사용한다. 수학 입실론에 의미를 부여한것.
using ascii::space;
using phoenix::ref;
auto skip_parser = space;
// #1
unsigned int val1 = 0;
auto today_parse1 = eps[phoenix::ref(val1) = 0] >> *(
ones[phoenix::ref(val1) += _1] ||
tens[phoenix::ref(val1) += _1] ||
hundreds[phoenix::ref(val1) += _1] ||
lit("M")[phoenix::ref(val1) += 1000]);
auto last1 = [&]() {std::cout << val1 << std::endl; };
// #2
unsigned int val2 = 0;
roman<iterator> roman_parser2;
auto today_parser2 = *(roman_parser2[phoenix::ref(val2) += _1]);
auto last2 = [&]() {std::cout << val2 << std::endl; };
// #3
std::vector<unsigned int> datas;
roman<iterator> roman_parser3;
auto last3 = [&]() {
std::cout << "data list : " << std::endl;
for (auto && mitem : datas) {
std::cout << mitem << std::endl;
}
};
bool result = phrase_parse(
first, last,
*roman_parser3,
skip_parser,
datas
);
if (first != last) return false; //partial match deny
last3();
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;
}