Translation.cpp File Reference

#include "AstNode.h"
#include "tree.h"
#include "AstContainer.h"
#include "Translation.h"
#include <vector>
#include <list>
#include <string>
#include <map>
#include <fstream>

Include dependency graph for Translation.cpp:

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 Documentation

#define CPPHEADERSIZE   2

Definition at line 33 of file Translation.cpp.

Referenced by Ast2Cpp::operator()().


Function Documentation

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

bool classAssignement ( const tree< AstNode >::iterator &  start,
const tree< AstNode > &  t 
)

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

string className ( const tree< AstNode >::iterator &  start,
const tree< AstNode > &  t 
)

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

string cppBufferize ( const string &  __in  ) 

Definition at line 40 of file Translation.cpp.

00040                                         {
00041     string buf = "";
00042 
00043     return buf;
00044 }

bool functionReturnValue ( const tree< AstNode >::iterator &  start,
const tree< AstNode > &  tr 
)

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

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 }

string subVarName ( const tree< AstNode >::iterator &  it,
const tree< AstNode > &  tr 
)

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

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()().


Generated on Wed Feb 27 20:31:26 2008 for php.ast.svn.src. by  doxygen 1.5.3