1
+ #include " HandlerParser.h"
2
+ #include < iostream>
3
+ #include < regex>
4
+
5
+ using namespace drogon ::internal;
6
+
7
+ std::pair<std::string, std::string> StructNode::findContentOfClassOrNameSpace (
8
+ const std::string &content,
9
+ std::string::size_type start)
10
+ {
11
+ int braces = 0 ;
12
+ std::string::size_type pos1{start};
13
+ std::string::size_type pos2{content.size () - 1 };
14
+ for (auto i = start; i < content.size (); i++)
15
+ {
16
+ if (content[i] == ' {' )
17
+ {
18
+ braces++;
19
+ if (braces == 1 )
20
+ {
21
+ pos1 = i + 1 ;
22
+ }
23
+ }
24
+ else if (content[i] == ' }' )
25
+ {
26
+ braces--;
27
+ if (braces == 0 )
28
+ {
29
+ pos2 = i;
30
+ break ;
31
+ }
32
+ }
33
+ }
34
+ return std::pair<std::string, std::string>(content.substr (pos1,
35
+ pos2 - pos1),
36
+ content.substr (pos2 + 1 ));
37
+ }
38
+ std::pair<StructNodePtr, std::string> StructNode::findClass (
39
+ const std::string &content)
40
+ {
41
+ LOG_DEBUG << " findClass: " << content;
42
+ if (content.empty ())
43
+ return std::pair<StructNodePtr, std::string>(nullptr , " " );
44
+ std::regex rx (R"( class[ \r\n]+([^ \r\n\{]+)[ \r\n\{:]+)" );
45
+ std::smatch results;
46
+ if (std::regex_search (content, results, rx))
47
+ {
48
+ assert (results.size () > 1 );
49
+ auto nextPart =
50
+ findContentOfClassOrNameSpace (content, results.position ());
51
+ return std::pair<StructNodePtr, std::string>(
52
+ std::make_shared<StructNode>(nextPart.first ,
53
+ results[1 ].str (),
54
+ kClass ),
55
+ nextPart.second );
56
+ }
57
+ return std::pair<StructNodePtr, std::string>(nullptr , " " );
58
+ }
59
+ std::tuple<std::string, StructNodePtr, std::string> StructNode::findNameSpace (
60
+ const std::string &content)
61
+ {
62
+ LOG_DEBUG << " findNameSpace" ;
63
+ if (content.empty ())
64
+ return std::tuple<std::string, StructNodePtr, std::string>(" " ,
65
+ nullptr ,
66
+ " " );
67
+ std::regex rx (R"( namespace[ \r\n]+([^ \r\n]+)[ \r\n]*\{)" );
68
+ std::smatch results;
69
+ if (std::regex_search (content, results, rx))
70
+ {
71
+ assert (results.size () > 1 );
72
+ auto pos = results.position ();
73
+ auto first = content.substr (0 , pos);
74
+ auto nextPart = findContentOfClassOrNameSpace (content, pos);
75
+ auto npNodePtr = std::make_shared<StructNode>(nextPart.first ,
76
+ results[1 ].str (),
77
+ kNameSpace );
78
+
79
+ return std::tuple<std::string, StructNodePtr, std::string>(
80
+ first, npNodePtr, nextPart.second );
81
+ }
82
+ else
83
+ {
84
+ return std::tuple<std::string, StructNodePtr, std::string>(" " ,
85
+ nullptr ,
86
+ " " );
87
+ }
88
+ }
89
+ std::vector<StructNodePtr> StructNode::parse (const std::string &content)
90
+ {
91
+ std::vector<StructNodePtr> res;
92
+ auto t = findNameSpace (content);
93
+ if (std::get<1 >(t))
94
+ {
95
+ res.emplace_back (std::get<1 >(t));
96
+ auto firstPart = std::get<0 >(t);
97
+ while (1 )
98
+ {
99
+ auto p = findClass (firstPart);
100
+ if (p.first )
101
+ {
102
+ res.emplace_back (p.first );
103
+ firstPart = p.second ;
104
+ }
105
+ else
106
+ {
107
+ break ;
108
+ }
109
+ }
110
+ auto subsequentNode = parse (std::get<2 >(t));
111
+ for (auto &node : subsequentNode)
112
+ {
113
+ res.emplace_back (node);
114
+ }
115
+ return res;
116
+ }
117
+ std::string classPart = content;
118
+ while (1 )
119
+ {
120
+ auto p = findClass (classPart);
121
+ if (p.first )
122
+ {
123
+ res.emplace_back (p.first );
124
+ classPart = p.second ;
125
+ }
126
+ else
127
+ {
128
+ break ;
129
+ }
130
+ }
131
+ return res;
132
+ }
133
+ void StructNode::print (int indent) const
134
+ {
135
+ std::string ind (indent, ' ' );
136
+ std::cout << ind;
137
+ switch (type_)
138
+ {
139
+ case kRoot :
140
+ {
141
+ std::cout << " Root\n " << ind << " {\n " ;
142
+ break ;
143
+ }
144
+ case kClass :
145
+ {
146
+ std::cout << " class " << name_ << " \n " << ind << " {\n " ;
147
+ break ;
148
+ }
149
+ case kNameSpace :
150
+ {
151
+ std::cout << " namespace " << name_ << " \n " << ind << " {\n " ;
152
+ break ;
153
+ }
154
+ }
155
+
156
+ for (auto child : children_)
157
+ {
158
+ child->print (indent + 2 );
159
+ }
160
+ if (type_ == kClass )
161
+ {
162
+ std::cout << content_ << " \n " ;
163
+ }
164
+ std::cout << ind << " }" ;
165
+ if (type_ == kClass )
166
+ std::cout << " ;" ;
167
+ std::cout << " \n " ;
168
+ }
0 commit comments