#include "AstNode.h"
#include "tree.h"
#include "AstContainer.h"
#include "Translation.h"
#include <vector>
#include <list>
#include <string>
#include <map>
#include <fstream>
Go to the source code of this file.
Defines | |
#define | CPPHEADERSIZE 2 |
Functions | |
string | cppBufferize (const string &__in) |
string | indent (unsigned nbIndent) |
std::ostream & | operator<< (std::ostream &stream, const StringBuffer &b) |
string | varname (const string &phpname, bool correctQuote=false) |
string | getNodeValue (const tree< AstNode >::iterator &start, const string &type, const tree< AstNode > &tr) |
tree< AstNode >::iterator | getNodeIter (const tree< AstNode >::iterator &start, const string &type, const tree< AstNode > &tr) |
bool | functionReturnValue (const tree< AstNode >::iterator &start, const tree< AstNode > &tr) |
bool | isAChildrenOf (const tree< AstNode >::iterator &start, const string &type, const tree< AstNode > &tr) |
bool | classAssignement (const tree< AstNode >::iterator &start, const tree< AstNode > &t) |
string | className (const tree< AstNode >::iterator &start, const tree< AstNode > &t) |
string | subVarName (const tree< AstNode >::iterator &it, const tree< AstNode > &tr) |
void | writeSiblingsCPP (const tree< AstNode > &t, const tree< AstNode >::iterator &iRoot, StringBuffer &buf, bool inString=false, bool inFct=false, bool inMain=false, bool inClass=false, bool inFctCall=false) |
void | writeCPP (const tree< AstNode > &tr, StringBuffer &buf) |
void | addFunctionCpp (const tree< AstNode >::iterator &start, const tree< AstNode > &tr, StringBuffer &buffer, bool fromClass=false, const string cname="") |
void | addClassCpp (const tree< AstNode >::iterator &start, const tree< AstNode > &tr, StringBuffer &buffer) |
Variables | |
list< string > | classVarNames |
const string | cppheader [2] |
#define CPPHEADERSIZE 2 |
void addClassCpp | ( | const tree< AstNode >::iterator & | start, | |
const tree< AstNode > & | tr, | |||
StringBuffer & | buffer | |||
) |
Definition at line 394 of file Translation.cpp.
References addFunctionCpp(), tree< T, tree_node_allocator >::begin(), tree< T, tree_node_allocator >::child(), tree< T, tree_node_allocator >::end(), getNodeIter(), getNodeValue(), tree< T, tree_node_allocator >::number_of_children(), and utils::start_with().
Referenced by Ast2Cpp::operator()().
00395 { 00396 // Check for the class name 00397 string cname, extend=""; 00398 cname = getNodeValue(start, "T_STRING", tr); 00399 tree<AstNode>::iterator extends = getNodeIter(start, "extends_from", tr); 00400 00401 buffer << "class " + cname; 00402 00403 if (tr.number_of_children(extends) > 0) { 00404 for (tree<AstNode>::iterator iter=tr.begin(extends);iter!=tr.end(extends);++iter) { 00405 if (iter->getType() == "T_STRING") { 00406 extend = tr.child(iter, 0)->getValue(); 00407 break; 00408 } 00409 } 00410 buffer << " : public " + extend; 00411 } 00412 buffer << "{\n"; 00413 00414 tree<AstNode>::iterator methodList = getNodeIter(start, "class_statement_list", tr); 00415 // Add the methods in the content 00416 00417 map<string, tree<AstNode>::iterator> specialFunctions; 00418 00419 // Check if there is contructor 00420 for (tree<AstNode>::iterator iter=tr.begin(methodList);iter!=tr.end(methodList);++iter) { 00421 if (iter->getType() == "class_statement") { 00422 for (tree<AstNode>::iterator jter=tr.begin(iter);jter!=tr.end(iter);++jter) { 00423 if (jter->getType() == "T_STRING") { 00424 jter = tr.child(jter, 0); 00425 if (jter->getType() == "text" && utils::start_with(jter->getValue(), "__")) { 00426 // special function 00427 specialFunctions.insert(make_pair(jter->getValue(), iter)); 00428 break; 00429 } 00430 } 00431 } 00432 } 00433 } 00434 00435 // Add the function definitions 00436 for (tree<AstNode>::iterator iter=tr.begin(methodList);iter!=tr.end(methodList);++iter) 00437 { 00438 if (iter->getType() == "class_statement") 00439 { 00440 //cout << "One call to method? declaration..." << endl; 00441 addFunctionCpp(iter, tr, buffer, true, cname); 00442 } 00443 } 00444 00445 if (specialFunctions.find("__construct") == specialFunctions.end()) { 00446 // write the default constructor 00447 buffer << ("\n " + cname + "() {}\n"); 00448 } 00449 if (specialFunctions.find("__destruct") == specialFunctions.end()) { 00450 // write the default constructor 00451 buffer << ("\n ~" + cname + "() {}\n"); 00452 } 00453 buffer << ("\n " + cname + "(const "+ cname + "& ____c) {}\n"); 00454 buffer << "\n};\n"; 00455 }
void addFunctionCpp | ( | const tree< AstNode >::iterator & | start, | |
const tree< AstNode > & | tr, | |||
StringBuffer & | buffer, | |||
bool | fromClass = false , |
|||
const string | cname = "" | |||
) |
Definition at line 336 of file Translation.cpp.
References tree< T, tree_node_allocator >::begin(), tree< T, tree_node_allocator >::child(), tree< T, tree_node_allocator >::end(), functionReturnValue(), getNodeIter(), getNodeValue(), tree< T, tree_node_allocator >::number_of_children(), utils::start_with(), varname(), and writeSiblingsCPP().
Referenced by addClassCpp(), and Ast2Cpp::operator()().
00337 { 00338 string fname; 00339 vector<string> paramVars; 00340 bool returnValue = functionReturnValue(start, tr); 00341 fname = getNodeValue(start, "T_STRING", tr); 00342 00343 if (fromClass) 00344 { 00345 if (utils::start_with(fname,"__")) { 00346 // looks like a constructor, copy etc. 00347 if (fname == "__construct") 00348 fname = cname; 00349 else if (fname == "__destruct") 00350 fname = "~" + cname; 00351 else if (fname == "__clone") // I'll do by myself! 00352 return; 00353 } 00354 } 00355 00356 tree<AstNode>::iterator params = getNodeIter(start, "parameter_list", tr); 00357 if (tr.number_of_children(params) > 0) { 00358 // fill paramVars 00359 for (tree<AstNode>::iterator iter=tr.begin(params);iter!=tr.end(params);++iter) { 00360 if (iter->getType() == "T_VARIABLE") { 00361 paramVars.push_back(varname(tr.child(iter, 0)->getValue())); 00362 } 00363 } 00364 } 00365 string decl = ""; 00366 if (returnValue) 00367 decl += "PhpObject "; 00368 else if (fname != cname) 00369 decl += "void "; 00370 decl += fname; 00371 decl += "( "; 00372 unsigned t = paramVars.size(); 00373 if (t > 0) { 00374 decl += ("PhpObject& loc_" + paramVars[0]); 00375 for (unsigned i=1;i<t;i++) 00376 decl += (", PhpObject& " + paramVars[i]); 00377 } 00378 decl += " ) {\n"; 00379 buffer << (decl); 00380 StringBuffer localFuncContent; 00381 tree<AstNode>::iterator content; 00382 00383 content = getNodeIter(start, "inner_statement_list", tr); 00384 00385 writeSiblingsCPP(tr, content, localFuncContent, false, true); 00386 for (vector<string>::const_iterator iter=paramVars.begin();iter!=paramVars.end();++iter) { 00387 localFuncContent.replace(" " + *iter + " ", " loc_" + *iter + " "); 00388 } 00389 buffer << localFuncContent; 00390 buffer << ("}\n"); 00391 }
Definition at line 179 of file Translation.cpp.
References tree< T, tree_node_allocator >::begin(), and tree< T, tree_node_allocator >::end().
Referenced by writeSiblingsCPP().
00179 { 00180 for (tree<AstNode>::iterator iter=t.begin(start);iter!=t.end(start);++iter) { 00181 if (iter->getType() == "T_NEW") { 00182 return true; 00183 } 00184 } 00185 return false; 00186 }
Definition at line 188 of file Translation.cpp.
References tree< T, tree_node_allocator >::begin(), and tree< T, tree_node_allocator >::end().
Referenced by Ast::fillAstInformation(), and writeSiblingsCPP().
00188 { 00189 for (tree<AstNode>::iterator iter=t.begin(start);iter!=t.end(start);++iter) { 00190 if (iter->getType() == "class_name_reference") { 00191 for (tree<AstNode>::iterator jter=t.begin(iter);jter!=t.end(iter);++jter) { 00192 if (jter->getType() == "text") { 00193 return jter->getValue(); 00194 } 00195 } 00196 return string(); 00197 } 00198 } 00199 return string(); 00200 }
string cppBufferize | ( | const string & | __in | ) |
Definition at line 155 of file Translation.cpp.
References tree< T, tree_node_allocator >::begin(), tree< T, tree_node_allocator >::end(), tree< T, tree_node_allocator >::number_of_children(), and tree< T, tree_node_allocator >::parent().
Referenced by addFunctionCpp().
00156 { 00157 for (tree<AstNode>::iterator iter=tr.begin(start);iter!=tr.end(start);++iter) { 00158 if (iter->getType() == "T_RETURN") { 00159 tree<AstNode>::iterator p = tr.parent(iter); 00160 if (tr.number_of_children(p) > 2) 00161 return true; 00162 } 00163 } 00164 return false; 00165 }
tree<AstNode>::iterator getNodeIter | ( | const tree< AstNode >::iterator & | start, | |
const string & | type, | |||
const tree< AstNode > & | tr | |||
) |
Definition at line 146 of file Translation.cpp.
References tree< T, tree_node_allocator >::begin(), and tree< T, tree_node_allocator >::end().
Referenced by addClassCpp(), addFunctionCpp(), and writeSiblingsCPP().
00147 { 00148 for (tree<AstNode>::iterator iter=tr.begin(start);iter!=tr.end(start);++iter) { 00149 if (iter->getType() == type) 00150 return iter; 00151 } 00152 return tr.end(); 00153 }
string getNodeValue | ( | const tree< AstNode >::iterator & | start, | |
const string & | type, | |||
const tree< AstNode > & | tr | |||
) |
Definition at line 131 of file Translation.cpp.
References tree< T, tree_node_allocator >::begin(), and tree< T, tree_node_allocator >::end().
Referenced by addClassCpp(), addFunctionCpp(), and writeSiblingsCPP().
00132 { 00133 for (tree<AstNode>::iterator iter=tr.begin(start);iter!=tr.end(start);++iter) { 00134 if (iter->getType() == type) { 00135 for (;iter->getType() != "text" && iter!=tr.end(start);++iter) 00136 ; 00137 if (iter->getType() == "text") 00138 return iter->getValue(); 00139 else 00140 return string(); 00141 } 00142 } 00143 return string(); 00144 }
string indent | ( | unsigned | nbIndent | ) |
Definition at line 46 of file Translation.cpp.
Referenced by StringBuffer::format().
00046 { 00047 string r = ""; 00048 for (unsigned i=0;i<nbIndent;i++) 00049 r += '\t'; 00050 return r; 00051 }
bool isAChildrenOf | ( | const tree< AstNode >::iterator & | start, | |
const string & | type, | |||
const tree< AstNode > & | tr | |||
) |
Definition at line 167 of file Translation.cpp.
References tree< T, tree_node_allocator >::child(), and tree< T, tree_node_allocator >::number_of_children().
00168 { 00169 unsigned nC = tr.number_of_children(start); 00170 if (nC > 0) { 00171 for (unsigned i=0;i<nC;i++) { 00172 if (tr.child(start, i)->getType() == type) 00173 return true; 00174 } 00175 } 00176 return false; 00177 }
std::ostream& operator<< | ( | std::ostream & | stream, | |
const StringBuffer & | b | |||
) |
Definition at line 110 of file Translation.cpp.
00110 { 00111 stream << b.buffer << std::endl; 00112 return stream; 00113 }
Definition at line 203 of file Translation.cpp.
References tree< T, tree_node_allocator >::child(), tree< T, tree_node_allocator >::end(), and tree< T, tree_node_allocator >::number_of_children().
Referenced by writeSiblingsCPP().
00204 { 00205 tree<AstNode>::iterator iter = it; 00206 // go the the variable 00207 for (;iter != tr.end(it); ++iter) { 00208 if (iter->getType() == "reference_variable") 00209 { 00210 unsigned nbchilds = tr.number_of_children(iter); 00211 if (nbchilds == 1) { 00212 if (tr.child(iter, 0)->getType() == "compound_variable") { 00213 // single variables 00214 tree<AstNode>::iterator var = iter; 00215 for(;var->getType() != "text"; ++var) 00216 ; 00217 return (var->getValue()); 00218 } 00219 } 00220 else if (nbchilds == 4) { 00221 // array ? 00222 tree<AstNode>::iterator array = tr.child(iter, 0); 00223 tree<AstNode>::iterator index = tr.child(iter, 2); 00224 for(;array->getType() != "text" && array != tr.end(); ++array) 00225 ; 00226 for(;index->getType() != "text" && index != tr.end(); ++index) 00227 ; 00228 return array->getValue() + "[" + index->getValue() + "]"; 00229 } 00230 } 00231 else if (iter->getType() == "expr_without_variable") 00232 { 00233 // go to the T_VARIABLE 00234 tree<AstNode>::iterator var = iter; 00235 for(;var->getType() != "T_VARIABLE"; ++var) 00236 ; 00237 var = tr.child(var, 0); 00238 return var->getValue(); 00239 } 00240 } 00241 // backtrack for: strings, functions, class 00242 return string(); 00243 }
string varname | ( | const string & | phpname, | |
bool | correctQuote = false | |||
) |
Definition at line 116 of file Translation.cpp.
Referenced by addFunctionCpp(), Ast2Cpp::operator()(), and writeSiblingsCPP().
00116 { 00117 string name; 00118 for (string::const_iterator i=phpname.begin();i!=phpname.end();++i) { 00119 if (*i == '$') 00120 continue; 00121 else if (correctQuote and *i == '\'') 00122 name += '"'; 00123 else 00124 name += *i; 00125 } 00126 return name; 00127 }
void writeCPP | ( | const tree< AstNode > & | tr, | |
StringBuffer & | buf | |||
) |
Definition at line 323 of file Translation.cpp.
References tree< T, tree_node_allocator >::begin(), tree< T, tree_node_allocator >::empty(), tree< T, tree_node_allocator >::end(), and writeSiblingsCPP().
00324 { 00325 if (tr.empty()) { 00326 throw length_error("writeCPP - The AST tree is empty"); 00327 return; 00328 } 00329 for(tree<AstNode>::sibling_iterator iRoots = tr.begin(); iRoots != tr.end(); iRoots++) { 00330 writeSiblingsCPP(tr,iRoots,buf); 00331 } 00332 }
void writeSiblingsCPP | ( | const tree< AstNode > & | t, | |
const tree< AstNode >::iterator & | iRoot, | |||
StringBuffer & | buf, | |||
bool | inString = false , |
|||
bool | inFct = false , |
|||
bool | inMain = false , |
|||
bool | inClass = false , |
|||
bool | inFctCall = false | |||
) |
Definition at line 245 of file Translation.cpp.
References tree< T, tree_node_allocator >::begin(), tree< T, tree_node_allocator >::child(), classAssignement(), className(), classVarNames, tree< T, tree_node_allocator >::empty(), tree< T, tree_node_allocator >::end(), getNodeIter(), getNodeValue(), tree< T, tree_node_allocator >::number_of_children(), tree< T, tree_node_allocator >::parent(), subVarName(), and varname().
Referenced by addFunctionCpp(), Ast2Cpp::operator()(), and writeCPP().
00247 { 00248 if(t.empty()) 00249 return; 00250 string type = iRoot->getType(); 00251 if (type == "root") { 00252 tree<AstNode>::sibling_iterator iChildren = t.begin(iRoot); 00253 writeSiblingsCPP(t,iChildren,buf,inString,inFct,inMain,inClass,inFctCall); 00254 } 00255 else if (t.number_of_children(iRoot) == 0) { 00256 if (iRoot->getValue().length() > 0) { 00257 if (iRoot->getValue() == ".") { /* concatenate transformation */ buf << " + "; } 00258 else if (t.parent(iRoot)->getType() == "T_ENCAPSED_AND_WHITESPACE") 00259 buf << (varname(iRoot->getValue(), false) + " "); 00260 else 00261 buf << (varname(iRoot->getValue(), true) + " "); 00262 } 00263 } 00264 else { 00265 int siblingNum; 00266 tree<AstNode>::sibling_iterator iChildren; 00267 if (type == "T_ECHO" or type == "T_INCLUDE" or type == "T_PRINT") { 00268 // gotta be a function 00269 tree<AstNode>::iterator parent = t.parent(iRoot); // go to the parent in order to get all information 00270 string funcName = getNodeValue(parent, type, t); 00271 string contentNodeName = "echo_expr_list"; 00272 if (type == "T_INCLUDE" or type == "T_PRINT") { 00273 contentNodeName = "expr"; 00274 } 00275 // must be always true, otherwise, the AST is ill-formed 00276 buf << (funcName + "("); 00277 writeSiblingsCPP(t,getNodeIter(parent, contentNodeName, t),buf,inString,inFct,inMain,inClass,inFctCall); 00278 buf << "); "; 00279 } 00280 else if (type == "expr_without_variable" && t.number_of_children(iRoot) == 3 00281 && t.child(iRoot,1)->getType() == "CHAR61" 00282 && classAssignement(t.child(iRoot,2), t)) { // assignement + class + new 00283 string cname = className(t.child(iRoot,2), t); 00284 if (cname.length() > 0) { 00285 string v = varname(subVarName(t.child(iRoot,0), t)); 00286 buf << cname << "* " << v << " = new " << cname << "()\n"; 00287 classVarNames.push_back(v); 00288 } 00289 else { 00290 for (iChildren = t.begin(iRoot), siblingNum = 0; iChildren != t.end(iRoot); ++iChildren) 00291 { 00292 string subtype = iChildren->getType(); 00293 if (subtype == "T_ECHO" or subtype == "T_INCLUDE" or subtype == "T_PRINT") { 00294 writeSiblingsCPP(t,iChildren,buf,inString,inFct,inMain,inClass,inFctCall); 00295 break; 00296 } 00297 else if (inMain && (subtype == "unticked_function_declaration_statement" || subtype == "unticked_class_declaration_statement")) { 00298 continue; 00299 } 00300 else 00301 writeSiblingsCPP(t,iChildren,buf,inString,inFct,inMain,inClass,inFctCall); 00302 } 00303 } 00304 } 00305 else { 00306 for (iChildren = t.begin(iRoot), siblingNum = 0; iChildren != t.end(iRoot); ++iChildren) 00307 { 00308 string subtype = iChildren->getType(); 00309 if (subtype == "T_ECHO" or subtype == "T_INCLUDE" or subtype == "T_PRINT") { 00310 writeSiblingsCPP(t,iChildren,buf,inString,inFct,inMain,inClass,inFctCall); 00311 break; 00312 } 00313 else if (inMain && (subtype == "unticked_function_declaration_statement" || subtype == "unticked_class_declaration_statement")) { 00314 continue; 00315 } 00316 else 00317 writeSiblingsCPP(t,iChildren,buf,inString,inFct,inMain,inClass,inFctCall); 00318 } 00319 } 00320 } 00321 }
list<string> classVarNames |
Definition at line 30 of file Translation.cpp.
Referenced by Ast2Cpp::operator()(), and writeSiblingsCPP().
const string cppheader[2] |
Initial value:
{ "#include <iostream>\n", "#include \"libphp.h\"\n\n" }
Definition at line 34 of file Translation.cpp.
Referenced by Ast2Cpp::operator()().