/*************************************** Auteur : Pierre Aubert Mail : aubertp7@gmail.com Licence : CeCILL-C ****************************************/ #include "string_utils.h" #include "repr_cpp_operator.h" #include "repr_cpp_token_operator.h" ///Save the headers of the PToken functions for Operator /** @param tabGraphToken : PTabGraphToken of all Operator * @param graphToken : graph of the current token * @return C++ header */ std::string repr_cpp_tokenOperatorHeader(const PTabGraphToken & tabGraphToken, const PGraphToken & graphToken){ std::string body(""), name(graphToken.getName()), varName(graphToken.getVarName()), varType(graphToken.getVarType()); PVecOperator vecOp; search_operatorByGraphUse(vecOp, tabGraphToken.getVecOperator(), graphToken.getName()); if(vecOp.size() != 0lu){ for(PVecOperator::iterator it(vecOp.begin()); it != vecOp.end(); ++it){ std::string baseFctName("Operator" + repr_cpp_operator_getEnumValue(it->getValueEnum())); body += "\t\tbool " + name + baseFctName + "Do(" + varType + " & " + varName + ");\n"; body += "\t\tvoid " + name + baseFctName + "Undo(" + varType + " & " + varName + ");\n\n"; } } return body; } ///Save the implementation of a single token Operator parsing function for the given graphToken /** @param op : operator to be used * @param graphToken : graph token related to the current operator * @return C++ */ std::string repr_cpp_singleTokenOperator(const POperator & op, const PGraphToken & graphToken){ std::string body(""), name(graphToken.getName()), varName(graphToken.getVarName()), varType(graphToken.getVarType()); std::string opToken(op.getVecToken().front()); body += "\t//repr_cpp_token_operator : Let's parse an Operator with 1 token\n"; body += "\t//repr_cpp_token_operator : the first operand is already parsed and given as parameter\n"; body += "\t//repr_cpp_token_operator : it would be great to add a while\n\n"; body += "\tif(!isMatch(\""+opToken+"\")){return false;}\n"; body += "\t//repr_cpp_token_operator : Let's call the graph token of the second operand\n"; body += "\tPStmt rightOp = "+op.getExprClass()+"_default();\n"; std::string rightOperandGraph(op.getVecExprGraph().back()); body += "\tif(!" + rightOperandGraph + "(rightOp)){return false;}\n"; body += "\t//repr_cpp_token_operator : here the operator is well parsed\n"; body += "\tPStmt op = "+op.getExprClass()+"_default();\n"; body += "\t"+op.getExprClass()+"_set"+firstToUpper(op.getAttrEnum())+"(op, "+op.getValueEnum()+");\n"; body += "\tPStmt & vecOperand = "+op.getExprClass()+"_get"+firstToUpper(op.getVecOp())+"(op);\n"; body += "\t\n"; body += "\tbool isStandardPushBack(true);\n"; body += "\tif(isAnOperator(rightOp)){\n"; body += "\t\tlong priorityOp(get_priority_operator(op)), priorityRight(get_priority_operator(rightOp));\n"; body += "\t\tstd::cout << \"op '"+opToken+"' : priorityOp = \" << priorityOp << \", priorityRight = \" << priorityRight << std::endl;\n"; body += "\t\tif(priorityOp > priorityRight){\n"; body += "\t\t\t//repr_cpp_token_operator : Let's get the first operand of the right operator rightOp\n"; body += "\t\t\tPStmt * firstOp = get_first_operand_of_operator(rightOp);\n"; body += "\t\t\tif(firstOp == NULL){return false;}\n"; body += "\t\t\tvecOperand.push_back("+varName+");\t//This is a copy, so it works\n"; body += "\t\t\tvecOperand.push_back(*firstOp);\n"; body += "\t\t\t*firstOp = op;\n"; body += "\t\t\t"+varName+" = rightOp;\n"; body += "\t\t\tisStandardPushBack = false;\n"; body += "\t\t}\n"; body += "\t}\n"; body += "\tif(isStandardPushBack){\n"; body += "\t\tstd::cout << \"op '"+opToken+"' : Do a standard push_back\" << std::endl;\n"; body += "\t\tvecOperand.push_back("+varName+");\n"; body += "\t\tvecOperand.push_back(rightOp);\n"; body += "\t\t//repr_cpp_token_operator : Finally, put the operator in the in/out parameter\n"; body += "\t\t"+varName+" = op;\n"; body += "\t}\n"; return body; } ///Save the implementation of a double tokens Operator parsing function for the given graphToken /** @param op : operator to be used * @param graphToken : graph token related to the current operator * @return C++ */ std::string repr_cpp_doubleTokenOperator(const POperator & op, const PGraphToken & graphToken){ std::string body(""), name(graphToken.getName()), varName(graphToken.getVarName()), varType(graphToken.getVarType()); body += "\t//repr_cpp_token_operator : Let's parse an Operator with 2 tokens\n"; return body; } ///Save the implementation of a triple tokens Operator parsing function for the given graphToken /** @param op : operator to be used * @param graphToken : graph token related to the current operator * @return C++ */ std::string repr_cpp_tripleTokenOperator(const POperator & op, const PGraphToken & graphToken){ std::string body(""), name(graphToken.getName()), varName(graphToken.getVarName()), varType(graphToken.getVarType()); body += "\t//repr_cpp_token_operator : Let's parse an Operator with 3 tokens\n"; return body; } ///Save the implementation of the Operator parsing function for the given graphToken /** @param parserName : name of the generated parser class * @param op : operator to be used * @param graphToken : graph token related to the current operator * @return C++ */ std::string repr_cpp_tokenOperatorSourceOperatorDo(const std::string & parserName, const POperator & op, const PGraphToken & graphToken){ std::string body(""), name(graphToken.getName()), varName(graphToken.getVarName()), varType(graphToken.getVarType()); std::string opValue(repr_cpp_operator_getEnumValue(op.getValueEnum())); std::string baseFctName("Operator" + opValue); size_t nbToken(op.getVecToken().size()); body += "///Parse the Operator " + opValue + " related to the GraphToken "+varName+"\n"; body += "/**\t@param " + varName + " : " + varType + " to be parsed by the operator\n"; body += " * \t@return true on success, false otherwise\n"; body += "*/\n"; body += "bool " + parserName + "::" + name + baseFctName + "Do(" + varType + " & " + varName + "){\n"; body += "\tp_parser->pushPosition();\n"; if(nbToken == 1lu){ body += repr_cpp_singleTokenOperator(op, graphToken); }else if(nbToken == 2lu){ body += repr_cpp_doubleTokenOperator(op, graphToken); }else if(nbToken == 3lu){ body += repr_cpp_tripleTokenOperator(op, graphToken); }else{ body += "\t#error \"repr_cpp_tokenOperatorSourceOperatorDo : no rules to parse operator with "+convertToString(nbToken)+" token\"\n"; } body += "\tPStmt & _vecOp = " + varType + "_get"+firstToUpper(op.getVecOp())+"(" + varName + ");\n"; body += "\t//repr_cpp_token_operator : If there is no operand\n"; body += "\tif(_vecOp.size() == 0lu){return false;}\n"; body +="\treturn true;\n"; body +="}\n\n"; return body; } ///Save the implementation of the Operator parsing function for the given graphToken /** @param parserName : name of the generated parser class * @param op : operator to be used * @param graphToken : graph token related to the current operator */ std::string repr_cpp_tokenOperatorSourceOperatorUndo(const std::string & parserName, const POperator & op, const PGraphToken & graphToken){ std::string body(""), name(graphToken.getName()), varName(graphToken.getVarName()), varType(graphToken.getVarType()); std::string opValue(repr_cpp_operator_getEnumValue(op.getValueEnum())); std::string baseFctName("Operator" + repr_cpp_operator_getEnumValue(op.getValueEnum())); body += "///Undo the Parsing of the Operator " + opValue + " related to the GraphToken "+varName+"\n"; body += "/**\t@param " + varName + " : " + varType + " to be parsed by the operator\n"; body += "*/\n"; body += "void " + parserName + "::" + name + baseFctName + "Undo(" + varType + " & " + varName + "){\n"; body += "\tp_parser->popPosition();\n"; body +="}\n\n"; return body; } ///Save the source of the PToken functions /** @param parserName : name of the generated parser class * @param tabGraphToken : contains all the graph and internal representation * @param graph : graph of the current token * @return C++ source */ std::string repr_cpp_tokenOperatorSource(const std::string & parserName, const PTabGraphToken & tabGraphToken, const PGraphToken & graph) { std::string body(""); PVecOperator vecOp; search_operatorByGraphUse(vecOp, tabGraphToken.getVecOperator(), graph.getName()); if(vecOp.size() != 0lu){ for(PVecOperator::iterator it(vecOp.begin()); it != vecOp.end(); ++it){ body += repr_cpp_tokenOperatorSourceOperatorDo(parserName, *it, graph); body += repr_cpp_tokenOperatorSourceOperatorUndo(parserName, *it, graph); } } return body; }