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