PhoenixGenerator  2.6.4
Set of tools to generate code
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 : CeCILL-C
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 PVecString listToken(attribut.split(" \n\t"));
75 PString attributName(listToken.back());
76 listToken.pop_back();
77 PString attributType("");
78 for(PVecString::iterator it(listToken.begin()); it != listToken.end(); ++it){
79 attributType += *it + " ";
80 }
81 attributType = attributType.eraseFirstLastChar(" \n\t");
82 config.addAttribute(createClassAttribute(attributType, attributName, currentComment));
83 currentComment = "";
84 return true;
85}
86
88
92bool parseParentOfClassConfig(PClassConfig & config, PFileParser & parser){
93 if(!parser.isMatch("(")) return true;
94
95 while(!parser.isEndOfFile() && parser.isMatch(")")){
96 PString parentDef(getClassName(parser));
97 if(parentDef == ""){
98 break;
99 }
100 config.addParentClass(parentDef);
101 if(parser.isMatch(")")){break;}
102
103 if(!parser.isMatch(",")){
104 errorUnexpectedToken(parser, parser.getNextToken());
105 return false;
106 }
107 }
108 return true;
109}
110
112
117bool parseEnumValue(PClassConfig & config, PFileParser & parser, PString & currentComment){
118 PString enumValue(getClassName(parser)), value("");
119 if(!parser.isMatch("=")){
120 value = parser.getStrComposedOf("0123456789xu");
121 }
122 PClassAttribute attr(createClassAttribute("int /* just to remember*/", enumValue, currentComment));
123 attr.setDefaultValue(value);
124 config.addAttribute(attr);
125 currentComment = "";
126 parser.isMatch(","); //We consume the comma if there is one
127 return true;
128}
129
131
136bool parseEnumConfig(std::vector<PClassConfig> & listClassConfig, PFileParser & parser, PString & currentComment){
137 if(!parser.isMatchToken("enum")){return false;}
138 PClassConfig config;
139 config.setIsEnum(true);
140 PString enumName(getClassName(parser)); //Get the name of the enum
141 std::cout << "parseEnumConfig : find enum : '"<<enumName<<"'" << std::endl;
142 config.setName(enumName);
143 config.setClassDocumentation(currentComment);
144 currentComment = "";
145 parser.skipWhiteSpace();
146 if(!parser.isMatch("{")){
147 errorUnexpectedToken(parser, parser.getNextToken());
148 std::cerr << "\tExpect '{' after enum name '"<<enumName<<"'" << std::endl;
149 return false;
150 }
151 bool searchingData(true);
152 while(!parser.isEndOfFile() && searchingData && !parser.isMatch("}")){
153 if(updateCurrentComment(parser, currentComment)){}
154 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
155 if(!parseEnumValue(config, parser, currentComment)){
156 errorUnexpectedToken(parser, parser.getNextToken());
157 return false;
158 }
159 }
160 }
161 listClassConfig.push_back(config);
162 return true;
163}
164
166
172bool parsePClassConfig(std::vector<PClassConfig> & listClassConfig, PFileParser & parser, PString & currentComment, PVecString & listTemplate){
173 PClassConfig config;
174 PString fullName(getClassName(parser));
175 size_t separator = fullName.rfind("::");
176 PString className, namespaceName;
177 if(separator != PString::npos){
178 className = fullName.substr(separator + 2);
179 namespaceName = fullName.substr(0, separator);
180 std::cout << "parsePClassConfig : find namespaceName : '"<<namespaceName<<"'" << std::endl;
181 }else{
182 className = fullName;
183 }
184 std::cout << "parsePClassConfig : find className : '"<<className<<"'" << std::endl;
185 config.setName(className);
186 config.setNamespace(namespaceName);
187 config.setClassDocumentation(currentComment);
188 config.setListTemplate(listTemplate);
189 currentComment = "";
190 listTemplate.clear();
191 parser.skipWhiteSpace();
192
193 if(!parseParentOfClassConfig(config, parser)){
194 std::cerr << "parsePClassConfig : file '" << parser.getFileName() << "' line " << parser.getLine() << std::endl;
195 std::cerr << "\tmissing ')' : can't parse parents of the class '"<<config.getName()<<"'" << std::endl;
196 }
197 if(parser.isEndOfFile()){
198 std::cerr << "parsePClassConfig : file '" << parser.getFileName() << "' line " << parser.getLine() << std::endl;
199 std::cerr << "\tmissing '}'" << std::endl;
200 return false;
201 }
202 if(!parser.isMatch("{")){
203 errorUnexpectedToken(parser, parser.getNextToken());
204 std::cerr << "\tExpect '{' after class name '"<<className<<"'" << std::endl;
205 return false;
206 }
207
208 bool searchingData(true);
209 while(!parser.isEndOfFile() && searchingData && !parser.isMatch("}")){
210 if(updateCurrentComment(parser, currentComment)){}
211 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
212 if(!parseClassConfigAttribut(config, parser, currentComment)){
213 errorUnexpectedToken(parser, parser.getNextToken());
214 return false;
215 }
216 }
217 }
218 listClassConfig.push_back(config);
219 return true;
220}
221
223
228bool parserClassConfig(std::vector<PClassConfig> & listClassConfig, PVecPath & listInclude, const PPath & fileName){
229 if(fileName == "") return false;
230 PFileParser parser;
231 parser.setWhiteSpace(" \t\n");
232 parser.setSeparator("{};/*");
233 if(!parser.open(fileName)) return false;
234 PString currentComment("");
235 PVecString listTemplate;
236 while(!parser.isEndOfFile()){
237 if(parser.isMatch("#")){
238 if(parser.isMatch("include")){
239 listInclude.push_back(parser.getUntilKeyWithoutPatern("\n").eraseChar(" \t\n"));
240 }
241 }else if(updateCurrentComment(parser, currentComment)){}
242 else if(updateCurrentTemplate(parser, listTemplate)){}
243 else if(parseEnumConfig(listClassConfig, parser, currentComment)){}
244 else{ //Si ce n'est pas un séparateur, c'est que l'on a trouvé un nom, de PClassConfig
245 if(!parsePClassConfig(listClassConfig, parser, currentComment, listTemplate)){
246 errorUnexpectedToken(parser, parser.getNextToken());
247 return false;
248 }
249 }
250 parser.skipWhiteSpace();
251 }
252 return true;
253}
254
255
256
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.