PhoenixGenerator  3.4.0
Generate code from template files and projects in C++, Rust, Python and wrapped C++ to Python
Loading...
Searching...
No Matches
parserClassConfig.cpp
Go to the documentation of this file.
1
2/***************************************
3 Auteur : Pierre Aubert
4 Mail : pierre.aubert@lapp.in2p3.fr
5 Licence : LGPL-3.0-only
6****************************************/
7
8#include <iostream>
10#include "parserClassConfig.h"
11
13
16void errorUnexpectedToken(const PFileParser & parser, const PString & token){
17 std::cerr << "errorUnexpectedToken : '" << parser.getFileName() << "' line " << parser.getLine() << std::endl;
18 std::cerr << "unexpected token '" << token << "'" << std::endl;
19}
20
22
25PString getClassName(PFileParser & parser){
26 PString name = parser.getStrComposedOf("_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
27 while(parser.isMatch("::")){
28 name += "::" + parser.getStrComposedOf("_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
29 }
30 return name;
31}
32
34
38bool updateCurrentComment(PFileParser & parser, PString & currentComment){
39 if(parser.isMatch("//")){
40 if(currentComment != ""){currentComment += "\n";}
41 currentComment += "//" + parser.getUntilKeyWithoutPatern("\n");
42 }else if(parser.isMatch("/*")){
43 if(currentComment != ""){currentComment += "\n";}
44 currentComment += "/*" + parser.getUntilKey("*/");
45 }else{
46 return false;
47 }
48 return true;
49}
50
52
56bool updateCurrentTemplate(PFileParser & parser, PVecString & currentTemplate){
57 if(!parser.isMatch("template")){return false;}
58 if(!parser.isMatch("<")){return false;}
59
60 currentTemplate = parser.getUntilKeyWithoutPaternRecurse(">", "<").split(',');
61
62 return true;
63}
64
66
71bool parseClassConfigAttribut(PClassConfig & config, PFileParser & parser, PString & currentComment){
72 parser.skipWhiteSpace();
73 PString attribut(parser.getUntilKeyWithoutPatern(";").eraseChar("\n"));
74 PString defaultValue("");
75 size_t bracePos(attribut.findPatternIndex("{"));
76 if(bracePos != attribut.size()){
77 defaultValue = PString(attribut.substr(bracePos)).eraseFirstLastChar(" \n\t");
78 attribut = attribut.substr(0, bracePos);
79 }
80 PVecString listToken(attribut.split(" \n\t"));
81 PString attributName(listToken.back());
82 listToken.pop_back();
83 PString attributType("");
84 for(PVecString::iterator it(listToken.begin()); it != listToken.end(); ++it){
85 attributType += *it + " ";
86 }
87 attributType = attributType.eraseFirstLastChar(" \n\t");
88 PClassAttribute attr(createClassAttribute(attributType, attributName, currentComment));
89 if(defaultValue != ""){attr.setDefaultValue(defaultValue);}
90 config.addAttribute(attr);
91 currentComment = "";
92 return true;
93}
94
96
100bool parseParentOfClassConfig(PClassConfig & config, PFileParser & parser){
101 if(!parser.isMatch("(")) return true;
102
103 while(!parser.isEndOfFile() && parser.isMatch(")")){
104 PString parentDef(getClassName(parser));
105 if(parentDef == ""){
106 break;
107 }
108 config.addParentClass(parentDef);
109 if(parser.isMatch(")")){break;}
110
111 if(!parser.isMatch(",")){
112 errorUnexpectedToken(parser, parser.getNextToken());
113 return false;
114 }
115 }
116 return true;
117}
118
120
125bool parseEnumValue(PClassConfig & config, PFileParser & parser, PString & currentComment){
126 PString enumValue(getClassName(parser)), value("");
127 if(!parser.isMatch("=")){
128 value = parser.getStrComposedOf("0123456789xu");
129 }
130 PClassAttribute attr(createClassAttribute("int /* just to remember*/", enumValue, currentComment));
131 attr.setDefaultValue(value);
132 config.addAttribute(attr);
133 currentComment = "";
134 parser.isMatch(","); //We consume the comma if there is one
135 return true;
136}
137
139
144bool parseEnumConfig(std::vector<PClassConfig> & listClassConfig, PFileParser & parser, PString & currentComment){
145 if(!parser.isMatchToken("enum")){return false;}
146 PClassConfig config;
147 config.setIsEnum(true);
148 PString enumName(getClassName(parser)); //Get the name of the enum
149 std::cout << "parseEnumConfig : find enum : '"<<enumName<<"'" << std::endl;
150 config.setName(enumName);
151 config.setClassDocumentation(currentComment);
152 currentComment = "";
153 parser.skipWhiteSpace();
154 if(!parser.isMatch("{")){
155 errorUnexpectedToken(parser, parser.getNextToken());
156 std::cerr << "\tExpect '{' after enum name '"<<enumName<<"'" << std::endl;
157 return false;
158 }
159 bool searchingData(true);
160 while(!parser.isEndOfFile() && searchingData && !parser.isMatch("}")){
161 if(updateCurrentComment(parser, currentComment)){}
162 else{ //Si ce n'est pas un séparateur, c'est que l'on a trouvé un nom, de PDataGroup ou de PDataVar ou PDataTable
163 if(!parseEnumValue(config, parser, currentComment)){
164 errorUnexpectedToken(parser, parser.getNextToken());
165 return false;
166 }
167 }
168 }
169 listClassConfig.push_back(config);
170 return true;
171}
172
174
180bool parsePClassConfig(std::vector<PClassConfig> & listClassConfig, PFileParser & parser, PString & currentComment, PVecString & listTemplate){
181 PClassConfig config;
182 PString fullName(getClassName(parser));
183 size_t separator = fullName.rfind("::");
184 PString className, namespaceName;
185 if(separator != PString::npos){
186 className = fullName.substr(separator + 2);
187 namespaceName = fullName.substr(0, separator);
188 std::cout << "parsePClassConfig : find namespaceName : '"<<namespaceName<<"'" << std::endl;
189 }else{
190 className = fullName;
191 }
192 std::cout << "parsePClassConfig : find className : '"<<className<<"'" << std::endl;
193 config.setName(className);
194 config.setNamespace(namespaceName);
195 config.setClassDocumentation(currentComment);
196 config.setListTemplate(listTemplate);
197 currentComment = "";
198 listTemplate.clear();
199 parser.skipWhiteSpace();
200
201 if(!parseParentOfClassConfig(config, parser)){
202 std::cerr << "parsePClassConfig : file '" << parser.getFileName() << "' line " << parser.getLine() << std::endl;
203 std::cerr << "\tmissing ')' : can't parse parents of the class '"<<config.getName()<<"'" << std::endl;
204 }
205 if(parser.isEndOfFile()){
206 std::cerr << "parsePClassConfig : file '" << parser.getFileName() << "' line " << parser.getLine() << std::endl;
207 std::cerr << "\tmissing '}'" << std::endl;
208 return false;
209 }
210 if(!parser.isMatch("{")){
211 errorUnexpectedToken(parser, parser.getNextToken());
212 std::cerr << "\tExpect '{' after class name '"<<className<<"'" << std::endl;
213 return false;
214 }
215
216 bool searchingData(true);
217 while(!parser.isEndOfFile() && searchingData && !parser.isMatch("}")){
218 if(updateCurrentComment(parser, currentComment)){}
219 else{ //Si ce n'est pas un séparateur, c'est que l'on a trouvé un nom, de PDataGroup ou de PDataVar ou PDataTable
220 if(!parseClassConfigAttribut(config, parser, currentComment)){
221 errorUnexpectedToken(parser, parser.getNextToken());
222 return false;
223 }
224 }
225 }
226 listClassConfig.push_back(config);
227 return true;
228}
229
231
236bool parserClassConfig(std::vector<PClassConfig> & listClassConfig, PVecPath & listInclude, const PPath & fileName){
237 if(fileName == "") return false;
238 PFileParser parser;
239 parser.setWhiteSpace(" \t\n");
240 parser.setSeparator("{};/*");
241 if(!parser.open(fileName)) return false;
242 PString currentComment("");
243 PVecString listTemplate;
244 while(!parser.isEndOfFile()){
245 if(parser.isMatch("#")){
246 if(parser.isMatch("include")){
247 listInclude.push_back(parser.getUntilKeyWithoutPatern("\n").eraseChar(" \t\n"));
248 }
249 }else if(updateCurrentComment(parser, currentComment)){}
250 else if(updateCurrentTemplate(parser, listTemplate)){}
251 else if(parseEnumConfig(listClassConfig, parser, currentComment)){}
252 else{ //Si ce n'est pas un séparateur, c'est que l'on a trouvé un nom, de PClassConfig
253 if(!parsePClassConfig(listClassConfig, parser, currentComment, listTemplate)){
254 errorUnexpectedToken(parser, parser.getNextToken());
255 return false;
256 }
257 }
258 parser.skipWhiteSpace();
259 }
260 return true;
261}
262
263
264
Describes a class attribute.
void setDefaultValue(const PString &defaultValue)
Sets the defaultValue of the PClassAttribute.
Class to describe a basic class.
void addAttribute(const PClassAttribute &attribute)
Adds an attribute to the class.
void setClassDocumentation(const PString &classDocumentation)
Sets the class documentation.
void setNamespace(const PString &value)
Sets the namespace of the class.
void setIsEnum(bool isEnum)
Set if the current PClassConfig is an enum.
const PString & getName() const
Returns the class name.
void setName(const PString &name)
Sets the class name.
void addParentClass(const PString &parentClass)
Add a parent class to the PClassConfig.
void setListTemplate(const PVecString &listTemplate)
Sets the list of template of the class.
PClassAttribute createClassAttribute(const PString &type, const PString &name, const PString &documentation)
Creates a PClassAttribute.
bool updateCurrentComment(PFileParser &parser, PString &currentComment)
Fonction qui met à jour un commentaire.
bool parseEnumValue(PClassConfig &config, PFileParser &parser, PString &currentComment)
Parse enum attribute value.
bool parseEnumConfig(std::vector< PClassConfig > &listClassConfig, PFileParser &parser, PString &currentComment)
Parse an enum definition.
bool parseClassConfigAttribut(PClassConfig &config, PFileParser &parser, PString &currentComment)
Parse a PClassConfig.
bool parsePClassConfig(std::vector< PClassConfig > &listClassConfig, PFileParser &parser, PString &currentComment, PVecString &listTemplate)
Parse a PClassConfig.
bool parserClassConfig(std::vector< PClassConfig > &listClassConfig, PVecPath &listInclude, const PPath &fileName)
Parser list class config.
bool updateCurrentTemplate(PFileParser &parser, PVecString &currentTemplate)
Update a template definition.
bool parseParentOfClassConfig(PClassConfig &config, PFileParser &parser)
Parse the parents of the PClassConfig.
PString getClassName(PFileParser &parser)
Get class name from parser.
void errorUnexpectedToken(const PFileParser &parser, const PString &token)
Affiche une erreur de token non attendu.