aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorRenaud Guezennec <renaud@rolisteam.org>2025-03-30 03:56:37 +0200
committerRenaud Guezennec <renaud@rolisteam.org>2025-03-30 03:58:59 +0200
commite18f4a9936d03a112b1a05b24b0559e5be602e0e (patch)
treee5939fba4307e5b00e3444eb82b477f49d09b166
parent8a3fa044ee7b74be3221717c3f949a10d4e8a178 (diff)
downloadOneRoll-e18f4a9936d03a112b1a05b24b0559e5be602e0e.tar.gz
OneRoll-e18f4a9936d03a112b1a05b24b0559e5be602e0e.zip
[math]: operator priority fix issue.
-rw-r--r--src/libparser/include/diceparser/parsingtoolbox.h1
-rw-r--r--src/libparser/node/executionnode.h2
-rw-r--r--src/libparser/node/parenthesesnode.cpp15
-rw-r--r--src/libparser/node/scalaroperatornode.cpp18
-rw-r--r--src/libparser/node/scalaroperatornode.h15
-rw-r--r--src/libparser/parsingtoolbox.cpp85
-rw-r--r--src/tests/dice/tst_dice.cpp6
7 files changed, 114 insertions, 28 deletions
diff --git a/src/libparser/include/diceparser/parsingtoolbox.h b/src/libparser/include/diceparser/parsingtoolbox.h
index 2700ae4..f34b4ac 100644
--- a/src/libparser/include/diceparser/parsingtoolbox.h
+++ b/src/libparser/include/diceparser/parsingtoolbox.h
@@ -173,6 +173,7 @@ public:
static bool readComma(QString& str);
bool readRepeaterArguments(RepeaterNode* node, QString& source);
bool readRoundArguments(RoundNode* node, QString& source);
+ bool readListExpression(QString& str, ExecutionNode*& node);
bool readExpression(QString& str, ExecutionNode*& node);
bool readInstructionOperator(QChar c);
bool readNode(QString& str, ExecutionNode*& node);
diff --git a/src/libparser/node/executionnode.h b/src/libparser/node/executionnode.h
index a2912e3..6dba052 100644
--- a/src/libparser/node/executionnode.h
+++ b/src/libparser/node/executionnode.h
@@ -37,7 +37,7 @@ public:
/**
* @brief setNextNode
*/
- void setNextNode(ExecutionNode*);
+ virtual void setNextNode(ExecutionNode*);
/**
* @brief getNextNode
* @return
diff --git a/src/libparser/node/parenthesesnode.cpp b/src/libparser/node/parenthesesnode.cpp
index d122fe2..17db85a 100644
--- a/src/libparser/node/parenthesesnode.cpp
+++ b/src/libparser/node/parenthesesnode.cpp
@@ -39,6 +39,21 @@ void ParenthesesNode::run(ExecutionNode* previous)
temp= temp->getNextNode();
}
m_result= temp->getResult();
+
+ if(!m_nextNode)
+ return;
+
+ auto pNext= m_nextNode->getPriority();
+
+ if(!m_previousNode)
+ return;
+
+ auto previousNextNode= m_previousNode->getNextNode();
+ if(pNext < getPriority() && previousNextNode != this)
+ {
+ m_previousNode->setNextNode(m_nextNode);
+ m_nextNode= nullptr;
+ }
}
QString ParenthesesNode::toString(bool b) const
{
diff --git a/src/libparser/node/scalaroperatornode.cpp b/src/libparser/node/scalaroperatornode.cpp
index 40f725d..5a5e60b 100644
--- a/src/libparser/node/scalaroperatornode.cpp
+++ b/src/libparser/node/scalaroperatornode.cpp
@@ -21,7 +21,7 @@
***************************************************************************/
#include "scalaroperatornode.h"
-#include "result/diceresult.h"
+#include "include/diceparser/parsingtoolbox.h"
#include <QDebug>
ScalarOperatorNode::ScalarOperatorNode()
@@ -252,7 +252,7 @@ QMap<Dice::ERROR_CODE, QString> ScalarOperatorNode::getExecutionErrorMap()
if(nullptr != m_internalNode)
{
auto keys= m_internalNode->getExecutionErrorMap().keys();
- for(const auto& key : keys)
+ for(const auto& key : std::as_const(keys))
{
m_errors.insert(key, m_internalNode->getExecutionErrorMap().value(key));
}
@@ -260,7 +260,7 @@ QMap<Dice::ERROR_CODE, QString> ScalarOperatorNode::getExecutionErrorMap()
if(nullptr != m_nextNode)
{
auto keys= m_nextNode->getExecutionErrorMap().keys();
- for(auto const& key : keys)
+ for(auto const& key : std::as_const(keys))
{
m_errors.insert(key, m_nextNode->getExecutionErrorMap().value(key));
}
@@ -278,3 +278,15 @@ ExecutionNode* ScalarOperatorNode::getCopy() const
}
return node;
}
+
+void ScalarOperatorNode::setNextNode(ExecutionNode* node)
+{
+ if(node && node->getPriority() > getPriority())
+ {
+ auto temp= m_internalNode;
+ temp= ParsingToolBox::getLeafNode(temp);
+ temp->setNextNode(node);
+ }
+ else
+ ExecutionNode::setNextNode(node);
+}
diff --git a/src/libparser/node/scalaroperatornode.h b/src/libparser/node/scalaroperatornode.h
index 57a1049..73e0bef 100644
--- a/src/libparser/node/scalaroperatornode.h
+++ b/src/libparser/node/scalaroperatornode.h
@@ -50,7 +50,7 @@ public:
/**
* @brief run
*/
- virtual void run(ExecutionNode*);
+ virtual void run(ExecutionNode*) override;
/**
* @brief setInternalNode
* @param node
@@ -61,22 +61,22 @@ public:
* @param wl
* @return
*/
- virtual QString toString(bool wl) const;
+ virtual QString toString(bool wl) const override;
/**
* @brief getPriority
* @return
*/
- virtual qint64 getPriority() const;
+ virtual qint64 getPriority() const override;
/**
* @brief generateDotTree
* @param s
*/
- void generateDotTree(QString& s);
+ void generateDotTree(QString& s) override;
/**
* @brief getErrorList
* @return
*/
- virtual QMap<Dice::ERROR_CODE, QString> getExecutionErrorMap();
+ virtual QMap<Dice::ERROR_CODE, QString> getExecutionErrorMap() override;
/**
* @brief getArithmeticOperator
* @return
@@ -92,7 +92,10 @@ public:
* @brief getCopy
* @return
*/
- virtual ExecutionNode* getCopy() const;
+ virtual ExecutionNode* getCopy() const override;
+
+
+ void setNextNode(ExecutionNode* node) override;
private:
/**
diff --git a/src/libparser/parsingtoolbox.cpp b/src/libparser/parsingtoolbox.cpp
index 18cb402..23e0cbb 100644
--- a/src/libparser/parsingtoolbox.cpp
+++ b/src/libparser/parsingtoolbox.cpp
@@ -511,7 +511,6 @@ QStringList ParsingToolBox::allFirstResultAsString(bool& hasAlias) const
QStringList stringListResult;
for(auto node : m_startNodes)
{
- QVariant var;
auto stringPair= hasResultOfType(Dice::RESULT_TYPE::STRING, node);
auto scalarPair= hasResultOfType(Dice::RESULT_TYPE::SCALAR, node);
if(stringPair.first)
@@ -615,7 +614,7 @@ std::pair<QString, QString> ParsingToolBox::finalScalarResult() const
{
QStringList strLst;
auto listScalar= scalarResultsFromEachInstruction();
- for(auto val : listScalar)
+ for(auto val : std::as_const(listScalar))
{
strLst << number(val);
}
@@ -626,7 +625,7 @@ std::pair<QString, QString> ParsingToolBox::finalScalarResult() const
{
auto values= sumOfDiceResult();
QStringList strLst;
- for(auto val : values)
+ for(auto val : std::as_const(values))
{
strLst << number(val);
}
@@ -678,15 +677,15 @@ QStringList listOfDiceResult(const QList<ExportedDiceResult>& list, bool removeD
{
QStringList listOfDiceResult;
std::set<QString> alreadyAdded;
- for(auto map : list)
+ for(const auto& map : list)
{
for(auto key : map.keys())
{
auto listOfList= map.value(key);
- for(auto dice : listOfList)
+ for(auto dice : std::as_const(listOfList))
{
QString stringVal;
- for(auto val : dice)
+ for(const auto& val : dice)
{
if(removeDouble && (alreadyAdded.end() != alreadyAdded.find(val.uuid())))
continue;
@@ -1272,12 +1271,12 @@ QString ParsingToolBox::replacePlaceHolderFromJson(const QString& source, const
{
QStringList valuesStr;
auto multiKey= (map.size() > 1);
- for(auto item : map)
+ for(const auto& item : map)
{
auto face= item.first;
auto valueList= item.second;
QStringList strs;
- for(auto list : valueList)
+ for(const auto& list : valueList)
{
strs << list.join(",");
}
@@ -1376,7 +1375,6 @@ QString ParsingToolBox::replacePlaceHolderToValue(const QString& source, const Q
});
QString result;
- int start= source.size() - 1;
// qDebug() << "replacePlaceHolderToValue @@@:" << result << start << resultList << inst2Result;
for(auto const& pair : inst2Result)
@@ -1477,7 +1475,21 @@ bool ParsingToolBox::readRoundArguments(RoundNode* node, QString& source)
return false;
ExecutionNode* startNode= nullptr;
- auto instruction= readExpression(source, startNode);
+ auto instruction= readListExpression(source, startNode);
+
+ /*while(readExpression(source, next))
+ {
+ instruction= true;
+ if(!startNode && next)
+ startNode= next; // first node
+
+ if(last)
+ last->setNextNode(next);
+
+ last= getLeafNode(next);
+ next= nullptr;
+ }*/
+
if(startNode == nullptr || !instruction)
{
m_errorMap.insert(Dice::ERROR_CODE::BAD_SYNTAXE, QObject::tr("Can read the parameter for Round Function."));
@@ -1496,7 +1508,20 @@ bool ParsingToolBox::readExpression(QString& str, ExecutionNode*& node)
if(readOpenParentheses(str))
{
ExecutionNode* internalNode= nullptr;
- if(readExpression(str, internalNode))
+ bool hasExpression= readListExpression(str, internalNode);
+ /*while(readExpression(str, next))
+ {
+ hasExpression= true;
+ if(!internalNode && next)
+ internalNode= next; // first node
+
+ if(last)
+ last->setNextNode(next);
+
+ last= getLeafNode(next);
+ next= nullptr;
+ }*/
+ if(hasExpression)
{
ParenthesesNode* parentheseNode= new ParenthesesNode();
parentheseNode->setInternelNode(internalNode);
@@ -1546,13 +1571,11 @@ bool ParsingToolBox::readExpression(QString& str, ExecutionNode*& node)
}
node= operandNode;
- operandNode= ParsingToolBox::getLeafNode(operandNode);
- // ExecutionNode* operatorNode=nullptr;
+ /*operandNode= ParsingToolBox::getLeafNode(operandNode);
while(readOperator(str, operandNode))
{
- // operandNode->setNextNode(operatorNode);
operandNode= ParsingToolBox::getLeafNode(operandNode);
- }
+ }*/
return true;
}
else if(readCommand(str, operandNode))
@@ -2088,6 +2111,31 @@ bool ParsingToolBox::readReplaceValueNode(QString& str, ReplaceValueNode* node)
return res;
}
+bool ParsingToolBox::readListExpression(QString& str, ExecutionNode*& node)
+{
+ ExecutionNode* next= nullptr;
+ ExecutionNode* last= nullptr;
+ bool hasExpression= false;
+ bool firstLoop= true;
+ while(readExpression(str, next))
+ {
+ hasExpression= true;
+ if(firstLoop)
+ {
+ node= next;
+ firstLoop= false;
+ }
+
+ if(last)
+ last->setNextNode(next);
+
+ last= getLeafNode(next);
+ next= nullptr;
+ }
+
+ return hasExpression;
+}
+
bool ParsingToolBox::readBlocInstruction(QString& str, ExecutionNode*& resultnode)
{
if(str.startsWith('{'))
@@ -2101,8 +2149,10 @@ bool ParsingToolBox::readBlocInstruction(QString& str, ExecutionNode*& resultnod
scalarNode= new ScalarOperatorNode();
scalarNode->setArithmeticOperator(op);
}
- if(readExpression(str, node))
+
+ if(readListExpression(str, node))
{
+ // node= getLeafNode(node);
if(str.startsWith('}'))
{
if(nullptr == scalarNode)
@@ -2330,7 +2380,8 @@ bool ParsingToolBox::readOperator(QString& str, ExecutionNode* previous)
nodeExec->setNextNode(nullptr);
}
- // nodeResult = node;
+ // if(node->getPriority() > previous->getPriority() && previous->)
+
previous->setNextNode(node);
result= true;
diff --git a/src/tests/dice/tst_dice.cpp b/src/tests/dice/tst_dice.cpp
index 0332504..eb07e57 100644
--- a/src/tests/dice/tst_dice.cpp
+++ b/src/tests/dice/tst_dice.cpp
@@ -481,7 +481,7 @@ void TestDice::wrongCommandsExecutionTimeTest()
<< "10d10k11"
<< "!!!!";
- for(QString cmd : commands)
+ for(QString cmd : std::as_const(commands))
{
bool test= m_diceParser->parseLine(cmd);
m_diceParser->start();
@@ -603,6 +603,8 @@ void TestDice::mathPriority_data()
QTest::addRow("cmd6") << "10*(3*2)" << 60;
QTest::addRow("cmd7") << "60/(3*2)" << 10;
QTest::addRow("cmd8") << "5-(5*5+5)" << -25;
+ QTest::addRow("cmd9") << "5-(5*5+5)" << -25;
+ QTest::addRow("cmd10") << "2*(5)+1" << 11;
}
void TestDice::dangerousCommandsTest()
@@ -1236,6 +1238,7 @@ void TestDice::ifCommandTest()
auto strResultExpected= startExperted[index];
auto resultText= strResult;
+ qDebug() << "debug: result" << resultText << strResultExpected << results;
QVERIFY2(resultText.startsWith(strResultExpected),
QString("string result does not fit the expectation %1").arg(cmd).toStdString().c_str());
}
@@ -1252,6 +1255,7 @@ void TestDice::ifCommandTest_data()
"[%2]\"}{\"Failure: %1 [%2]\"}}"
<< Dice::CompareOperator::GreaterOrEqual << QList<int>({15, 10, 1})
<< QStringList({"Complete Success:", "Success with Complications:", "Failure:"});
+
QTest::addRow("cmd2") << "2d10;$1i:[>=15]{\"Complete Success: %1 [%2]\"}{$1i:[>=10]{\"Success "
"with Complications: %1 "
"[%2]\"}{\"Failure: %1 [%2]\"}}"