Docker-in-Docker (DinD) capabilities of public runners deactivated. More info

Commit 1bbe5cc5 authored by Pierre Aubert's avatar Pierre Aubert
Browse files

Fix the parsing of PStmt with operators and with respect to the operator priority

parent 40654057
Pipeline #99354 passed with stages
in 11 minutes and 1 second
......@@ -14,4 +14,5 @@ add_subdirectory(TEST_C_ENUM)
add_subdirectory(TEST_VAR_DECL)
add_subdirectory(TEST_VAR_DECL_STRING)
add_subdirectory(TEST_OPERATOR)
add_subdirectory(TEST_OPERATOR_PRIORITY)
project(Phoenix)
cmake_minimum_required(VERSION 3.0)
# compileLibTestGenerator(test_math_operator_priority_parser "PTestOperatorParser" parser_operator.pdecparser)
# compileMainTestGenerator(test_math_operator_priority_parser "PTestOperatorParser" parser_operator.pdecparser main_test.cpp)
# Only when the test will be OK
# compileTestGenerator(test_math_operator_priority_parser "PTestOperatorParser" parser_operator.pdecparser main_test.cpp fileAdd.math)
compileBaseTestGenerator(test_math_operator_priority_parser "PTestOperatorParser" parser_operator.pdecparser main_base_test.cpp)
add_executable(test_math_operator_priority_parser_input main_test.cpp)
target_link_libraries(test_math_operator_priority_parser_input test_math_operator_priority_parser_parser phoenix_parser_stmt file_parser option_parser string_utils)
add_test(NAME Test_test_math_operator_priority_parser_input
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test_math_operator_priority_parser_input -i ${CMAKE_CURRENT_SOURCE_DIR}/fileAdd.math -r "(a+b)"
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
add_test(NAME Test_test_math_operator_priority_parser_input3
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test_math_operator_priority_parser_input -i ${CMAKE_CURRENT_SOURCE_DIR}/fileAdd3.math -r "(a+(b+c))"
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
add_test(NAME Test_test_math_operator_priority_parser_inputMult
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test_math_operator_priority_parser_input -i ${CMAKE_CURRENT_SOURCE_DIR}/fileMult.math -r "(a*b)"
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
add_test(NAME Test_test_math_operator_priority_parser_inputMult3
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test_math_operator_priority_parser_input -i ${CMAKE_CURRENT_SOURCE_DIR}/fileMult3.math -r "(a*(b*c))"
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
add_test(NAME Test_test_math_operator_priority_parser_inputMultAdd
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test_math_operator_priority_parser_input -i ${CMAKE_CURRENT_SOURCE_DIR}/fileMultAdd.math -r "((a*b)+c)"
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
add_test(NAME Test_test_math_operator_priority_parser_inputAddMult
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/test_math_operator_priority_parser_input -i ${CMAKE_CURRENT_SOURCE_DIR}/fileAddMult.math -r "(a+(b*c))"
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
/***************************************
Auteur : Pierre Aubert
Mail : aubertp7@gmail.com
Licence : CeCILL-C
****************************************/
// To get the generated parser
#include "PTestOperatorParserFull.h"
using namespace std;
///Test the conversion of and add expression into a string
/** @return true on success, false otherwise
*/
bool testExprAddToString(){
PExpr varA = PExpr_default();
PExpr_setType(varA, PExprType::VAR);
PExpr_setVarName(varA, "a");
PExpr varB = PExpr_default();
PExpr_setType(varB, PExprType::VAR);
PExpr_setVarName(varB, "b");
PExpr exprAdd = PExpr_default();
PExpr_setType(exprAdd, PExprType::ADD);
PExpr_getVecOperand(exprAdd).push_back(varA);
PExpr_getVecOperand(exprAdd).push_back(varB);
std::string exprStr = gExprVarName(exprAdd);
std::cout << "testExprAddToString : exprAdd = '"<<exprStr<<"'" << std::endl;
// std::cout << "testExprAddToString : exprAdd ok example :"<< std::endl;
// exprAdd.print();
return exprStr == "(a+b)";
}
///Test the conversion of and add expression into a string
/** @return true on success, false otherwise
*/
bool testExprAdd2ToString(){
PExpr varA = PExpr_default();
PExpr_setType(varA, PExprType::VAR);
PExpr_setVarName(varA, "a");
PExpr varB = PExpr_default();
PExpr_setType(varB, PExprType::VAR);
PExpr_setVarName(varB, "b");
PExpr exprAddAB = PExpr_default();
PExpr_setType(exprAddAB, PExprType::ADD);
PExpr_getVecOperand(exprAddAB).push_back(varA);
PExpr_getVecOperand(exprAddAB).push_back(varB);
PExpr varC = PExpr_default();
PExpr_setType(varC, PExprType::VAR);
PExpr_setVarName(varC, "c");
PExpr exprAdd = PExpr_default();
PExpr_setType(exprAdd, PExprType::ADD);
PExpr_getVecOperand(exprAdd).push_back(exprAddAB);
PExpr_getVecOperand(exprAdd).push_back(varC);
std::string exprStr = gExprVarName(exprAdd);
std::cout << "testExprAdd2ToString : exprAdd = '"<<exprStr<<"'" << std::endl;
return exprStr == "((a+b)+c)";
}
///Test the conversion of and add expression into a string
/** @return true on success, false otherwise
*/
bool testExprAdd3ToString(){
PExpr varA = PExpr_default();
PExpr_setType(varA, PExprType::VAR);
PExpr_setVarName(varA, "a");
PExpr varB = PExpr_default();
PExpr_setType(varB, PExprType::VAR);
PExpr_setVarName(varB, "b");
PExpr exprAddAB = PExpr_default();
PExpr_setType(exprAddAB, PExprType::ADD);
PExpr_getVecOperand(exprAddAB).push_back(varA);
PExpr_getVecOperand(exprAddAB).push_back(varB);
PExpr varC = PExpr_default();
PExpr_setType(varC, PExprType::VAR);
PExpr_setVarName(varC, "c");
PExpr varD = PExpr_default();
PExpr_setType(varD, PExprType::VAR);
PExpr_setVarName(varD, "d");
PExpr exprAddCD = PExpr_default();
PExpr_setType(exprAddCD, PExprType::ADD);
PExpr_getVecOperand(exprAddCD).push_back(varC);
PExpr_getVecOperand(exprAddCD).push_back(varD);
PExpr exprAdd = PExpr_default();
PExpr_setType(exprAdd, PExprType::ADD);
PExpr_getVecOperand(exprAdd).push_back(exprAddAB);
PExpr_getVecOperand(exprAdd).push_back(exprAddCD);
std::string exprStr = gExprVarName(exprAdd);
std::cout << "testExprAdd3ToString : exprAdd = '"<<exprStr<<"'" << std::endl;
return exprStr == "((a+b)+(c+d))";
}
int main(int argc, char** argv){
bool b(testExprAddToString());
b &= testExprAdd2ToString();
b &= testExprAdd3ToString();
if(b){return 0;}
else{return -1;}
}
/***************************************
Auteur : Pierre Aubert
Mail : aubertp7@gmail.com
Licence : CeCILL-C
****************************************/
#include "OptionParser.h"
// To get the generated parser
#include "PTestOperatorParserFull.h"
using namespace std;
///Create the OptionParser of this program
/** @return OptionParser of this program
*/
OptionParser createOptionParser(){
OptionParser parser(true, __PROGRAM_VERSION__);
parser.setExampleLongOption("use_parser --input=fileName.shadok");
parser.setExampleShortOption("use_parser -i fileName.shadok");
parser.addOption("input", "i", OptionType::FILENAME, true, "input code file name");
parser.addOption("reference", "r", OptionType::STRING, true, "reference value to be parsed");
return parser;
}
///Parse a source file
/** @param fileName : name of the source file
* @param reference : expeced result of the parsed file
* @return true on success, false otherwise
*/
bool testParseFileName(const std::string & fileName, const std::string & reference){
//We create the parser
PTestOperatorParser parser;
if(!parser.load(fileName)){
cerr << "testParseFileName : can't load file '"<<fileName<<"'" << endl;
return false;
}
//We get the parsed internal representation
PExpr & source = parser.getPExprE();
std::cout << "PExpr full stmt :" << std::endl;
source.print();
std::string exprStr = gExprVarName(source);
std::cout << "testParseFileName : exprStr = '"<<exprStr<<"', expected = '"<<reference<<"'" << std::endl;
return exprStr == reference;
}
int main(int argc, char** argv){
OptionParser optionParser = createOptionParser();
optionParser.parseArgument(argc, argv);
const OptionMode & defaultMode = optionParser.getDefaultMode();
std::string fileName(""), reference("");
defaultMode.getValue(fileName, "input");
defaultMode.getValue(reference, "reference");
bool b(true);
b &= testParseFileName(fileName, reference);
if(b){return 0;}
else{return -1;}
}
///Type of the expression
Enum PExprType{
VAR
ADD
MULT
};
///Describes a simple mathematic expression
Class PExpr{
///Type of the expression
PExprType::PExprType type;
///Name of the variable
String varName[csVariableName];
///Vector of operand
Vector(PExpr) vecOperand;
}
Graph gExprVarName(PExpr e){
e.varName e.type=PExprType::VAR
}
Operator("+", PExpr, type=PExprType::ADD, vecOperand, gExprVarName, gExprVarName)
Operator("*", PExpr, type=PExprType::MULT, vecOperand, gExprVarName, gExprVarName)
......@@ -61,6 +61,7 @@ std::string repr_cpp_operatorHeader(const PTabGraphToken & tabGraphToken){
body += "bool isAnOperator(const PStmt & _op);\n";
body += "long get_priority_operator(const PStmt & _op);\n";
body += "PStmt* get_last_operand_of_operator(PStmt & _op);\n";
body += "PStmt* get_first_operand_of_operator(PStmt & _op);\n";
body += "\n\n";
body += "#endif\n\n\n";
......@@ -127,7 +128,7 @@ std::string repr_cpp_operatorSource(const PTabGraphToken & tabGraphToken, const
body += "*/\n";
body += "PStmt* get_last_operand_of_operator(PStmt & _op){\n";
body += "\t//repr_cpp_operator : Get the last operand of the given operator\n";
body += "\tPStmt * outputPtr = NULL;\n";
body += "\tPStmt * outputPtr = &_op;\n";
prevElse = "";
for(PMapVecOperator::iterator itVec(mapOp.begin()); itVec != mapOp.end(); ++itVec){
body += "\t"+prevElse+"if(is"+(itVec->first)+"(_op)){\n";
......@@ -136,7 +137,32 @@ std::string repr_cpp_operatorSource(const PTabGraphToken & tabGraphToken, const
body += "\t\t"+itPrevElse+"if("+it->getExprClass()+"_get"+firstToUpper(it->getAttrEnum())+"(_op) == "+it->getValueEnum()+"){\n";
body += "\t\t\t//repr_cpp_operator : let's get the number of operand of this operator\n";
body += "\t\t\tPStmt & vecOp = "+it->getExprClass()+"_get"+firstToUpper(it->getVecOp())+"(_op);\n";
body += "\t\t\tif(vecOp.size() != 0lu){outputPtr = &(vecOp.back());}\n";
body += "\t\t\tif(vecOp.size() != 0lu){outputPtr = get_last_operand_of_operator(vecOp.back());}\n";
body += "\t\t}\n";
itPrevElse = "else ";
}
body += "\t}";
prevElse = "else ";
}
body += "\n\treturn outputPtr;\n";
body += "}\n\n";
body += "///Get the first operand of the given PStmt\n";
body += "/**\t@param _op : expression to be checked\n";
body += " * \t@return pointer to the first operand of the given operator, NULL otherwise\n";
body += "*/\n";
body += "PStmt* get_first_operand_of_operator(PStmt & _op){\n";
body += "\t//repr_cpp_operator : Get the first operand of the given operator\n";
body += "\tPStmt * outputPtr = &_op;\n";
prevElse = "";
for(PMapVecOperator::iterator itVec(mapOp.begin()); itVec != mapOp.end(); ++itVec){
body += "\t"+prevElse+"if(is"+(itVec->first)+"(_op)){\n";
std::string itPrevElse("");
for(PVecOperator::iterator it(itVec->second.begin()); it != itVec->second.end(); ++it){
body += "\t\t"+itPrevElse+"if("+it->getExprClass()+"_get"+firstToUpper(it->getAttrEnum())+"(_op) == "+it->getValueEnum()+"){\n";
body += "\t\t\t//repr_cpp_operator : let's get the number of operand of this operator\n";
body += "\t\t\tPStmt & vecOp = "+it->getExprClass()+"_get"+firstToUpper(it->getVecOp())+"(_op);\n";
body += "\t\t\tif(vecOp.size() != 0lu){outputPtr = get_last_operand_of_operator(vecOp.front());}\n";
body += "\t\t}\n";
itPrevElse = "else ";
}
......
......@@ -34,12 +34,13 @@ std::string repr_cpp_tokenOperatorHeader(const PTabGraphToken & tabGraphToken, 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(\""+op.getVecToken().front()+"\")){return false;}\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";
......@@ -54,19 +55,22 @@ std::string repr_cpp_singleTokenOperator(const POperator & op, const PGraphToken
body += "\tPStmt & vecOperand = "+op.getExprClass()+"_get"+firstToUpper(op.getVecOp())+"(op);\n";
body += "\t\n";
body += "\tbool isStandardPushBack(true);\n";
body += "\tif(isAnOperator(e)){\n";
body += "\t\tlong priorityOp(get_priority_operator(op)), priorityInput(get_priority_operator("+varName+"));\n";
body += "\t\tif(priorityOp > priorityInput){\n";
body += "\t\t\t//repr_cpp_token_operator : Let's get the last operand of the input "+varName+"\n";
body += "\t\t\tPStmt * lastOp = get_last_operand_of_operator("+varName+");\n";
body += "\t\t\tvecOperand.push_back(*lastOp);\t//This is a copy, so it works\n";
body += "\t\t\tvecOperand.push_back(rightOp);\n";
body += "\t\t\t*lastOp = op;\n";
body += "\t\t\t\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 NULL;}\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";
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment