From 27bf74462b977f0d506b7963703efd47e4e8ae98 Mon Sep 17 00:00:00 2001 From: Anna Zinovyeva Date: Sat, 5 Jun 2021 13:49:10 +0300 Subject: [PATCH 01/12] hmm.. it was not good --- qrutils/graphUtils/deepFirstSearcher.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qrutils/graphUtils/deepFirstSearcher.cpp b/qrutils/graphUtils/deepFirstSearcher.cpp index 5419ac0cf6..2e04c6f25a 100644 --- a/qrutils/graphUtils/deepFirstSearcher.cpp +++ b/qrutils/graphUtils/deepFirstSearcher.cpp @@ -69,7 +69,7 @@ void DeepFirstSearcher::dfs(const Id &id, const QList &visit } for (const LinkInfo &link : linkInfos) { - if (!link.targetVisited && link.connected && !mSearchTerminated) { + if (!mVisitedNodes.contains(link.target) && link.connected && !mSearchTerminated) { dfs(link.target, visitors); } } From 9dcbd672000ed499a2e54c596375e65094daaba4 Mon Sep 17 00:00:00 2001 From: Anna Zinovyeva Date: Sat, 5 Jun 2021 14:34:15 +0300 Subject: [PATCH 02/12] add draft version of new structural generator --- .../ev3GeneratorBase/ev3GeneratorFactory.h | 1 + .../src/ev3GeneratorCustomizer.cpp | 3 +- .../src/ev3GeneratorCustomizer.h | 1 + .../src/ev3GeneratorFactory.cpp | 3 +- .../src/ev3MasterGeneratorBase.cpp | 4 +- .../ev3RbfGeneratorCustomizer.cpp | 3 +- .../ev3RbfGeneratorCustomizer.h | 1 + .../ev3RbfGeneratorFactory.cpp | 3 +- .../ev3RbfGenerator/ev3RbfGeneratorFactory.h | 1 + .../ev3RbfGenerator/ev3RbfMasterGenerator.cpp | 2 +- .../generatorBase/generatorBase.pri | 44 +- .../generatorBase/generatorFactoryBase.h | 17 +- .../generatorBase/masterGeneratorBase.h | 5 + .../generatorBase/semanticTree/ifNode.h | 6 + .../generatorBase/semanticTree/simpleNode.h | 3 + .../generatorBase/semanticTree/switchNode.h | 2 + .../src/generatorFactoryBase.cpp | 17 +- .../generatorBase/src/masterGeneratorBase.cpp | 4 + .../src/readableLabelManager.cpp} | 13 +- .../src/readableLabelManager.h} | 6 +- .../generatorBase/src/semanticTree/ifNode.cpp | 24 +- .../src/semanticTree/simpleNode.cpp | 10 + .../src/semanticTree/switchNode.cpp | 11 + .../simpleGenerators/syntheticIfGenerator.cpp | 53 ++ .../simpleGenerators/syntheticIfGenerator.h | 49 ++ .../syntheticVariableNameGenerator.cpp | 19 + .../syntheticVariableNameGenerator.h | 23 + .../src/structuralControlFlowGenerator.cpp | 583 ++++-------- .../src/structuralControlFlowGenerator.h | 85 +- .../generatorBase/src/structurizator.cpp | 826 ------------------ .../generatorBase/src/structurizator.h | 145 --- .../blockStructurizatorNode.cpp | 57 -- .../blockStructurizatorNode.h | 41 - .../breakStructurizatorNode.cpp | 40 - .../breakStructurizatorNode.h | 36 - .../ifStructurizatorNode.cpp | 70 -- .../ifStructurizatorNode.h | 47 - .../intermediateStructurizatorNode.cpp | 33 - .../intermediateStructurizatorNode.h | 51 -- .../selfLoopStructurizatorNode.cpp | 49 -- .../selfLoopStructurizatorNode.h | 37 - .../simpleStructurizatorNode.cpp | 44 - .../simpleStructurizatorNode.h | 37 - .../structurizatorNodeWithBreaks.cpp | 63 -- .../structurizatorNodeWithBreaks.h | 44 - .../switchStructurizatorNode.cpp | 68 -- .../switchStructurizatorNode.h | 44 - .../whileStructurizatorNode.cpp | 64 -- .../whileStructurizatorNode.h | 44 - .../generatorBase/src/structurizer.cpp | 199 +++++ .../generatorBase/src/structurizer.h | 45 + .../breakStructurizerNode.cpp | 23 + .../structurizerNodes/breakStructurizerNode.h | 19 + .../continuationStructurizerNode.cpp | 102 +++ .../continuationStructurizerNode.h | 42 + .../src/structurizerNodes/elementNode.cpp | 436 +++++++++ .../src/structurizerNodes/elementNode.h | 49 ++ .../structurizerNodes/ifStructurizerNode.cpp | 203 +++++ .../structurizerNodes/ifStructurizerNode.h | 53 ++ .../loopStructurizerNode.cpp | 139 +++ .../structurizerNodes/loopStructurizerNode.h | 51 ++ .../sequenceStructurizerNode.cpp | 367 ++++++++ .../sequenceStructurizerNode.h | 44 + .../simpleStructurizerNode.cpp | 98 +++ .../simpleStructurizerNode.h | 41 + .../structurizerNodes/structurizerNode.cpp | 182 ++++ .../src/structurizerNodes/structurizerNode.h | 87 ++ .../switchStructurizerNode.cpp | 228 +++++ .../switchStructurizerNode.h | 52 ++ .../nxtGeneratorBase/nxtGeneratorFactory.h | 1 + .../src/nxtGeneratorCustomizer.cpp | 3 +- .../src/nxtGeneratorCustomizer.h | 1 + .../src/nxtGeneratorFactory.cpp | 3 +- .../src/nxtMasterGeneratorBase.cpp | 2 +- .../pioneerLuaGenerator.pro | 2 - .../pioneerLuaGeneratorCustomizer.cpp | 4 +- .../pioneerLuaGeneratorCustomizer.h | 3 +- .../pioneerLuaGeneratorFactory.cpp | 13 +- .../pioneerLuaGeneratorFactory.h | 9 +- .../pioneerLuaMasterGenerator.cpp | 6 +- .../pioneerLuaMasterGenerator.h | 5 +- .../simpleGenerators/gotoGenerator.cpp | 6 +- .../simpleGenerators/gotoGenerator.h | 5 +- .../simpleGenerators/labelGenerator.cpp | 6 +- .../simpleGenerators/labelGenerator.h | 5 +- .../src/trikGeneratorCustomizer.cpp | 3 +- .../src/trikGeneratorCustomizer.h | 1 + .../src/trikGeneratorFactory.cpp | 3 +- .../src/trikGeneratorFactory.h | 1 + .../src/trikMasterGeneratorBase.cpp | 2 +- 90 files changed, 2970 insertions(+), 2410 deletions(-) rename plugins/robots/generators/{pioneer/pioneerLuaGenerator/generators/gotoLabelManager.cpp => generatorBase/src/readableLabelManager.cpp} (79%) rename plugins/robots/generators/{pioneer/pioneerLuaGenerator/generators/gotoLabelManager.h => generatorBase/src/readableLabelManager.h} (94%) create mode 100644 plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticIfGenerator.cpp create mode 100644 plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticIfGenerator.h create mode 100644 plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticVariableNameGenerator.cpp create mode 100644 plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticVariableNameGenerator.h delete mode 100644 plugins/robots/generators/generatorBase/src/structurizator.cpp delete mode 100644 plugins/robots/generators/generatorBase/src/structurizator.h delete mode 100644 plugins/robots/generators/generatorBase/src/structurizatorNodes/blockStructurizatorNode.cpp delete mode 100644 plugins/robots/generators/generatorBase/src/structurizatorNodes/blockStructurizatorNode.h delete mode 100644 plugins/robots/generators/generatorBase/src/structurizatorNodes/breakStructurizatorNode.cpp delete mode 100644 plugins/robots/generators/generatorBase/src/structurizatorNodes/breakStructurizatorNode.h delete mode 100644 plugins/robots/generators/generatorBase/src/structurizatorNodes/ifStructurizatorNode.cpp delete mode 100644 plugins/robots/generators/generatorBase/src/structurizatorNodes/ifStructurizatorNode.h delete mode 100644 plugins/robots/generators/generatorBase/src/structurizatorNodes/intermediateStructurizatorNode.cpp delete mode 100644 plugins/robots/generators/generatorBase/src/structurizatorNodes/intermediateStructurizatorNode.h delete mode 100644 plugins/robots/generators/generatorBase/src/structurizatorNodes/selfLoopStructurizatorNode.cpp delete mode 100644 plugins/robots/generators/generatorBase/src/structurizatorNodes/selfLoopStructurizatorNode.h delete mode 100644 plugins/robots/generators/generatorBase/src/structurizatorNodes/simpleStructurizatorNode.cpp delete mode 100644 plugins/robots/generators/generatorBase/src/structurizatorNodes/simpleStructurizatorNode.h delete mode 100644 plugins/robots/generators/generatorBase/src/structurizatorNodes/structurizatorNodeWithBreaks.cpp delete mode 100644 plugins/robots/generators/generatorBase/src/structurizatorNodes/structurizatorNodeWithBreaks.h delete mode 100644 plugins/robots/generators/generatorBase/src/structurizatorNodes/switchStructurizatorNode.cpp delete mode 100644 plugins/robots/generators/generatorBase/src/structurizatorNodes/switchStructurizatorNode.h delete mode 100644 plugins/robots/generators/generatorBase/src/structurizatorNodes/whileStructurizatorNode.cpp delete mode 100644 plugins/robots/generators/generatorBase/src/structurizatorNodes/whileStructurizatorNode.h create mode 100644 plugins/robots/generators/generatorBase/src/structurizer.cpp create mode 100644 plugins/robots/generators/generatorBase/src/structurizer.h create mode 100644 plugins/robots/generators/generatorBase/src/structurizerNodes/breakStructurizerNode.cpp create mode 100644 plugins/robots/generators/generatorBase/src/structurizerNodes/breakStructurizerNode.h create mode 100644 plugins/robots/generators/generatorBase/src/structurizerNodes/continuationStructurizerNode.cpp create mode 100644 plugins/robots/generators/generatorBase/src/structurizerNodes/continuationStructurizerNode.h create mode 100644 plugins/robots/generators/generatorBase/src/structurizerNodes/elementNode.cpp create mode 100644 plugins/robots/generators/generatorBase/src/structurizerNodes/elementNode.h create mode 100644 plugins/robots/generators/generatorBase/src/structurizerNodes/ifStructurizerNode.cpp create mode 100644 plugins/robots/generators/generatorBase/src/structurizerNodes/ifStructurizerNode.h create mode 100644 plugins/robots/generators/generatorBase/src/structurizerNodes/loopStructurizerNode.cpp create mode 100644 plugins/robots/generators/generatorBase/src/structurizerNodes/loopStructurizerNode.h create mode 100644 plugins/robots/generators/generatorBase/src/structurizerNodes/sequenceStructurizerNode.cpp create mode 100644 plugins/robots/generators/generatorBase/src/structurizerNodes/sequenceStructurizerNode.h create mode 100644 plugins/robots/generators/generatorBase/src/structurizerNodes/simpleStructurizerNode.cpp create mode 100644 plugins/robots/generators/generatorBase/src/structurizerNodes/simpleStructurizerNode.h create mode 100644 plugins/robots/generators/generatorBase/src/structurizerNodes/structurizerNode.cpp create mode 100644 plugins/robots/generators/generatorBase/src/structurizerNodes/structurizerNode.h create mode 100644 plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.cpp create mode 100644 plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.h diff --git a/plugins/robots/generators/ev3/ev3GeneratorBase/include/ev3GeneratorBase/ev3GeneratorFactory.h b/plugins/robots/generators/ev3/ev3GeneratorBase/include/ev3GeneratorBase/ev3GeneratorFactory.h index bff76dce3a..fcb277bb57 100644 --- a/plugins/robots/generators/ev3/ev3GeneratorBase/include/ev3GeneratorBase/ev3GeneratorFactory.h +++ b/plugins/robots/generators/ev3/ev3GeneratorBase/include/ev3GeneratorBase/ev3GeneratorFactory.h @@ -29,6 +29,7 @@ class ROBOTS_EV3_GENERATOR_BASE_EXPORT Ev3GeneratorFactory : public generatorBas , qReal::ErrorReporterInterface &errorReporter , const kitBase::robotModel::RobotModelManagerInterface &robotModelManager , generatorBase::lua::LuaProcessor &luaProcessor + , generatorBase::ReadableLabelManager &readableLabelManager , const QString &generatorName); ~Ev3GeneratorFactory() override; diff --git a/plugins/robots/generators/ev3/ev3GeneratorBase/src/ev3GeneratorCustomizer.cpp b/plugins/robots/generators/ev3/ev3GeneratorBase/src/ev3GeneratorCustomizer.cpp index 23fc4596c4..253b8929e9 100644 --- a/plugins/robots/generators/ev3/ev3GeneratorBase/src/ev3GeneratorCustomizer.cpp +++ b/plugins/robots/generators/ev3/ev3GeneratorBase/src/ev3GeneratorCustomizer.cpp @@ -20,9 +20,10 @@ Ev3GeneratorCustomizer::Ev3GeneratorCustomizer(const qrRepo::RepoApi &repo , qReal::ErrorReporterInterface &errorReporter , const kitBase::robotModel::RobotModelManagerInterface &robotModelManager , generatorBase::lua::LuaProcessor &luaProcessor + , generatorBase::ReadableLabelManager &readableLabelManager , const QString &generatorName , bool supportsSwitchUnstableToBreaks) - : mFactory(repo, errorReporter, robotModelManager, luaProcessor, generatorName) + : mFactory(repo, errorReporter, robotModelManager, luaProcessor, readableLabelManager, generatorName) , mSupportsSwitchUnstableToBreaks(supportsSwitchUnstableToBreaks) { } diff --git a/plugins/robots/generators/ev3/ev3GeneratorBase/src/ev3GeneratorCustomizer.h b/plugins/robots/generators/ev3/ev3GeneratorBase/src/ev3GeneratorCustomizer.h index 70e761b1dc..401b53be64 100644 --- a/plugins/robots/generators/ev3/ev3GeneratorBase/src/ev3GeneratorCustomizer.h +++ b/plugins/robots/generators/ev3/ev3GeneratorBase/src/ev3GeneratorCustomizer.h @@ -27,6 +27,7 @@ class Ev3GeneratorCustomizer : public generatorBase::GeneratorCustomizer , qReal::ErrorReporterInterface &errorReporter , const kitBase::robotModel::RobotModelManagerInterface &robotModelManager , generatorBase::lua::LuaProcessor &luaProcessor + , generatorBase::ReadableLabelManager &readableLabelManager , const QString &generatorName , bool supportsSwitchUnstableToBreaks); diff --git a/plugins/robots/generators/ev3/ev3GeneratorBase/src/ev3GeneratorFactory.cpp b/plugins/robots/generators/ev3/ev3GeneratorBase/src/ev3GeneratorFactory.cpp index fbd18410f1..78bb0380e3 100644 --- a/plugins/robots/generators/ev3/ev3GeneratorBase/src/ev3GeneratorFactory.cpp +++ b/plugins/robots/generators/ev3/ev3GeneratorBase/src/ev3GeneratorFactory.cpp @@ -53,8 +53,9 @@ Ev3GeneratorFactory::Ev3GeneratorFactory(const qrRepo::RepoApi &repo , qReal::ErrorReporterInterface &errorReporter , const kitBase::robotModel::RobotModelManagerInterface &robotModelManager , generatorBase::lua::LuaProcessor &luaProcessor + , generatorBase::ReadableLabelManager &readableLabelManager , const QString &generatorName) - : GeneratorFactoryBase(repo, errorReporter, robotModelManager, luaProcessor) + : GeneratorFactoryBase(repo, errorReporter, robotModelManager, luaProcessor, readableLabelManager) , mGeneratorName(generatorName) , mMailboxes({":/" + mGeneratorName + "/templates"}) { diff --git a/plugins/robots/generators/ev3/ev3GeneratorBase/src/ev3MasterGeneratorBase.cpp b/plugins/robots/generators/ev3/ev3GeneratorBase/src/ev3MasterGeneratorBase.cpp index 5d90020eae..8d40f72f76 100644 --- a/plugins/robots/generators/ev3/ev3GeneratorBase/src/ev3MasterGeneratorBase.cpp +++ b/plugins/robots/generators/ev3/ev3GeneratorBase/src/ev3MasterGeneratorBase.cpp @@ -32,8 +32,8 @@ Ev3MasterGeneratorBase::Ev3MasterGeneratorBase(const qrRepo::RepoApi &repo generatorBase::GeneratorCustomizer *Ev3MasterGeneratorBase::createCustomizer() { - return new Ev3GeneratorCustomizer(mRepo, mErrorReporter, mRobotModelManager, *createLuaProcessor(), - mGeneratorName, supportsSwitchUnstableToBreaks()); + return new Ev3GeneratorCustomizer(mRepo, mErrorReporter, mRobotModelManager, *createLuaProcessor() + , *mReadableLabelManager, mGeneratorName, supportsSwitchUnstableToBreaks()); } void Ev3MasterGeneratorBase::beforeGeneration() diff --git a/plugins/robots/generators/ev3/ev3RbfGenerator/ev3RbfGeneratorCustomizer.cpp b/plugins/robots/generators/ev3/ev3RbfGenerator/ev3RbfGeneratorCustomizer.cpp index 018e69920c..b96da7c204 100644 --- a/plugins/robots/generators/ev3/ev3RbfGenerator/ev3RbfGeneratorCustomizer.cpp +++ b/plugins/robots/generators/ev3/ev3RbfGenerator/ev3RbfGeneratorCustomizer.cpp @@ -20,9 +20,10 @@ Ev3RbfGeneratorCustomizer::Ev3RbfGeneratorCustomizer(const qrRepo::RepoApi &repo , qReal::ErrorReporterInterface &errorReporter , const kitBase::robotModel::RobotModelManagerInterface &robotModelManager , generatorBase::lua::LuaProcessor &luaProcessor + , generatorBase::ReadableLabelManager &readableLabelManager , const QString &generatorName , bool supportsSwitchUnstableToBreaks) - : mFactory(repo, errorReporter, robotModelManager, luaProcessor, generatorName) + : mFactory(repo, errorReporter, robotModelManager, luaProcessor, readableLabelManager, generatorName) , mSupportsSwitchUnstableToBreaks(supportsSwitchUnstableToBreaks) { } diff --git a/plugins/robots/generators/ev3/ev3RbfGenerator/ev3RbfGeneratorCustomizer.h b/plugins/robots/generators/ev3/ev3RbfGenerator/ev3RbfGeneratorCustomizer.h index 764d6582cc..09bd5a9062 100644 --- a/plugins/robots/generators/ev3/ev3RbfGenerator/ev3RbfGeneratorCustomizer.h +++ b/plugins/robots/generators/ev3/ev3RbfGenerator/ev3RbfGeneratorCustomizer.h @@ -28,6 +28,7 @@ class Ev3RbfGeneratorCustomizer : public generatorBase::GeneratorCustomizer , qReal::ErrorReporterInterface &errorReporter , const kitBase::robotModel::RobotModelManagerInterface &robotModelManager , generatorBase::lua::LuaProcessor &luaProcessor + , generatorBase::ReadableLabelManager &readableLabelManager , const QString &generatorName , bool supportsSwitchUnstableToBreaks); diff --git a/plugins/robots/generators/ev3/ev3RbfGenerator/ev3RbfGeneratorFactory.cpp b/plugins/robots/generators/ev3/ev3RbfGenerator/ev3RbfGeneratorFactory.cpp index 4d1708efb4..5b63354925 100644 --- a/plugins/robots/generators/ev3/ev3RbfGenerator/ev3RbfGeneratorFactory.cpp +++ b/plugins/robots/generators/ev3/ev3RbfGenerator/ev3RbfGeneratorFactory.cpp @@ -22,8 +22,9 @@ Ev3RbfGeneratorFactory::Ev3RbfGeneratorFactory(const qrRepo::RepoApi &repo , qReal::ErrorReporterInterface &errorReporter , const kitBase::robotModel::RobotModelManagerInterface &robotModelManager , generatorBase::lua::LuaProcessor &luaProcessor + , generatorBase::ReadableLabelManager &readableLabelManager , const QString &generatorName) - : Ev3GeneratorFactory(repo, errorReporter, robotModelManager, luaProcessor, generatorName) + : Ev3GeneratorFactory(repo, errorReporter, robotModelManager, luaProcessor, readableLabelManager, generatorName) { } diff --git a/plugins/robots/generators/ev3/ev3RbfGenerator/ev3RbfGeneratorFactory.h b/plugins/robots/generators/ev3/ev3RbfGenerator/ev3RbfGeneratorFactory.h index 8c8e28e4a1..cdfd339fd3 100644 --- a/plugins/robots/generators/ev3/ev3RbfGenerator/ev3RbfGeneratorFactory.h +++ b/plugins/robots/generators/ev3/ev3RbfGenerator/ev3RbfGeneratorFactory.h @@ -27,6 +27,7 @@ class Ev3RbfGeneratorFactory : public Ev3GeneratorFactory , qReal::ErrorReporterInterface &errorReporter , const kitBase::robotModel::RobotModelManagerInterface &robotModelManager , generatorBase::lua::LuaProcessor &luaProcessor + , generatorBase::ReadableLabelManager &readableLabelManager , const QString &generatorName); generatorBase::simple::AbstractSimpleGenerator *labelGenerator(const qReal::Id &id diff --git a/plugins/robots/generators/ev3/ev3RbfGenerator/ev3RbfMasterGenerator.cpp b/plugins/robots/generators/ev3/ev3RbfGenerator/ev3RbfMasterGenerator.cpp index db188dec86..0a408248b1 100644 --- a/plugins/robots/generators/ev3/ev3RbfGenerator/ev3RbfMasterGenerator.cpp +++ b/plugins/robots/generators/ev3/ev3RbfGenerator/ev3RbfMasterGenerator.cpp @@ -153,5 +153,5 @@ generatorBase::lua::LuaProcessor *Ev3RbfMasterGenerator::createLuaProcessor() GeneratorCustomizer *Ev3RbfMasterGenerator::createCustomizer() { return new Ev3RbfGeneratorCustomizer(mRepo, mErrorReporter - , mRobotModelManager, *createLuaProcessor(), mGeneratorName, supportsSwitchUnstableToBreaks()); + , mRobotModelManager, *createLuaProcessor(), *mReadableLabelManager, mGeneratorName, supportsSwitchUnstableToBreaks()); } diff --git a/plugins/robots/generators/generatorBase/generatorBase.pri b/plugins/robots/generators/generatorBase/generatorBase.pri index 956daa1cee..93d8cf153d 100644 --- a/plugins/robots/generators/generatorBase/generatorBase.pri +++ b/plugins/robots/generators/generatorBase/generatorBase.pri @@ -65,22 +65,25 @@ HEADERS += \ $$PWD/include/generatorBase/lua/reservedFunctionsConverter.h \ $$PWD/include/generatorBase/gotoControlFlowGenerator.h \ $$PWD/src/converters/dynamicPropertiesConverter.h \ + $$PWD/src/readableLabelManager.h \ + $$PWD/src/simpleGenerators/syntheticIfGenerator.h \ + $$PWD/src/simpleGenerators/syntheticVariableNameGenerator.h \ $$PWD/src/structuralControlFlowGenerator.h \ - $$PWD/src/structurizator.h \ + $$PWD/src/structurizer.h \ + $$PWD/src/structurizerNodes/breakStructurizerNode.h \ + $$PWD/src/structurizerNodes/continuationStructurizerNode.h \ + $$PWD/src/structurizerNodes/ifStructurizerNode.h \ + $$PWD/src/structurizerNodes/loopStructurizerNode.h \ + $$PWD/src/structurizerNodes/sequenceStructurizerNode.h \ + $$PWD/src/structurizerNodes/simpleStructurizerNode.h \ + $$PWD/src/structurizerNodes/structurizerNode.h \ + $$PWD/src/structurizerNodes/switchStructurizerNode.h \ HEADERS += \ - $$PWD/src/structurizatorNodes/intermediateStructurizatorNode.h \ - $$PWD/src/structurizatorNodes/simpleStructurizatorNode.h \ - $$PWD/src/structurizatorNodes/breakStructurizatorNode.h \ - $$PWD/src/structurizatorNodes/ifStructurizatorNode.h \ - $$PWD/src/structurizatorNodes/structurizatorNodeWithBreaks.h \ - $$PWD/src/structurizatorNodes/switchStructurizatorNode.h \ - $$PWD/src/structurizatorNodes/blockStructurizatorNode.h \ - $$PWD/src/structurizatorNodes/whileStructurizatorNode.h \ - $$PWD/src/structurizatorNodes/selfLoopStructurizatorNode.h \ SOURCES += \ + $$PWD/src/readableLabelManager.cpp \ $$PWD/src/robotsGeneratorPluginBase.cpp \ $$PWD/src/masterGeneratorBase.cpp \ $$PWD/src/generatorCustomizer.cpp \ @@ -88,6 +91,16 @@ SOURCES += \ $$PWD/src/robotsDiagramVisitor.cpp \ $$PWD/src/primaryControlFlowValidator.cpp \ $$PWD/src/generatorFactoryBase.cpp \ + $$PWD/src/simpleGenerators/syntheticIfGenerator.cpp \ + $$PWD/src/simpleGenerators/syntheticVariableNameGenerator.cpp \ + $$PWD/src/structurizerNodes/breakStructurizerNode.cpp \ + $$PWD/src/structurizerNodes/continuationStructurizerNode.cpp \ + $$PWD/src/structurizerNodes/ifStructurizerNode.cpp \ + $$PWD/src/structurizerNodes/loopStructurizerNode.cpp \ + $$PWD/src/structurizerNodes/sequenceStructurizerNode.cpp \ + $$PWD/src/structurizerNodes/simpleStructurizerNode.cpp \ + $$PWD/src/structurizerNodes/structurizerNode.cpp \ + $$PWD/src/structurizerNodes/switchStructurizerNode.cpp \ $$PWD/src/templateParametrizedEntity.cpp \ $$PWD/src/parts/variables.cpp \ $$PWD/src/parts/subprograms.cpp \ @@ -113,7 +126,7 @@ SOURCES += \ $$PWD/src/gotoControlFlowGenerator.cpp \ $$PWD/src/converters/dynamicPropertiesConverter.cpp \ $$PWD/src/structuralControlFlowGenerator.cpp \ - $$PWD/src/structurizator.cpp \ + $$PWD/src/structurizer.cpp \ # Simple element generators & converters @@ -253,12 +266,3 @@ SOURCES += \ $$PWD/src/lua/precedenceConverter.cpp \ SOURCES += \ - $$PWD/src/structurizatorNodes/intermediateStructurizatorNode.cpp \ - $$PWD/src/structurizatorNodes/simpleStructurizatorNode.cpp \ - $$PWD/src/structurizatorNodes/breakStructurizatorNode.cpp \ - $$PWD/src/structurizatorNodes/ifStructurizatorNode.cpp \ - $$PWD/src/structurizatorNodes/structurizatorNodeWithBreaks.cpp \ - $$PWD/src/structurizatorNodes/switchStructurizatorNode.cpp \ - $$PWD/src/structurizatorNodes/blockStructurizatorNode.cpp \ - $$PWD/src/structurizatorNodes/whileStructurizatorNode.cpp \ - $$PWD/src/structurizatorNodes/selfLoopStructurizatorNode.cpp \ diff --git a/plugins/robots/generators/generatorBase/include/generatorBase/generatorFactoryBase.h b/plugins/robots/generators/generatorBase/include/generatorBase/generatorFactoryBase.h index 4d6cdd3dd9..529c4ab3e2 100644 --- a/plugins/robots/generators/generatorBase/include/generatorBase/generatorFactoryBase.h +++ b/plugins/robots/generators/generatorBase/include/generatorBase/generatorFactoryBase.h @@ -42,6 +42,7 @@ class LuaProcessor; } class GeneratorCustomizer; +class ReadableLabelManager; /// This class must be inherited in each concrete generator. Implementation /// must specify every generator part (starting from simple block generators @@ -53,7 +54,8 @@ class ROBOTS_GENERATOR_EXPORT GeneratorFactoryBase : public QObject GeneratorFactoryBase(const qrRepo::RepoApi &repo , qReal::ErrorReporterInterface &errorReporter , const kitBase::robotModel::RobotModelManagerInterface &robotModelManager - , lua::LuaProcessor &luaProcessor); + , lua::LuaProcessor &luaProcessor + , ReadableLabelManager &readableLabelManager); virtual ~GeneratorFactoryBase(); @@ -97,6 +99,14 @@ class ROBOTS_GENERATOR_EXPORT GeneratorFactoryBase : public QObject , bool elseIsEmpty , bool needInverting); + /// Returns a pointer to a code generator for blocks with if semantics + virtual simple::AbstractSimpleGenerator *syntheticIfGenerator(const qReal::Id &id + , const QMap &ids + , GeneratorCustomizer &customizer + , bool elseIsEmpty + , QString syntheticCondition + , bool needInverting); + /// Returns a pointer to a code generator for infinite loops virtual simple::AbstractSimpleGenerator *infiniteLoopGenerator(const qReal::Id &id , GeneratorCustomizer &customizer); @@ -147,6 +157,10 @@ class ROBOTS_GENERATOR_EXPORT GeneratorFactoryBase : public QObject virtual simple::AbstractSimpleGenerator *labelGenerator(const qReal::Id &id , GeneratorCustomizer &customizer); + /// Returns a pointer to a code generator for goto label declaration + virtual simple::AbstractSimpleGenerator *syntheticVariableNameGenerator(const qReal::Id &id + , GeneratorCustomizer &customizer); + /// Returns a pointer to a code generator for 'goto' instruction virtual simple::AbstractSimpleGenerator *gotoSimpleGenerator(const qReal::Id &id , GeneratorCustomizer &customizer); @@ -276,6 +290,7 @@ class ROBOTS_GENERATOR_EXPORT GeneratorFactoryBase : public QObject QScopedPointer mSensors; QScopedPointer mFunctions; QScopedPointer mDeviceVariables; + ReadableLabelManager &mReadableLabelManager; int mLoopGeneratorIndex { 0 }; }; diff --git a/plugins/robots/generators/generatorBase/include/generatorBase/masterGeneratorBase.h b/plugins/robots/generators/generatorBase/include/generatorBase/masterGeneratorBase.h index d0db8b7df2..b7ee74bef9 100644 --- a/plugins/robots/generators/generatorBase/include/generatorBase/masterGeneratorBase.h +++ b/plugins/robots/generators/generatorBase/include/generatorBase/masterGeneratorBase.h @@ -25,6 +25,8 @@ #include "templateParametrizedEntity.h" #include "primaryControlFlowValidator.h" +#include "src/readableLabelManager.h" + class QFileInfo; namespace utils { @@ -114,6 +116,9 @@ class ROBOTS_GENERATOR_EXPORT MasterGeneratorBase : public QObject, public Templ QString mProjectDir; int mCurInitialNodeNumber {}; const utils::ParserErrorReporter &mParserErrorReporter; + + /// Storage and generator for human-readable goto labels. + QScopedPointer mReadableLabelManager; }; } diff --git a/plugins/robots/generators/generatorBase/include/generatorBase/semanticTree/ifNode.h b/plugins/robots/generators/generatorBase/include/generatorBase/semanticTree/ifNode.h index afef75a224..d8ae256445 100644 --- a/plugins/robots/generators/generatorBase/include/generatorBase/semanticTree/ifNode.h +++ b/plugins/robots/generators/generatorBase/include/generatorBase/semanticTree/ifNode.h @@ -26,6 +26,7 @@ class ROBOTS_GENERATOR_EXPORT IfNode : public ConditionalNode { public: explicit IfNode(const qReal::Id &idBinded, QObject *parent = nullptr); + explicit IfNode(QObject *parent = nullptr); ZoneNode *thenZone(); ZoneNode *elseZone(); @@ -33,6 +34,8 @@ class ROBOTS_GENERATOR_EXPORT IfNode : public ConditionalNode /// Will be called when both branches link to same block, making thus if statement unnesesary. void transformToSimple(); + void setSyntheticCondition(const QString &s, const QMap &l); + protected: QLinkedList children() const override; QString toStringImpl(GeneratorCustomizer &customizer, int indent, const QString &indentString) const override; @@ -41,6 +44,9 @@ class ROBOTS_GENERATOR_EXPORT IfNode : public ConditionalNode ZoneNode *mThenZone; // Takes ownership ZoneNode *mElseZone; // Takes ownership bool mIsSimple; + bool mIsSynthetic; + QString mSyntheticCondition; + QMap mIdWasUsedBefore; }; } diff --git a/plugins/robots/generators/generatorBase/include/generatorBase/semanticTree/simpleNode.h b/plugins/robots/generators/generatorBase/include/generatorBase/semanticTree/simpleNode.h index f462c97382..436da22c48 100644 --- a/plugins/robots/generators/generatorBase/include/generatorBase/semanticTree/simpleNode.h +++ b/plugins/robots/generators/generatorBase/include/generatorBase/semanticTree/simpleNode.h @@ -33,6 +33,7 @@ class ROBOTS_GENERATOR_EXPORT SimpleNode : public NonZoneNode , breakNode , continueNode , gotoNode + , tempVariableNode }; explicit SimpleNode(const qReal::Id &idBinded, QObject *parent = nullptr); @@ -41,6 +42,8 @@ class ROBOTS_GENERATOR_EXPORT SimpleNode : public NonZoneNode void bindToSyntheticConstruction(SyntheticBlockType type); static SimpleNode *createBreakNode(QObject *parent); + static SimpleNode *createSyntheticVariableNode(const qReal::Id &id, QObject *parent); + protected: QLinkedList children() const override; diff --git a/plugins/robots/generators/generatorBase/include/generatorBase/semanticTree/switchNode.h b/plugins/robots/generators/generatorBase/include/generatorBase/semanticTree/switchNode.h index 36e1410ee7..812d80e105 100644 --- a/plugins/robots/generators/generatorBase/include/generatorBase/semanticTree/switchNode.h +++ b/plugins/robots/generators/generatorBase/include/generatorBase/semanticTree/switchNode.h @@ -43,6 +43,8 @@ class ROBOTS_GENERATOR_EXPORT SwitchNode : public NonZoneNode void setGenerateIfs(); + ZoneNode *branchZoneByValue(const QString &value); + protected: QLinkedList children() const override; QString toStringImpl(GeneratorCustomizer &customizer, int indent, const QString &indentString) const override; diff --git a/plugins/robots/generators/generatorBase/src/generatorFactoryBase.cpp b/plugins/robots/generators/generatorBase/src/generatorFactoryBase.cpp index ae44a5776e..94a28e7fc9 100644 --- a/plugins/robots/generators/generatorBase/src/generatorFactoryBase.cpp +++ b/plugins/robots/generators/generatorBase/src/generatorFactoryBase.cpp @@ -20,9 +20,11 @@ #include "simpleGenerators/nullGenerator.h" #include "simpleGenerators/commentElementGenerator.h" #include "simpleGenerators/ifElementGenerator.h" +#include "simpleGenerators/syntheticIfGenerator.h" #include "simpleGenerators/infiniteLoopGenerator.h" #include "simpleGenerators/forLoopGenerator.h" #include "simpleGenerators/whileLoopGenerator.h" +#include "simpleGenerators/syntheticVariableNameGenerator.h" #include "simpleGenerators/forkCallGenerator.h" #include "simpleGenerators/joinGenerator.h" #include "simpleGenerators/killThreadGenerator.h" @@ -95,11 +97,13 @@ using namespace kitBase::robotModel; GeneratorFactoryBase::GeneratorFactoryBase(const qrRepo::RepoApi &repo , ErrorReporterInterface &errorReporter , const RobotModelManagerInterface &robotModelManager - , lua::LuaProcessor &luaProcessor) + , lua::LuaProcessor &luaProcessor + , ReadableLabelManager &readableLabelManager) : mRepo(repo) , mErrorReporter(errorReporter) , mRobotModelManager(robotModelManager) , mLuaTranslator(luaProcessor) + , mReadableLabelManager(readableLabelManager) { } @@ -206,6 +210,13 @@ simple::AbstractSimpleGenerator *GeneratorFactoryBase::ifGenerator(const Id &id , bool needInverting) RETURN_GENERATOR_PTR(IfElementGenerator, (mRepo, customizer, id, elseIsEmpty, needInverting, this)) +simple::AbstractSimpleGenerator *GeneratorFactoryBase::syntheticIfGenerator(const Id &id + , const QMap &ids + , GeneratorCustomizer &customizer + , bool elseIsEmpty + , QString syntheticCondition + , bool needInverting) +RETURN_GENERATOR_PTR(SyntheticIfGenerator, (mRepo, customizer, ids, elseIsEmpty, syntheticCondition, id, needInverting, mReadableLabelManager, this)) simple::AbstractSimpleGenerator *GeneratorFactoryBase::infiniteLoopGenerator(const Id &id , GeneratorCustomizer &customizer) @@ -319,6 +330,10 @@ AbstractSimpleGenerator *GeneratorFactoryBase::labelGenerator(const qReal::Id &i , GeneratorCustomizer &customizer) RETURN_GENERATOR_PTR(LabelGenerator, (mRepo, customizer, id, this)) +AbstractSimpleGenerator *GeneratorFactoryBase::syntheticVariableNameGenerator(const qReal::Id &id + , GeneratorCustomizer &customizer) +RETURN_GENERATOR_PTR(SyntheticVariableNameGenerator, (mRepo, customizer, id, mReadableLabelManager, this)) + AbstractSimpleGenerator *GeneratorFactoryBase::gotoSimpleGenerator(const qReal::Id &id , GeneratorCustomizer &customizer) RETURN_GENERATOR_PTR(GotoSimpleGenerator, (mRepo, customizer, id, this)) diff --git a/plugins/robots/generators/generatorBase/src/masterGeneratorBase.cpp b/plugins/robots/generators/generatorBase/src/masterGeneratorBase.cpp index 21492ecd68..f07640d4b0 100644 --- a/plugins/robots/generators/generatorBase/src/masterGeneratorBase.cpp +++ b/plugins/robots/generators/generatorBase/src/masterGeneratorBase.cpp @@ -32,6 +32,7 @@ #include "generatorBase/parts/threads.h" #include "generatorBase/parts/sensors.h" #include "generatorBase/parts/initTerminateCodeGenerator.h" +#include "readableLabelManager.h" using namespace generatorBase; using namespace qReal; @@ -48,6 +49,7 @@ MasterGeneratorBase::MasterGeneratorBase(const qrRepo::RepoApi &repo , mTextLanguage(textLanguage) , mDiagram(diagramId) , mParserErrorReporter(parserErrorReporter) + , mReadableLabelManager(new ReadableLabelManager()) { } @@ -80,6 +82,8 @@ QString MasterGeneratorBase::generate(const QString &indentString) return QString(); } + mReadableLabelManager->reinit(); + beforeGeneration(); if (!QDir(mProjectDir).exists()) { QDir().mkpath(mProjectDir); diff --git a/plugins/robots/generators/pioneer/pioneerLuaGenerator/generators/gotoLabelManager.cpp b/plugins/robots/generators/generatorBase/src/readableLabelManager.cpp similarity index 79% rename from plugins/robots/generators/pioneer/pioneerLuaGenerator/generators/gotoLabelManager.cpp rename to plugins/robots/generators/generatorBase/src/readableLabelManager.cpp index e0bf94b1fe..0a4bf08211 100644 --- a/plugins/robots/generators/pioneer/pioneerLuaGenerator/generators/gotoLabelManager.cpp +++ b/plugins/robots/generators/generatorBase/src/readableLabelManager.cpp @@ -12,14 +12,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "gotoLabelManager.h" +#include "readableLabelManager.h" #include #include -using namespace pioneer::lua; +using namespace generatorBase; -QString GotoLabelManager::labelFor(const qReal::Id &id) +QString ReadableLabelManager::labelFor(const qReal::Id &id) { qReal::Id actualId = id; if (actualId.editor().startsWith("label_")) { @@ -41,18 +41,19 @@ QString GotoLabelManager::labelFor(const qReal::Id &id) mNodeTypesCount.insert(type, 1); } - const auto label = beautify(QString("%1_%2").arg(actualId.element()).arg(mNodeTypesCount.value(type))); + const auto label = QString("__temp_%1").arg(mLabels.size() + 1); + //beautify(QString("%1_%2").arg(actualId.element()).arg(mNodeTypesCount.value(type))); mLabels.insert(actualId, label); return label; } -void GotoLabelManager::reinit() +void ReadableLabelManager::reinit() { mLabels.clear(); mNodeTypesCount.clear(); } -QString GotoLabelManager::beautify(const QString &label) +QString ReadableLabelManager::beautify(const QString &label) { QString result; for (QChar ch : label) { diff --git a/plugins/robots/generators/pioneer/pioneerLuaGenerator/generators/gotoLabelManager.h b/plugins/robots/generators/generatorBase/src/readableLabelManager.h similarity index 94% rename from plugins/robots/generators/pioneer/pioneerLuaGenerator/generators/gotoLabelManager.h rename to plugins/robots/generators/generatorBase/src/readableLabelManager.h index c9cde5bb41..cb6265f9d6 100644 --- a/plugins/robots/generators/pioneer/pioneerLuaGenerator/generators/gotoLabelManager.h +++ b/plugins/robots/generators/generatorBase/src/readableLabelManager.h @@ -19,11 +19,10 @@ #include -namespace pioneer { -namespace lua { +namespace generatorBase { /// Class that stores and produces human-readable labels for goto statements. -class GotoLabelManager +class ReadableLabelManager { public: /// Returns existing or generates new label for a node with given id. @@ -42,4 +41,3 @@ class GotoLabelManager }; } -} diff --git a/plugins/robots/generators/generatorBase/src/semanticTree/ifNode.cpp b/plugins/robots/generators/generatorBase/src/semanticTree/ifNode.cpp index 2de67df26d..612899f4d2 100644 --- a/plugins/robots/generators/generatorBase/src/semanticTree/ifNode.cpp +++ b/plugins/robots/generators/generatorBase/src/semanticTree/ifNode.cpp @@ -24,6 +24,18 @@ IfNode::IfNode(const Id &idBinded, QObject *parent) , mThenZone(new ZoneNode(this)) , mElseZone(new ZoneNode(this)) , mIsSimple(false) + , mIsSynthetic(false) +{ + mThenZone->setParentNode(this); + mElseZone->setParentNode(this); +} + +IfNode::IfNode(QObject *parent) + : ConditionalNode(qReal::Id(), parent) + , mThenZone(new ZoneNode(this)) + , mElseZone(new ZoneNode(this)) + , mIsSimple(false) + , mIsSynthetic(true) { mThenZone->setParentNode(this); mElseZone->setParentNode(this); @@ -44,6 +56,13 @@ void IfNode::transformToSimple() mIsSimple = true; } +void IfNode::setSyntheticCondition(const QString &s, const QMap &l) +{ + mIsSynthetic = true; + mSyntheticCondition = s; + mIdWasUsedBefore = l; +} + QString IfNode::toStringImpl(GeneratorCustomizer &customizer, int indent, const QString &indentString) const { if (mIsSimple) { @@ -55,7 +74,10 @@ QString IfNode::toStringImpl(GeneratorCustomizer &customizer, int indent, const } const bool elseIsEmpty = mElseZone->isEmpty(); - QString result = utils::StringUtils::addIndent(customizer.factory()-> + QString result = mIsSynthetic ? + utils::StringUtils::addIndent(customizer.factory()-> + syntheticIfGenerator(mId, mIdWasUsedBefore, customizer, elseIsEmpty, mSyntheticCondition, mAddNotToCondition)->generate(), indent, indentString) + : utils::StringUtils::addIndent(customizer.factory()-> ifGenerator(mId, customizer, elseIsEmpty, mAddNotToCondition)->generate(), indent, indentString); const QString thenBlock = mThenZone->toString(customizer, indent + 1, indentString); diff --git a/plugins/robots/generators/generatorBase/src/semanticTree/simpleNode.cpp b/plugins/robots/generators/generatorBase/src/semanticTree/simpleNode.cpp index 88611e039a..101510f3eb 100644 --- a/plugins/robots/generators/generatorBase/src/semanticTree/simpleNode.cpp +++ b/plugins/robots/generators/generatorBase/src/semanticTree/simpleNode.cpp @@ -38,6 +38,9 @@ QString SimpleNode::toStringImpl(GeneratorCustomizer &customizer, int indent, co case gotoNode: return utils::StringUtils::addIndent(customizer.factory()->gotoSimpleGenerator(mId , customizer)->generate(), indent, indentString); + case tempVariableNode: + return utils::StringUtils::addIndent(customizer.factory()->syntheticVariableNameGenerator(mId + , customizer)->generate(), indent, indentString); default: return utils::StringUtils::addIndent(customizer.factory()->simpleGenerator(mId , customizer)->generate(), indent, indentString); @@ -56,6 +59,13 @@ SimpleNode *SimpleNode::createBreakNode(QObject *parent) return breakNode; } +SimpleNode *SimpleNode::createSyntheticVariableNode(const qReal::Id &id, QObject *parent) +{ + SimpleNode *varNode = new SimpleNode(id, parent); + varNode->bindToSyntheticConstruction(SyntheticBlockType::tempVariableNode); + return varNode; +} + QLinkedList SimpleNode::children() const { return QLinkedList(); diff --git a/plugins/robots/generators/generatorBase/src/semanticTree/switchNode.cpp b/plugins/robots/generators/generatorBase/src/semanticTree/switchNode.cpp index 53ab2d0adb..2e33fb637c 100644 --- a/plugins/robots/generators/generatorBase/src/semanticTree/switchNode.cpp +++ b/plugins/robots/generators/generatorBase/src/semanticTree/switchNode.cpp @@ -121,3 +121,14 @@ QLinkedList SwitchNode::children() const return result; } + +ZoneNode *SwitchNode::branchZoneByValue(const QString &value) +{ + if ((value == "") && (mDefaultBranch != nullptr)) { + return mDefaultBranch; + } + if (mBranches.keys().contains(value)) { + return mBranches[value]; + } + return nullptr; +} diff --git a/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticIfGenerator.cpp b/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticIfGenerator.cpp new file mode 100644 index 0000000000..7ce2036ab4 --- /dev/null +++ b/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticIfGenerator.cpp @@ -0,0 +1,53 @@ +/* Copyright 2007-2015 QReal Research Group + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ + +#include "syntheticIfGenerator.h" +#include "generatorBase/generatorCustomizer.h" + +using namespace generatorBase::simple; + +SyntheticIfGenerator::SyntheticIfGenerator(const qrRepo::RepoApi &repo + , GeneratorCustomizer &customizer + , const QMap &useVariable + , bool elseIsEmpty + , const QString syntheticCondition + , const qReal::Id &id + , bool needInverting + , ReadableLabelManager &nameManager + , QObject *parent) + : AbstractSimpleGenerator(repo, customizer, id, parent) + , mUseVariable(useVariable) + , mSyntheticCondition(syntheticCondition) + , mElseIsEmpty(elseIsEmpty) + , mNeedInverting(needInverting) + , mNameManager(nameManager) +{ + +} + +QString SyntheticIfGenerator::generate() +{ + QString result = mSyntheticCondition; + for (const qReal::Id &id : mUseVariable.keys()) { + if (mUseVariable[id]) { + result.replace(id.id(), mNameManager.labelFor(id)); + } else { + result.replace(id.id(), mRepo.property(id, "Condition").toString()); + } + } + QString finalResult = customizer().factory()->boolPropertyConverter(mUseVariable.firstKey() + , "Condition", mNeedInverting)->convert(result); + return readTemplate(mElseIsEmpty ? "conditional/if.t" : "conditional/ifElse.t") + .replace("@@CONDITION@@", finalResult); +} diff --git a/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticIfGenerator.h b/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticIfGenerator.h new file mode 100644 index 0000000000..73e52a3330 --- /dev/null +++ b/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticIfGenerator.h @@ -0,0 +1,49 @@ +/* Copyright 2007-2015 QReal Research Group + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ + +#pragma once + +#include "generatorBase/simpleGenerators/abstractSimpleGenerator.h" + +#include "src/readableLabelManager.h" + +namespace generatorBase { +namespace simple { + +/// Generator for conditional construnctions +class SyntheticIfGenerator : public AbstractSimpleGenerator +{ +public: + SyntheticIfGenerator(const qrRepo::RepoApi &repo + , GeneratorCustomizer &customizer + , const QMap &useVariable + , bool elseIsEmpty + , const QString syntheticCondition + , const qReal::Id &id + , bool needInverting + , ReadableLabelManager &nameManager + , QObject *parent = nullptr); + + QString generate() override; + +private: + const QMap mUseVariable; + const QString mSyntheticCondition; + const bool mElseIsEmpty; + const bool mNeedInverting; + ReadableLabelManager &mNameManager; +}; + +} +} diff --git a/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticVariableNameGenerator.cpp b/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticVariableNameGenerator.cpp new file mode 100644 index 0000000000..5feab9d3d5 --- /dev/null +++ b/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticVariableNameGenerator.cpp @@ -0,0 +1,19 @@ +#include "syntheticVariableNameGenerator.h" +#include "generatorBase/generatorCustomizer.h" + +using namespace generatorBase; +using namespace qReal; + +simple::SyntheticVariableNameGenerator::SyntheticVariableNameGenerator(const qrRepo::RepoApi &repo + , GeneratorCustomizer &customizer + , const Id &id + , ReadableLabelManager &nameManager + , QObject *parent) + : BindingGenerator(repo, customizer, id, "function.t" + , { Binding::createStaticConverting("@@BODY@@" + , nameManager.labelFor(id) + "=" + + repo.property(id, repo.hasProperty(id, "Condition") ? "Condition" : "Expression").toString() + , customizer.factory()->functionBlockConverter(id, "Condition")) } + , parent) +{ +} diff --git a/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticVariableNameGenerator.h b/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticVariableNameGenerator.h new file mode 100644 index 0000000000..7224393131 --- /dev/null +++ b/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticVariableNameGenerator.h @@ -0,0 +1,23 @@ +#pragma once + +#include "generatorBase/simpleGenerators/bindingGenerator.h" + +#include "src/readableLabelManager.h" + +namespace generatorBase { +namespace simple { + +//class ReadableLabelManager; + +class SyntheticVariableNameGenerator : public BindingGenerator +{ +public: + SyntheticVariableNameGenerator(const qrRepo::RepoApi &repo + , GeneratorCustomizer &customizer + , const qReal::Id &id + , ReadableLabelManager &nameManager + , QObject *parent); +}; + +} +} diff --git a/plugins/robots/generators/generatorBase/src/structuralControlFlowGenerator.cpp b/plugins/robots/generators/generatorBase/src/structuralControlFlowGenerator.cpp index 0c10f8a3e2..f581a17e7c 100644 --- a/plugins/robots/generators/generatorBase/src/structuralControlFlowGenerator.cpp +++ b/plugins/robots/generators/generatorBase/src/structuralControlFlowGenerator.cpp @@ -14,15 +14,6 @@ #include "structuralControlFlowGenerator.h" -#include "structurizatorNodes/intermediateStructurizatorNode.h" -#include "structurizatorNodes/blockStructurizatorNode.h" -#include "structurizatorNodes/breakStructurizatorNode.h" -#include "structurizatorNodes/ifStructurizatorNode.h" -#include "structurizatorNodes/structurizatorNodeWithBreaks.h" -#include "structurizatorNodes/selfLoopStructurizatorNode.h" -#include "structurizatorNodes/simpleStructurizatorNode.h" -#include "structurizatorNodes/switchStructurizatorNode.h" -#include "structurizatorNodes/whileStructurizatorNode.h" #include "generatorBase/parts/subprograms.h" #include "generatorBase/parts/threads.h" @@ -36,15 +27,11 @@ StructuralControlFlowGenerator::StructuralControlFlowGenerator(const qrRepo::Rep , PrimaryControlFlowValidator &validator , const Id &diagramId , QObject *parent - , bool isThisDiagramMain - , const Id &simpleId) + , bool isThisDiagramMain) : ControlFlowGeneratorBase(repo, errorReporter, customizer, validator, diagramId, parent, isThisDiagramMain) , mCanBeGeneratedIntoStructuredCode(true) - , mStructurizator(new Structurizator(this)) - , mVerticesNumber(0) - , mStartVertex(0) + , mStructurizer(new Structurizer(this)) , mIsGraphBeingConstructed(true) - , mFictiveId(simpleId) { } @@ -52,7 +39,7 @@ ControlFlowGeneratorBase *StructuralControlFlowGenerator::cloneFor(const Id &dia { StructuralControlFlowGenerator * const copy = new StructuralControlFlowGenerator(mRepo , mErrorReporter, mCustomizer, cloneForNewDiagram ? *mValidator.clone() : mValidator - , diagramId, parent(), false, mFictiveId); + , diagramId, parent(), false); return copy; } @@ -61,59 +48,36 @@ void StructuralControlFlowGenerator::beforeSearch() { } -void StructuralControlFlowGenerator::visit(const Id &id, QList &links) -{ - if (mFictiveId.isNull()) { - mFictiveId = id.sameTypeId(); - } - - mEdgesAndVerticesWereAdded = false; - - ControlFlowGeneratorBase::visit(id, links); - - if (!mEdgesAndVerticesWereAdded) { - appendEdgesAndVertices(id, links); - addVerticesInLoopBody(id, links); - } -} - -void StructuralControlFlowGenerator::afterVisit(const Id &id, QList &links) +void StructuralControlFlowGenerator::visitRegular(const Id &id, const QList &links) { if (!mIsGraphBeingConstructed) { + ControlFlowGeneratorBase::visitRegular(id, links); return; } - if (isLoop(id)) { - mLoopNumbers.pop(); - - const QPair loopBranches = loopBranchesFor(id); - mVerticesInsideLoopBody.remove(mVertexNumber[loopBranches.first.target]); - } - - removeVerticesFromLoopBody(id, links); + appendEdgesAndVertices(id, links); } void StructuralControlFlowGenerator::visitConditional(const Id &id, const QList &links) { - Q_UNUSED(id) Q_UNUSED(links) + const QPair ifBranches = ifBranchesFor(id); + + appendEdgesAndVertices(id, {ifBranches.first}); + appendEdgesAndVertices(id, {ifBranches.second}); } void StructuralControlFlowGenerator::visitLoop(const Id &id, const QList &links) { + Q_UNUSED(links) if (!mIsGraphBeingConstructed) { return; } - appendEdgesAndVertices(id, links); - addVerticesInLoopBody(id, links); - - mEdgesAndVerticesWereAdded = true; - - mLoopNumbers.push(mVertexNumber[id]); - const QPair loopBranches = loopBranchesFor(id); - mVerticesInsideLoopBody.insert(mVertexNumber[loopBranches.first.target]); + + appendEdgesAndVertices(id, {loopBranches.first}); + appendEdgesAndVertices(id, {loopBranches.second}); } void StructuralControlFlowGenerator::visitPreconditionalLoop(const Id &id, const QList &links) @@ -123,14 +87,20 @@ void StructuralControlFlowGenerator::visitPreconditionalLoop(const Id &id, const void StructuralControlFlowGenerator::visitSwitch(const Id &id, const QList &links) { - Q_UNUSED(id) - Q_UNUSED(links) + LinkInfo defaultLink; + for (auto &link : links) { + if (mRepo.property(link.linkId, "Guard").toString() == "") { + defaultLink = link; + } else { + appendEdgesAndVertices(id, {link}); + } + } + appendEdgesAndVertices(id, {defaultLink}); } void StructuralControlFlowGenerator::visitUnknown(const Id &id, const QList &links) { - Q_UNUSED(id) - Q_UNUSED(links) + appendEdgesAndVertices(id, links); } void StructuralControlFlowGenerator::afterSearch() @@ -144,21 +114,23 @@ bool StructuralControlFlowGenerator::cantBeGeneratedIntoStructuredCode() const void StructuralControlFlowGenerator::performGeneration() { + mStartVertex = mSemanticTree->initialBlock(); + mIsGraphBeingConstructed = true; ControlFlowGeneratorBase::performGeneration(); - IntermediateStructurizatorNode *tree = mStructurizator->performStructurization(mIds - , mStartVertex, mFollowers, mVertexNumber, mVerticesNumber); - - if (tree) { - obtainSemanticTree(tree); - mIsGraphBeingConstructed = false; - ControlFlowGeneratorBase::performGeneration(); - } else { - mCanBeGeneratedIntoStructuredCode = false; - } - - if (!mCanBeGeneratedIntoStructuredCode) { - mSemanticTree = nullptr; + StructurizerNode *tree = mStructurizer->performStructurization(mIds + , mStartVertex, mFollowers); + QMap numberOfOccurrences; + for (const auto &e : mIds) { + if (mFollowers[e].size() > 1) { + numberOfOccurrences[e] = tree->numberOfConditionCalculating(e); + } } + QSet alreadyCalculated; + auto zone = new ZoneNode(mSemanticTree); + makeSemanticTree(tree, zone, numberOfOccurrences, alreadyCalculated); + mSemanticTree->setRoot(zone); + mIsGraphBeingConstructed = false; + ControlFlowGeneratorBase::performGeneration(); } void StructuralControlFlowGenerator::registerOtherThreads(const Id &id, const QList &threads @@ -177,363 +149,131 @@ void StructuralControlFlowGenerator::registerTerminatingThreads(const Id &id, pa } } -void StructuralControlFlowGenerator::obtainSemanticTree(IntermediateStructurizatorNode *root) +void StructuralControlFlowGenerator::makeSemanticTree(StructurizerNode *nodes, semantics::ZoneNode *zone + , QMap &numberOfOccurrences, QSet &alreadyCalculated) { - root->analyzeBreak(); - mSemanticTree->setRoot(transformNode(root)); -} - -void StructuralControlFlowGenerator::checkAndAppendBlock(ZoneNode *zone, IntermediateStructurizatorNode *node) -{ - if (node->type() == IntermediateStructurizatorNode::simple) { - SimpleStructurizatorNode *simpleNode = static_cast(node); - - switch (semanticsOf(simpleNode->id())) { - case enums::semantics::conditionalBlock: - case enums::semantics::switchBlock: - break; - default: - zone->appendChild(transformSimple(simpleNode)); + if (nodes != nullptr && nodes->type() == StructurizerNode::Type::sequence) { + for (auto &s : static_cast(nodes)->children()) { + switch (s->type()) { + case StructurizerNode::Type::simple: { + addSimple(s, zone, numberOfOccurrences, alreadyCalculated); + break; + } + case StructurizerNode::Type::breakFromLoop: { + addBreak(s, zone, numberOfOccurrences, alreadyCalculated); + break; + } + case StructurizerNode::Type::loop: { + addLoop(s, zone, numberOfOccurrences, alreadyCalculated); + break; + } + case StructurizerNode::Type::ifThenElse: { + addIf(s, zone, numberOfOccurrences, alreadyCalculated); + break; + } + case StructurizerNode::Type::switchCase: { + addSwitch(s, zone, numberOfOccurrences, alreadyCalculated); + break; + } + default: {qDebug() << "CONTINUATION IN FINAL TREE"; return;} + } } - } else { - zone->appendChild(transformNode(node)); - } + } else qDebug() << "that shouldn't happen too"; } -SemanticNode *StructuralControlFlowGenerator::transformNode(IntermediateStructurizatorNode *node) -{ - switch (node->type()) { - case IntermediateStructurizatorNode::Type::simple: { - SimpleStructurizatorNode *simpleNode = static_cast(node); - return transformSimple(simpleNode); - } - case IntermediateStructurizatorNode::Type::block: { - BlockStructurizatorNode *blockNode = static_cast(node); - return transformBlock(blockNode); - } - - case IntermediateStructurizatorNode::Type::ifThenElseCondition: { - IfStructurizatorNode *ifNode = static_cast(node); - return transformIfThenElse(ifNode); - } - - case IntermediateStructurizatorNode::Type::switchCondition: { - SwitchStructurizatorNode *switchNode = static_cast(node); - return transformSwitch(switchNode); - } - - case IntermediateStructurizatorNode::Type::infiniteloop: { - SelfLoopStructurizatorNode *selfLoopNode = static_cast(node); - return transformSelfLoop(selfLoopNode); - } - - case IntermediateStructurizatorNode::Type::whileloop: { - WhileStructurizatorNode *whileNode = static_cast(node); - return transformWhileLoop(whileNode); - } - - case IntermediateStructurizatorNode::Type::breakNode: { - return transformBreakNode(); - } - - case IntermediateStructurizatorNode::Type::nodeWithBreaks: { - return createConditionWithBreaks(static_cast(node)); - } - - default: - mCanBeGeneratedIntoStructuredCode = false; - return mSemanticTree->produceSimple(); - } -} - -SemanticNode *StructuralControlFlowGenerator::transformSimple(SimpleStructurizatorNode *simpleNode) +void StructuralControlFlowGenerator::addSimple(StructurizerNode *node, semantics::ZoneNode *zone + , QMap &numberOfOccurrences, QSet &alreadyCalculated) { - return mSemanticTree->produceNodeFor(simpleNode->id()); + Q_UNUSED(numberOfOccurrences) + Q_UNUSED(alreadyCalculated) + zone->appendChild(mSemanticTree->produceNodeFor(node->id())); } -SemanticNode *StructuralControlFlowGenerator::transformBlock(BlockStructurizatorNode *blockNode) +void StructuralControlFlowGenerator::addBreak(StructurizerNode *node, semantics::ZoneNode *zone + , QMap &numberOfOccurrences, QSet &alreadyCalculated) { - ZoneNode *zone = new ZoneNode(mSemanticTree); - checkAndAppendBlock(zone, blockNode->firstNode()); - checkAndAppendBlock(zone, blockNode->secondNode()); - - return zone; + Q_UNUSED(node) + Q_UNUSED(numberOfOccurrences) + Q_UNUSED(alreadyCalculated) + zone->appendChild(SimpleNode::createBreakNode(mSemanticTree)); } -SemanticNode *StructuralControlFlowGenerator::transformIfThenElse(IfStructurizatorNode *ifNode) +void StructuralControlFlowGenerator::addSwitch(StructurizerNode *node, semantics::ZoneNode *zone + , QMap &numberOfOccurrences, QSet &alreadyCalculated) { - if (ifNode->condition()->type() == IntermediateStructurizatorNode::nodeWithBreaks) { - StructurizatorNodeWithBreaks *nodeWithBreaks = - static_cast(ifNode->condition()); - nodeWithBreaks->setRestBranches({ifNode->thenBranch(), ifNode->elseBranch()}); - return createConditionWithBreaks(nodeWithBreaks); - } - - const qReal::Id conditionId = ifNode->condition()->firstId(); - - switch (semanticsOf(conditionId)) { - - case enums::semantics::conditionalBlock: { - return createSemanticIfNode(conditionId, ifNode->thenBranch(), ifNode->elseBranch()); - } - - case enums::semantics::switchBlock: { - QList branches = { ifNode->thenBranch() }; - - if (ifNode->elseBranch()) { - branches.append(ifNode->elseBranch()); - } - - return createSemanticSwitchNode(conditionId, branches, ifNode->hasBreakInside()); + auto switchElement = static_cast(node); + if (numberOfOccurrences[switchElement->id()] > 1) { + zone->appendChild(SimpleNode::createSyntheticVariableNode(switchElement->id(), mSemanticTree)); + alreadyCalculated.insert(switchElement->id()); } - case enums::semantics::preconditionalLoopBlock: - case enums::semantics::loopBlock : { - if ((ifNode->exit() && ifNode->elseBranch() && ifNode->exit()->firstId() == ifNode->firstId()) - || (!ifNode->exit() && ifNode->elseBranch())) { - ZoneNode *zone = new ZoneNode(mSemanticTree); - const qReal::Id loopCondition = ifNode->condition()->firstId(); - LoopNode *innerLoop = mSemanticTree->produceLoop(loopCondition); - - const QPair loopBranches = loopBranchesFor(loopCondition); - IntermediateStructurizatorNode *restBranch = ifNode->thenBranch(); - - if (ifNode->thenBranch()->firstId() == loopBranches.first.target) { - innerLoop->bodyZone()->appendChild(transformNode(ifNode->thenBranch())); - restBranch = ifNode->elseBranch(); - } else { - innerLoop->bodyZone()->appendChild(transformNode(ifNode->elseBranch())); - } - - zone->appendChild(innerLoop); - zone->appendChild(transformNode(restBranch)); - return zone; - } - } + auto switchNode = static_cast(mSemanticTree->produceNodeFor(switchElement->id())); + zone->appendChild(switchNode); - default: - break; + for (auto &link : mRepo.outgoingLinks(switchElement->id())) { + const QString value = mRepo.property(link, "Guard").toString(); + switchNode->addBranch(value, nullptr); + auto target = mRepo.otherEntityFromLink(link, switchElement->id()); + makeSemanticTree(switchElement->branches()[target] + , switchNode->branchZoneByValue(value) + , numberOfOccurrences + , alreadyCalculated); } - - mCanBeGeneratedIntoStructuredCode = false; - return mSemanticTree->produceSimple(); } -SemanticNode *StructuralControlFlowGenerator::transformSelfLoop(SelfLoopStructurizatorNode *selfLoopNode) +void StructuralControlFlowGenerator::addIf(StructurizerNode *node, semantics::ZoneNode *zone + , QMap &numberOfOccurrences, QSet &alreadyCalculated) { - LoopNode *semanticLoop = mSemanticTree->produceLoop(); - semanticLoop->bodyZone()->appendChild(transformNode(selfLoopNode->bodyNode())); - return semanticLoop; -} - -SemanticNode *StructuralControlFlowGenerator::transformWhileLoop(WhileStructurizatorNode *whileNode) -{ - IntermediateStructurizatorNode *headNode = whileNode->headNode(); - IntermediateStructurizatorNode *bodyNode = whileNode->bodyNode(); - IntermediateStructurizatorNode *exitNode = whileNode->exitNode(); - - LoopNode *semanticLoop = nullptr; - const qReal::Id conditionId = headNode->firstId(); - - if (headNode->type() == IntermediateStructurizatorNode::Type::simple) { - switch (semanticsOf(conditionId)) { - case enums::semantics::conditionalBlock: { - if (ifBranchesFor(conditionId).first.target == bodyNode->firstId()) { - semanticLoop = mSemanticTree->produceLoop(conditionId); - } else { - semanticLoop = mSemanticTree->produceLoop(); - IfNode *conditionNode = mSemanticTree->produceConditional(conditionId); - conditionNode->thenZone()->appendChild(SimpleNode::createBreakNode(mSemanticTree)); - semanticLoop->bodyZone()->appendChild(conditionNode); + auto ifElement = static_cast(node); + QMap idWasUsed; + for (auto &x : numberOfOccurrences.keys()) { //todo in topological order + if (ifElement->condition()->numberOfFirstVertex(x) > 0) { + if (!alreadyCalculated.contains(x) && numberOfOccurrences[x] > 1) { + zone->appendChild(SimpleNode::createSyntheticVariableNode(x, mSemanticTree)); + alreadyCalculated.insert(x); } - - semanticLoop->bodyZone()->appendChild(transformNode(bodyNode)); - return semanticLoop; + idWasUsed[x] = alreadyCalculated.contains(x); } - - case enums::semantics::preconditionalLoopBlock: - case enums::semantics::loopBlock: { - semanticLoop = mSemanticTree->produceLoop(conditionId); - semanticLoop->bodyZone()->appendChild(transformNode(bodyNode)); - return semanticLoop; - } - - case enums::semantics::switchBlock: { - StructurizatorNodeWithBreaks *nodeWithBreaks = new StructurizatorNodeWithBreaks(headNode - , { new BreakStructurizatorNode(exitNode->firstId(), mStructurizator) }, mStructurizator); - nodeWithBreaks->setRestBranches( { bodyNode } ); - - semanticLoop = mSemanticTree->produceLoop(); - semanticLoop->bodyZone()->appendChild(createConditionWithBreaks(nodeWithBreaks)); - return semanticLoop; - } - - default: - break; - } - } else if (headNode->type() == IntermediateStructurizatorNode::Type::nodeWithBreaks - && isLoop(conditionId)) { - StructurizatorNodeWithBreaks *nodeWitBreaks = static_cast(headNode); - if (nodeWitBreaks->exitBranches().size() != 1 || - nodeWitBreaks->exitBranches().first()->type() == IntermediateStructurizatorNode::block) { - mCanBeGeneratedIntoStructuredCode = false; - return mSemanticTree->produceSimple(); - } else { - semanticLoop = mSemanticTree->produceLoop(conditionId); - semanticLoop->bodyZone()->appendChild(transformNode(bodyNode)); - return semanticLoop; - } - } - - semanticLoop = mSemanticTree->produceLoop(); - semanticLoop->bodyZone()->appendChild(transformNode(headNode)); - semanticLoop->bodyZone()->appendChild(transformNode(bodyNode)); - return semanticLoop; -} - -SemanticNode *StructuralControlFlowGenerator::transformSwitch(SwitchStructurizatorNode *switchNode) -{ - const qReal::Id &conditionId = switchNode->condition()->firstId(); - const QList branches = switchNode->branches(); - - if (switchNode->condition()->type() == IntermediateStructurizatorNode::nodeWithBreaks) { - StructurizatorNodeWithBreaks *nodeWithBreaks = - static_cast(switchNode->condition()); - nodeWithBreaks->setRestBranches(branches); - return createConditionWithBreaks(nodeWithBreaks); } - - if (semanticsOf(conditionId) == enums::semantics::switchBlock) { - return createSemanticSwitchNode(conditionId, branches, switchNode->hasBreakInside()); + auto ifNode = mSemanticTree->produceConditional(); + ifNode->setSyntheticCondition(syntheticConditionToString(ifElement->condition()), idWasUsed); + zone->appendChild(ifNode); + if (static_cast(ifElement->thenBranch())->children().size() == 0) { + ifNode->invertCondition(); + makeSemanticTree(ifElement->elseBranch(), ifNode->thenZone(), numberOfOccurrences, alreadyCalculated); + } else { + makeSemanticTree(ifElement->thenBranch(), ifNode->thenZone(), numberOfOccurrences, alreadyCalculated); + makeSemanticTree(ifElement->elseBranch(), ifNode->elseZone(), numberOfOccurrences, alreadyCalculated); } - - mCanBeGeneratedIntoStructuredCode = false; - return mSemanticTree->produceSimple(); } -SemanticNode *StructuralControlFlowGenerator::transformBreakNode() +void StructuralControlFlowGenerator::addLoop(StructurizerNode *node, semantics::ZoneNode *zone + , QMap &numberOfOccurrences, QSet &alreadyCalculated) { - return semantics::SimpleNode::createBreakNode(mSemanticTree); -} - -SemanticNode *StructuralControlFlowGenerator::createConditionWithBreaks(StructurizatorNodeWithBreaks *nodeWithBreaks) -{ - const qReal::Id conditionId = nodeWithBreaks->firstId(); - - const QList exitBranches = nodeWithBreaks->exitBranches(); - const QList restBranches = nodeWithBreaks->restBranches(); - - switch(semanticsOf(conditionId)) { - case enums::semantics::conditionalBlock: { - return createSemanticIfNode(conditionId, exitBranches.first(), nullptr); - } - - case enums::semantics::switchBlock: { - const QList allBranches = restBranches + exitBranches; - return createSemanticSwitchNode(conditionId, allBranches, true); - } - - case enums::semantics::preconditionalLoopBlock: - case enums::semantics::loopBlock: { - if (exitBranches.size() != 1 || - exitBranches.first()->type() == IntermediateStructurizatorNode::Type::breakNode) { - break; + auto loopElement = static_cast(node); + LoopNode *loopNode = nullptr; + if (loopElement->id() == Id()) { + loopNode = mSemanticTree->produceLoop(); + } else { + loopNode = mSemanticTree->produceLoop(node->id()); + if (loopElement->isInverted()) { + loopNode->invertCondition(); } - - LoopNode *loopNode = mSemanticTree->produceLoop(conditionId); - loopNode->bodyZone()->appendChild(transformNode(exitBranches.first())); - return loopNode; } - - default: - break; - - } - - mCanBeGeneratedIntoStructuredCode = false; - return mSemanticTree->produceSimple(); + zone->appendChild(loopNode); + makeSemanticTree(loopElement->body(), loopNode->bodyZone(), numberOfOccurrences, alreadyCalculated); } -SemanticNode *StructuralControlFlowGenerator::createSemanticIfNode(const Id &conditionId - , IntermediateStructurizatorNode *thenNode - , IntermediateStructurizatorNode *elseNode) -{ - IfNode *semanticIf = mSemanticTree->produceConditional(conditionId); - const QPair links = ifBranchesFor(conditionId); - - if (links.first.target != thenNode->firstId()) { - if (elseNode) { - IntermediateStructurizatorNode *tmp = thenNode; - thenNode = elseNode; - elseNode = tmp; - } else { - semanticIf->invertCondition(); - } - } - - semanticIf->thenZone()->appendChild(transformNode(thenNode)); - - if (elseNode) { - semanticIf->elseZone()->appendChild(transformNode(elseNode)); - } - - return semanticIf; -} - -SemanticNode *StructuralControlFlowGenerator::createSemanticSwitchNode(const Id &conditionId - , const QList &branches, bool generateIfs) -{ - SwitchNode *semanticSwitch = mSemanticTree->produceSwitch(conditionId); - - QMap visitedBranch; - - for (const qReal::Id &link : mRepo.outgoingLinks(conditionId)) { - const QString expression = mRepo.property(link, "Guard").toString(); - const qReal::Id otherVertex = mRepo.otherEntityFromLink(link, conditionId); - - if (visitedBranch.contains(otherVertex)) { - NonZoneNode * const target = static_cast(visitedBranch[otherVertex]); - semanticSwitch->mergeBranch(expression, target); - } else { - bool branchNodeWasFound = false; - SemanticNode *semanticNodeForBranch = nullptr; - for (IntermediateStructurizatorNode *branchNode : branches) { - if (branchNode->firstId() == otherVertex) { - semanticNodeForBranch = transformNode(branchNode); - branchNodeWasFound = true; - break; - } - } - - if (!branchNodeWasFound) { - semanticNodeForBranch = mSemanticTree->produceSimple(); - } - - semanticSwitch->addBranch(expression, semanticNodeForBranch); - visitedBranch[otherVertex] = semanticNodeForBranch; - } - } - - if (generateIfs) { - semanticSwitch->setGenerateIfs(); - } - - return semanticSwitch; -} void StructuralControlFlowGenerator::appendVertex(const Id &vertex) { mIds.insert(vertex); - mVerticesNumber++; - mVertexNumber[vertex] = mVerticesNumber; } void StructuralControlFlowGenerator::addEdgeIntoGraph(const Id &from, const Id &to) { - int numberFrom = mVertexNumber[from]; - int numberTo = mVertexNumber[to]; - mFollowers[numberFrom].insert(numberTo); + mFollowers[from].append(to); } void StructuralControlFlowGenerator::appendEdgesAndVertices(const Id &vertex, const QList &links) @@ -546,57 +286,40 @@ void StructuralControlFlowGenerator::appendEdgesAndVertices(const Id &vertex, co appendVertex(vertex); } - if (!mStartVertex) { - mStartVertex = mVertexNumber[vertex]; - } - for (const LinkInfo &link : links) { - const qReal::Id otherVertex = link.target; - + const Id otherVertex = link.target; if (!mIds.contains(otherVertex)) { - if (isLoop(otherVertex)) { - const qReal::Id loopHeader = mFictiveId.sameTypeId(); - mAdditionalVertices.push_back(loopHeader); - appendVertex(loopHeader); - appendVertex(otherVertex); - addEdgeIntoGraph(vertex, loopHeader); - addEdgeIntoGraph(loopHeader, otherVertex); - mLoopHeader[mVertexNumber[otherVertex]] = mVertexNumber[loopHeader]; - } else { - appendVertex(otherVertex); - addEdgeIntoGraph(vertex, otherVertex); - } - } else { - if (!isLoop(otherVertex) || (mLoopNumbers.contains(mVertexNumber[otherVertex]) - && mVerticesInsideLoopBody.contains(mVertexNumber[vertex]))) { - addEdgeIntoGraph(vertex, otherVertex); - } else { - addEdgeIntoGraph(vertex, mVertexNumber.key(mLoopHeader[mVertexNumber[otherVertex]])); - } - } - } -} - -void StructuralControlFlowGenerator::addVerticesInLoopBody(const Id &vertex, const QList &links) -{ - if (mVerticesInsideLoopBody.contains(mVertexNumber[vertex])) { - for (const LinkInfo &link : links) { - mVerticesInsideLoopBody.insert(mVertexNumber[link.target]); + appendVertex(otherVertex); } + addEdgeIntoGraph(vertex, otherVertex); } } -void StructuralControlFlowGenerator::removeVerticesFromLoopBody(const Id &vertex, const QList &links) +QString StructuralControlFlowGenerator::syntheticConditionToString(StructurizerNode::ConditionTree *tree) { - if (mVerticesInsideLoopBody.contains(mVertexNumber[vertex])) { - for (const LinkInfo &link : links) { - mVerticesInsideLoopBody.remove(mVertexNumber[link.target]); + QString result; + if (tree->isValue()) { + auto head = tree->value().first; + auto target = tree->value().second; + if (mCustomizer.semanticsOf(head) == enums::semantics::conditionalBlock) { + //it is if + result = head.id(); + } else if (mCustomizer.semanticsOf(head) == enums::semantics::switchBlock) { + //it is switch + for (auto &link : mRepo.outgoingLinks(head)) { + if (mRepo.otherEntityFromLink(link, head) == target) { + QString guard = mRepo.property(link, "Guard").toString(); + result = QString("(%1==%2)").arg(head.id(), guard); + break; + } + } + } else { + //strange case + result = head.id(); } + } else { + result = tree->boolOperator() == StructurizerNode::ConditionTree::OR ? "(@@1@@) or (@@2@@)" : "(@@1@@) and (@@2@@)"; + result.replace("@@1@@", syntheticConditionToString(tree->left())).replace("@@2@@", syntheticConditionToString(tree->right())); } -} - -bool StructuralControlFlowGenerator::isLoop(const Id &vertex) const -{ - auto s = semanticsOf(vertex); - return s == enums::semantics::loopBlock || s == enums::semantics::preconditionalLoopBlock; + return tree->isInverted() ? QString("not(%1)").arg(result) : result; } diff --git a/plugins/robots/generators/generatorBase/src/structuralControlFlowGenerator.h b/plugins/robots/generators/generatorBase/src/structuralControlFlowGenerator.h index 09f791c98b..69a501d54e 100644 --- a/plugins/robots/generators/generatorBase/src/structuralControlFlowGenerator.h +++ b/plugins/robots/generators/generatorBase/src/structuralControlFlowGenerator.h @@ -17,7 +17,14 @@ #include "generatorBase/robotsGeneratorDeclSpec.h" #include "generatorBase/controlFlowGeneratorBase.h" #include "generatorBase/semanticTree/semanticTree.h" -#include "structurizator.h" +#include "structurizer.h" +#include "structurizerNodes/structurizerNode.h" +#include "structurizerNodes/ifStructurizerNode.h" +#include "structurizerNodes/loopStructurizerNode.h" +#include "structurizerNodes/simpleStructurizerNode.h" +#include "structurizerNodes/switchStructurizerNode.h" +#include "structurizerNodes/sequenceStructurizerNode.h" + #include #include @@ -26,7 +33,7 @@ namespace generatorBase { /// Generates semantic tree in control-structured style. /// First we obtain control flow graph. -/// Then we are trying structurize such a graph with Structurizator. +/// Then we are trying structurize such a graph with Structurizer. /// If structurization was successfull then we are trying to transform /// control flow tree to Semantic Tree used for code generation. /// @@ -43,8 +50,7 @@ class ROBOTS_GENERATOR_EXPORT StructuralControlFlowGenerator : public ControlFlo , PrimaryControlFlowValidator &validator , const qReal::Id &diagramId , QObject *parent = 0 - , bool isThisDiagramMain = true - , const qReal::Id &simpleId = qReal::Id()); + , bool isThisDiagramMain = true); /// Implementation of clone operation for structural generator ControlFlowGeneratorBase *cloneFor(const qReal::Id &diagramId, bool cloneForNewDiagram) override; @@ -52,20 +58,14 @@ class ROBOTS_GENERATOR_EXPORT StructuralControlFlowGenerator : public ControlFlo void beforeSearch() override; /// functions for visiting Ids. While each visit we contruct graph. - void visit(const qReal::Id &id, QList &links) override; + void visitRegular(const qReal::Id &id, const QList &links) override; void visitConditional(const qReal::Id &id, const QList &links) override; void visitSwitch(const qReal::Id &id, const QList &links) override; void visitUnknown(const qReal::Id &id, QList const &links) override; - - /// We introduce fake-loop-preheader vertex incident to vertices not from loop body. - /// We remember vertices belonging to loop. void visitLoop(const qReal::Id &id, const QList &links) override; void visitPreconditionalLoop(const qReal::Id &id, const QList &links) override; - /// We clean old info about vertices belonging to some loop. - void afterVisit(const qReal::Id &id, QList &links) override; - /// This method can be used for semantic tree debug printing after all /// traversal stages. void afterSearch() override; @@ -91,58 +91,39 @@ class ROBOTS_GENERATOR_EXPORT StructuralControlFlowGenerator : public ControlFlo , bool fromMain) override; void performStructurization(); - void obtainSemanticTree(IntermediateStructurizatorNode *root); - - /// helper method for ZoneNode - void checkAndAppendBlock(semantics::ZoneNode *zone, IntermediateStructurizatorNode *node); - - /// transformation methods - semantics::SemanticNode *transformNode(IntermediateStructurizatorNode *node); - semantics::SemanticNode *transformSimple(SimpleStructurizatorNode *simpleNode); - semantics::SemanticNode *transformBlock(BlockStructurizatorNode *blockNode); - semantics::SemanticNode *transformIfThenElse(IfStructurizatorNode *ifNode); - semantics::SemanticNode *transformSelfLoop(SelfLoopStructurizatorNode *selfLoopNode); - semantics::SemanticNode *transformWhileLoop(WhileStructurizatorNode *whileNode); - semantics::SemanticNode *transformSwitch(SwitchStructurizatorNode *switchNode); - semantics::SemanticNode *transformBreakNode(); - - /// helper functions - semantics::SemanticNode *createConditionWithBreaks(StructurizatorNodeWithBreaks *nodeWithBreaks); - semantics::SemanticNode *createSemanticIfNode(const qReal::Id &conditionId - , IntermediateStructurizatorNode *thenNode - , IntermediateStructurizatorNode *elseNode); - - semantics::SemanticNode *createSemanticSwitchNode(const qReal::Id &conditionId - , const QList &branches - , bool generateIfs); + + void makeSemanticTree(StructurizerNode *nodes, semantics::ZoneNode *zone + , QMap &numberOfOccurrences, QSet &alreadyCalculated); + + void addSimple(StructurizerNode *node, semantics::ZoneNode *zone + , QMap &numberOfOccurrences, QSet &alreadyCalculated); + + void addBreak(StructurizerNode *node, semantics::ZoneNode *zone + , QMap &numberOfOccurrences, QSet &alreadyCalculated); + + void addIf(StructurizerNode *node, semantics::ZoneNode *zone + , QMap &numberOfOccurrences, QSet &alreadyCalculated); + + void addLoop(StructurizerNode *node, semantics::ZoneNode *zone + , QMap &numberOfOccurrences, QSet &alreadyCalculated); + + void addSwitch(StructurizerNode *node, semantics::ZoneNode *zone + , QMap &numberOfOccurrences, QSet &alreadyCalculated); /// methods for building graph void appendVertex(const qReal::Id &vertex); void addEdgeIntoGraph(const qReal::Id &from, const qReal::Id &to); void appendEdgesAndVertices(const qReal::Id &vertex, const QList &links); - /// methods for handling vertices belonging to loop body - void addVerticesInLoopBody(const qReal::Id &vertex, const QList &links); - void removeVerticesFromLoopBody(const qReal::Id &vertex, const QList &links); - - bool isLoop(const qReal::Id &vertex) const; + QString syntheticConditionToString(StructurizerNode::ConditionTree *tree); - QMap mTrees; bool mCanBeGeneratedIntoStructuredCode; - Structurizator *mStructurizator; + Structurizer *mStructurizer; - int mVerticesNumber; QSet mIds; - int mStartVertex; - QMap mVertexNumber; - QMap mLoopHeader; - QMap> mFollowers; + qReal::Id mStartVertex; + QMap> mFollowers; bool mIsGraphBeingConstructed; - QStack mLoopNumbers; - QSet mVerticesInsideLoopBody; - QVector mAdditionalVertices; - bool mEdgesAndVerticesWereAdded {}; - qReal::Id mFictiveId; }; } diff --git a/plugins/robots/generators/generatorBase/src/structurizator.cpp b/plugins/robots/generators/generatorBase/src/structurizator.cpp deleted file mode 100644 index 80233af907..0000000000 --- a/plugins/robots/generators/generatorBase/src/structurizator.cpp +++ /dev/null @@ -1,826 +0,0 @@ -/* Copyright 2018 Konstantin Batoev - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. */ - -#include "structurizator.h" - -#include - -#include "structurizatorNodes/intermediateStructurizatorNode.h" -#include "structurizatorNodes/blockStructurizatorNode.h" -#include "structurizatorNodes/breakStructurizatorNode.h" -#include "structurizatorNodes/ifStructurizatorNode.h" -#include "structurizatorNodes/structurizatorNodeWithBreaks.h" -#include "structurizatorNodes/selfLoopStructurizatorNode.h" -#include "structurizatorNodes/simpleStructurizatorNode.h" -#include "structurizatorNodes/switchStructurizatorNode.h" -#include "structurizatorNodes/whileStructurizatorNode.h" - -using namespace generatorBase; - -Structurizator::Structurizator(QObject *parent) - : QObject(parent) - , mVerticesNumber(1) - , mStartVertex(-1) - , mMaxPostOrderTime(-1) -{ -} - -IntermediateStructurizatorNode *Structurizator::performStructurization(const QSet &verticesIds - , int startVertex - , const QMap> &followers - , const QMap &vertexNumber - , int verticesNumber) -{ - for (const qReal::Id &id : verticesIds) { - mInitialIds.insert(id); - mMapIdToInt[id] = vertexNumber[id]; - mVertices.insert(vertexNumber[id]); - } - - mVerticesNumber = verticesNumber; - mStartVertex = startVertex; - - for (const int v : followers.keys()) { - for (const int u : followers[v]) { - mFollowers[v].push_back(u); - mPredecessors[u].push_back(v); - } - } - - calculatePostOrder(); - calculateDominators(); - createInitialNodesForIds(); - - bool somethingChanged = true; - while (somethingChanged) { - somethingChanged = false; - - int t = 0; - while (t <= mMaxPostOrderTime && (mVertices.size() > 1 || !mFollowers[mStartVertex].isEmpty())) { - int v = mPostOrder.key(t); - - QSet reachUnder; - QSet> edgesToRemove = {}; - QMap verticesRoles; - if (isBlock(v, edgesToRemove, verticesRoles)) { - reduceBlock(edgesToRemove, verticesRoles); - } else if (isSwitch(v, edgesToRemove, verticesRoles)) { - reduceSwitch(edgesToRemove, verticesRoles); - } else if (isIfThenElse(v, edgesToRemove, verticesRoles)) { - reduceIfThenElse(edgesToRemove, verticesRoles); - } else if (isIfThen(v, edgesToRemove, verticesRoles)) { - reduceIfThen(edgesToRemove, verticesRoles); - } else if (isInfiniteLoop(v, edgesToRemove, verticesRoles)) { - reduceInfiniteLoop(edgesToRemove, verticesRoles); - } else if (isWhileLoop(v, edgesToRemove, verticesRoles)) { - reduceWhileLoop(edgesToRemove, verticesRoles); - } else if (isHeadOfCycle(v, reachUnder)) { - int minTime = -1; - for (const int vertex : reachUnder) { - if (minTime == -1 || minTime > mPostOrder[vertex]) { - minTime = mPostOrder[vertex]; - } - } - - QMap> nodesWithExits; - int commonExit = -1; - bool isCycle = isCycleWithBreaks(reachUnder, nodesWithExits, commonExit); - QSet verticesWithExits = nodesWithExits.keys().toSet(); - - if (!isCycle) { - t++; - appendNodesDetectedAsNodeWithExit(verticesWithExits, v); - continue; - } - - if (!nodesWithExits.isEmpty() && checkNodes(verticesWithExits)) { - - for (const int vertexInsideLoop : nodesWithExits.keys()) { - for (const int vertexOutsideLoop : nodesWithExits[vertexInsideLoop]) { - if (minTime > mPostOrder[vertexOutsideLoop]) { - minTime = mPostOrder[vertexOutsideLoop]; - } - } - } - - reduceConditionsWithBreaks(v, nodesWithExits, commonExit); - t = minTime; - somethingChanged = true; - appendNodesDetectedAsNodeWithExit(verticesWithExits, v); - continue; - } - } - - if (!verticesRoles.empty()) { - t -= (verticesRoles.size() - 1); - if (t < 0) { - t = 0; - } - - somethingChanged = true; - } else { - t++; - } - } - } - - if (mVertices.size() == 1) { - return mTrees[mStartVertex]; - } - - return nullptr; -} - -bool Structurizator::isBlock(int v, QSet> &edgesToRemove, QMap &verticesRoles) -{ - if (outgoingEdgesNumber(v) != 1) { - return false; - } - - int u = mFollowers[v].first(); - if (outgoingEdgesNumber(u) <= 1 && incomingEdgesNumber(u) == 1 && u != v && mDominators[u].contains(v)) { - verticesRoles["block1"] = v; - verticesRoles["block2"] = u; - - edgesToRemove.insert(qMakePair(v, u)); - return true; - } - - return false; -} - -bool Structurizator::isIfThenElse(int v, QSet> &edgesToRemove, QMap &verticesRoles) -{ - if (outgoingEdgesNumber(v) != 2) { - return false; - } - - int u1 = mFollowers[v].first(); - int u2 = mFollowers[v].last(); - if (incomingEdgesNumber(u1) != 1 || incomingEdgesNumber(u2) != 1 || mDominators[v].contains(u1) - || mDominators[v].contains(u2)) { - return false; - } - - if ((outgoingEdgesNumber(u1) == 0 && outgoingEdgesNumber(u2) == 0) || - (outgoingEdgesNumber(u1) == 1 && outgoingEdgesNumber(u2) == 1 && - mFollowers[u1].first() == mFollowers[u2].first())) { - - verticesRoles["condition"] = v; - verticesRoles["then"] = u1; - verticesRoles["else"] = u2; - - if (outgoingEdgesNumber(u1) > 0) { - verticesRoles["exit"] = mFollowers[u1].first(); - } - - edgesToRemove += { qMakePair(v, u1), qMakePair(v, u2) }; - return true; - } - - return false; -} - -bool Structurizator::isIfThen(int v, QSet> &edgesToRemove, QMap &verticesRoles) -{ - if (outgoingEdgesNumber(v) != 2) { - return false; - } - - int u1 = mFollowers[v].first(); - int u2 = mFollowers[v].last(); - - int thenNumber = -1; - int elseNumber = -1; - if (checkIfThenHelper(u1, u2)) { - thenNumber = u1; - elseNumber = u2; - } else if (checkIfThenHelper(u2, u1)) { - thenNumber = u2; - elseNumber = u1; - } - - if (thenNumber == -1 || elseNumber == v || mDominators[v].contains(thenNumber)) { - return false; - } - - verticesRoles["condition"] = v; - verticesRoles["then"] = thenNumber; - - if (outgoingEdgesNumber(thenNumber) > 0) { - verticesRoles["exit"] = mFollowers[thenNumber].first(); - } - - edgesToRemove = { qMakePair(v, u1), qMakePair(v, u2) }; - - return true; -} - -bool Structurizator::isSwitch(int v, QSet> &edgesToRemove, QMap &verticesRoles) -{ - if (outgoingEdgesNumber(v) < 3) { - return false; - } - - int exit = -1; - QSet vertices = {}; - QSet> edges = {}; - for (const int u : mFollowers[v]) { - if (incomingEdgesNumber(u) != 1 || outgoingEdgesNumber(u) >= 2) { - if (exit == -1) { - exit = u; - } else if (exit != u) { - return false; - } - } else { - if (outgoingEdgesNumber(u) == 1) { - int m = mFollowers[u].first(); - if (exit == -1) { - exit = m; - } else if (m != exit) { - return false; - } - } - vertices.insert(u); - } - - if (u != exit && mDominators[v].contains(u)) { - return false; - } - - edges.insert(qMakePair(v, u)); - } - - verticesRoles["head"] = v; - edgesToRemove = edges; - - int cnt = 1; - for (int u : vertices) { - verticesRoles[QString::number(cnt)] = u; - cnt++; - } - - verticesRoles["exit"] = exit; - - return true; -} - -bool Structurizator::isInfiniteLoop(int v, QSet> &edgesToRemove, QMap &verticesRoles) -{ - if (outgoingEdgesNumber(v) != 1) { - return false; - } - - int u = mFollowers[v].first(); - if (u != v) { - return false; - } - - verticesRoles["body"] = v; - edgesToRemove.insert(qMakePair(v, v)); - return true; -} - -bool Structurizator::isWhileLoop(int v, QSet> &edgesToRemove, QMap &verticesRoles) -{ - if (outgoingEdgesNumber(v) != 2) { - return false; - } - - int u1 = mFollowers[v].first(); - int u2 = mFollowers[v].last(); - - int bodyNumber = -1; - int exitNumber = -1; - if (checkWhileLoopHelper(v, u1)) { - bodyNumber = u1; - exitNumber = u2; - } else if (checkWhileLoopHelper(v, u2)) { - bodyNumber = u2; - exitNumber = u1; - } - - if (bodyNumber == -1) { - return false; - } - - if (mDominators[v].contains(bodyNumber)) { - return false; - } - - edgesToRemove = { qMakePair(v, bodyNumber), qMakePair(bodyNumber, v) }; - - verticesRoles["head"] = v; - verticesRoles["body"] = bodyNumber; - verticesRoles["exit"] = exitNumber; - - return true; -} - -bool Structurizator::checkIfThenHelper(int thenNumber, int exitNumber) -{ - if (incomingEdgesNumber(thenNumber) == 1 && outgoingEdgesNumber(thenNumber) == 1) { - if (mFollowers[thenNumber].contains(exitNumber)) { - return true; - } - } - - return false; -} - -bool Structurizator::checkWhileLoopHelper(int head, int body) -{ - if (incomingEdgesNumber(body) == 1 && outgoingEdgesNumber(body) == 1) { - int w = mFollowers[body].first(); - if (w == head) { - return true; - } - } - - return false; -} - -bool Structurizator::isCycleWithBreaks(QSet &reachUnder, QMap> &nodesWithExits, int &commonExit) -{ - bool result = findCommonExit(reachUnder, nodesWithExits, commonExit); - if (!result) { - return false; - } - - return checkCommonExitUniqueness(commonExit, nodesWithExits); -} - -bool Structurizator::isHeadOfCycle(int v, QSet &reachUnder) -{ - QQueue queueForReachUnder; - - for (const int u : mPredecessors[v]) { - if (mDominators[u].contains(v)) { - queueForReachUnder.push_back(u); - } - } - - while (!queueForReachUnder.empty()) { - int u = queueForReachUnder.front(); - queueForReachUnder.pop_front(); - reachUnder.insert(u); - for (const int w : mPredecessors[u]) { - if (mDominators[w].contains(v) && !reachUnder.contains(w)) { - queueForReachUnder.push_back(w); - } - } - } - - return !reachUnder.isEmpty(); -} - -bool Structurizator::findCommonExit(QSet &reachUnder, QMap> &nodesWithExits, int &commonExit) -{ - commonExit = -1; - QSet exits; - - for (const int u : reachUnder) { - for (const int w : mFollowers[u]) { - if (!reachUnder.contains(w)) { - if (exits.contains(w) || incomingEdgesNumber(w) > 1) { - if (commonExit != -1 && commonExit != w) { - return false; - } - commonExit = w; - } - - exits.insert(w); - nodesWithExits[u].insert(w); - } - } - } - - if (commonExit != -1) { - return true; - } - - QList regionToFindCommonChild; - for (const int exitNumber : exits) { - if (outgoingEdgesNumber(exitNumber) == 1) { - regionToFindCommonChild.append(exitNumber); - } else if (outgoingEdgesNumber(exitNumber) > 1) { - if (commonExit == -1) { - // we have found post-cycle execution point - commonExit = exitNumber; - } else if (commonExit != exitNumber) { - // each cycle can have at most 1 point to transfer execution - return false; - } - } - } - - if (commonExit != -1) { - return true; - } - - // assume that one exit point is commonChild - if (regionToFindCommonChild.size() == 1) { - commonExit = regionToFindCommonChild.first(); - return true; - } - - for (const int exitNumber : regionToFindCommonChild) { - for (const int postExit : mFollowers[exitNumber]) { - if (commonExit == -1) { - commonExit = postExit; - } else if (commonExit != postExit) { - return false; - } - } - } - - return true; -} - -bool Structurizator::checkCommonExitUniqueness(int commonExit, const QMap> &nodesWithExits) -{ - for (const int vertexFromCycle : nodesWithExits.keys()) { - for (const int exit : nodesWithExits[vertexFromCycle]) { - if (commonExit == exit) { - continue; - } - - if (incomingEdgesNumber(exit) != 1 || outgoingEdgesNumber(exit) >= 2) { - return false; - } - - if (outgoingEdgesNumber(exit) == 1 && commonExit != mFollowers[exit].first()) { - return false; - } - } - } - - return true; -} - -bool Structurizator::checkNodes(const QSet &verticesWithExits) -{ - QSet testSet = mWasPreviouslyDetectedAsNodeWithExit.keys().toSet(); - testSet.intersect(verticesWithExits); - return testSet.isEmpty(); -} - -void Structurizator::reduceBlock(QSet> &edgesToRemove, QMap &verticesRoles) -{ - BlockStructurizatorNode *block = new BlockStructurizatorNode(mTrees[verticesRoles["block1"]] - , mTrees[verticesRoles["block2"]], this); - replace(appendVertex(block), edgesToRemove, verticesRoles); -} - -void Structurizator::reduceIfThenElse(QSet> &edgesToRemove, QMap &verticesRoles) -{ - IntermediateStructurizatorNode *exit = nullptr; - if (verticesRoles.contains("exit")) { - exit = mTrees[verticesRoles["exit"]]; - verticesRoles.remove("exit"); - } - - IfStructurizatorNode *ifNode = new IfStructurizatorNode(mTrees[verticesRoles["condition"]] - , mTrees[verticesRoles["then"]] - , mTrees[verticesRoles["else"]] - , exit - , this); - replace(appendVertex(ifNode), edgesToRemove, verticesRoles); -} - -void Structurizator::reduceIfThen(QSet> &edgesToRemove, QMap &verticesRoles) -{ - IntermediateStructurizatorNode *exit = nullptr; - if (verticesRoles.contains("exit")) { - exit = mTrees[verticesRoles["exit"]]; - verticesRoles.remove("exit"); - } - - IfStructurizatorNode *ifNode = new IfStructurizatorNode(mTrees[verticesRoles["condition"]], - mTrees[verticesRoles["then"]] - , nullptr - , exit - , this); - replace(appendVertex(ifNode), edgesToRemove, verticesRoles); -} - -void Structurizator::reduceSwitch(QSet> &edgesToRemove, QMap &verticesRoles) -{ - int v = verticesRoles["head"]; - int exitNodeNumber = verticesRoles["exit"]; - verticesRoles.remove("exit"); - - QSet otherVerteces = verticesRoles.values().toSet(); - otherVerteces.remove(v); - - QList branches; - for (const int u : mFollowers[v]) { - if (otherVerteces.contains(u)) { - branches.append(mTrees[u]); - } else { - branches.append(new SimpleStructurizatorNode(qReal::Id(), this)); - } - } - - IntermediateStructurizatorNode *exitNode = exitNodeNumber == -1 ? nullptr : mTrees[exitNodeNumber]; - SwitchStructurizatorNode *switchNode = new SwitchStructurizatorNode(mTrees[v], branches, exitNode, this); - - replace(appendVertex(switchNode), edgesToRemove, verticesRoles); -} - -void Structurizator::reduceInfiniteLoop(QSet> &edgesToRemove, QMap &verticesRoles) -{ - SelfLoopStructurizatorNode *loopNode = new SelfLoopStructurizatorNode(mTrees[verticesRoles["body"]], this); - - replace(appendVertex(loopNode), edgesToRemove, verticesRoles); -} - -void Structurizator::reduceWhileLoop(QSet> &edgesToRemove, QMap &verticesRoles) -{ - WhileStructurizatorNode *whileNode = new WhileStructurizatorNode(mTrees[verticesRoles["head"]] - , mTrees[verticesRoles["body"]] - , mTrees[verticesRoles["exit"]] - , this); - - verticesRoles.remove("exit"); - replace(appendVertex(whileNode), edgesToRemove, verticesRoles); -} - -void Structurizator::reduceConditionsWithBreaks(int &v, QMap> &nodesWithExits, int commonExit) -{ - QList exitBranches; - QSet> edgesToRemove; - QSet vertices; - for (const int u : nodesWithExits.keys()) { - exitBranches.clear(); - edgesToRemove.clear(); - vertices = {u}; - - for (const int exit : nodesWithExits[u]) { - qReal::Id id = mTrees[exit]->firstId(); - IntermediateStructurizatorNode *node; - if (exit == commonExit) { - node = new BreakStructurizatorNode(id, this); - } else { - node = new BlockStructurizatorNode(mTrees[exit], new BreakStructurizatorNode(id, this), this); - - vertices.insert(exit); - - if (mFollowers[exit].contains(commonExit)) { - edgesToRemove.insert(qMakePair(exit, commonExit)); - } - } - edgesToRemove.insert(qMakePair(u, exit)); - exitBranches.append(node); - } - - StructurizatorNodeWithBreaks *nodeWithBreaks = new StructurizatorNodeWithBreaks(mTrees[u] - , exitBranches, this); - replace(appendVertex(nodeWithBreaks), edgesToRemove, vertices); - - if (u == v) { - v = mTrees.key(nodeWithBreaks); - } - } - - // adding edge from head to common exit - if (commonExit != -1 && !mFollowers[v].contains(commonExit)) { - mFollowers[v].push_back(commonExit); - mPredecessors[commonExit].push_back(v); - } -} - -void Structurizator::replace(int newNodeNumber, QSet> &edgesToRemove, QSet &vertices) -{ - updateEdges(newNodeNumber, edgesToRemove, vertices); - updatePostOrder(newNodeNumber, vertices); - updateDominators(newNodeNumber, vertices); - updateVertices(newNodeNumber, vertices); - removeNodesPreviouslyDetectedAsNodeWithExit(vertices); -} - -void Structurizator::replace(int newNodeNumber, QSet> &edgesToRemove, - QMap &verticesRoles) -{ - QSet vertices = verticesRoles.values().toSet(); - replace(newNodeNumber, edgesToRemove, vertices); -} - -void Structurizator::updateEdges(int newNodeNumber, QSet> &edgesToRemove, QSet &vertices) -{ - for (const QPair p : edgesToRemove) { - mFollowers[p.first].removeAll(p.second); - mPredecessors[p.second].removeAll(p.first); - } - - const QMap> followers = mFollowers; - for (const int v : mVertices) { - for (const int u : followers[v]) { - - int newV = vertices.contains(v) ? newNodeNumber : v; - int newU = vertices.contains(u) ? newNodeNumber : u; - - if (newU == newNodeNumber || newV == newNodeNumber) { - // removing old information - mFollowers[v].removeAll(u); - mPredecessors[u].removeAll(v); - - // inserting new information - if (!mFollowers[newV].contains(newU)) { - mFollowers[newV].push_back(newU); - mPredecessors[newU].push_back(newV); - } - } - } - } - - for (const int v : vertices) { - mFollowers.remove(v); - mPredecessors.remove(v); - } -} - -void Structurizator::updatePostOrder(int newNodeNumber, QSet &verteces) -{ - int maximum = -1; - for (int v : verteces) { - if (maximum == -1 || maximum < mPostOrder[v]) { - maximum = mPostOrder[v]; - } - } - - mPostOrder[newNodeNumber] = maximum; - - for (int v : verteces) { - mPostOrder.remove(v); - } - - mMaxPostOrderTime = mMaxPostOrderTime - verteces.size() + 1; - - QVector times = mPostOrder.values().toVector(); - std::sort(times.begin(), times.end()); - - for (int i = 0; i <= mMaxPostOrderTime; i++) { - int v = mPostOrder.key(times[i]); - mPostOrder[v] = i; - } -} - -void Structurizator::updateDominators(int newNodeNumber, QSet &vertices) -{ - // others - for (int v : mPostOrder.keys()) { - QSet tempSet = mDominators[v]; - tempSet.intersect(vertices); - if (!tempSet.isEmpty()) { - mDominators[v].subtract(vertices); - mDominators[v].insert(newNodeNumber); - } - } - - // new - QSet doms = mVertices; - for (int v : vertices) { - doms.intersect(mDominators[v]); - } - - doms.subtract(vertices); - doms.insert(newNodeNumber); - - mDominators[newNodeNumber] = doms; - - // old - for (int v : vertices) { - mDominators.remove(v); - } -} - -void Structurizator::updateVertices(int newNodeNumber, QSet &vertices) -{ - mStartVertex = vertices.contains(mStartVertex) ? newNodeNumber : mStartVertex; - mVertices.subtract(vertices); - mVertices.insert(newNodeNumber); -} - -void Structurizator::removeNodesPreviouslyDetectedAsNodeWithExit(QSet &vertices) -{ - for (const int v : vertices) { - mWasPreviouslyDetectedAsNodeWithExit.remove(v); - } -} - -void Structurizator::calculateDominators() -{ - for (const int u : mVertices) { - mDominators[u] = mVertices; - } - - mDominators[mStartVertex] = { mStartVertex }; - - bool somethingChanged = true; - while (somethingChanged) { - somethingChanged = false; - - for (const int v : mVertices) { - if (v == mStartVertex) { - continue; - } - - QSet doms = mVertices; - for (const int u : mPredecessors[v]) { - doms = doms.intersect(mDominators[u]); - } - - doms.insert(v); - - if (doms != mDominators[v]) { - mDominators[v] = doms; - somethingChanged = true; - } - } - } - - -} - -void Structurizator::findStartVertex() -{ - for (const int u : mVertices) { - if (mPredecessors[u].isEmpty()) { - mStartVertex = u; - return; - } - } -} - -void Structurizator::calculatePostOrder() -{ - mPostOrder.clear(); - - QMap used; - for (const int v : mVertices) { - used[v] = false; - } - - int currentTime = 0; - dfs(mStartVertex, currentTime, used); - - mMaxPostOrderTime = currentTime - 1; -} - -void Structurizator::createInitialNodesForIds() -{ - for (const int v : mVertices) { - mTrees[v] = new SimpleStructurizatorNode(mMapIdToInt.key(v), this); - } -} - -void Structurizator::dfs(int v, int ¤tTime, QMap &used) -{ - used[v] = true; - for (const int u : mFollowers[v]) { - if (!used[u]) { - dfs(u, currentTime, used); - } - } - - mPostOrder[v] = currentTime; - currentTime++; -} - -void Structurizator::appendNodesDetectedAsNodeWithExit(QSet &vertices, int cycleHead) -{ - for (const int v : vertices) { - mWasPreviouslyDetectedAsNodeWithExit[v] = cycleHead; - } -} - -int Structurizator::appendVertex(IntermediateStructurizatorNode *node) -{ - mVerticesNumber++; - mTrees[mVerticesNumber] = node; - mVertices.insert(mVerticesNumber); - - return mVerticesNumber; -} - -int Structurizator::outgoingEdgesNumber(int v) const -{ - return mFollowers[v].size(); -} - -int Structurizator::incomingEdgesNumber(int v) const -{ - return mPredecessors[v].size(); -} diff --git a/plugins/robots/generators/generatorBase/src/structurizator.h b/plugins/robots/generators/generatorBase/src/structurizator.h deleted file mode 100644 index 08e9442403..0000000000 --- a/plugins/robots/generators/generatorBase/src/structurizator.h +++ /dev/null @@ -1,145 +0,0 @@ -/* Copyright 2018 Konstantin Batoev - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. */ - -#pragma once - -#include -#include - -#include - -namespace generatorBase { - -class IntermediateStructurizatorNode; -class SimpleStructurizatorNode; -class BreakStructurizatorNode; -class IfStructurizatorNode; -class SwitchStructurizatorNode; -class BlockStructurizatorNode; -class WhileStructurizatorNode; -class SelfLoopStructurizatorNode; -class StructurizatorNodeWithBreaks; - -/// @class Structurizator is aimed to produce control flow AST from diagram performing Structural Analysis. -/// AST Nodes are concrete classes (BlockNode, WhileNode, etc.) of abstract @class IntermediateNode -/// and represent some type of control structure of high-order programming language. -/// -/// We should fill needed structures before performing main algorithm: -/// 1) calculate dominators used for detecting vertices in cycle body; -/// 2) calculate postorder vertices numbers to perform structurizaion from down to up. -/// -/// Structurization is a process of graph transformations made iteratively. -/// Each transformation has four steps: -/// 1) pattern matching, remembering vertices and their roles -/// 2) creating new vertex and IntermediateNode of corresponding subclass -/// 3) reducing graph substituting "old" edges incident to old vertices with "new" ones; -/// 4) updating dominance relationship and postorder -/// -/// These four steps are performed until there would be one vertex with no edges. -/// -/// @return a pointer to an obtained tree and nullptr if structurization was unsuccessfull. -class Structurizator : public QObject -{ - Q_OBJECT - -public: - explicit Structurizator(QObject *parent = nullptr); - - /// main function that performs structurization - IntermediateStructurizatorNode *performStructurization(const QSet &verticesIds, int startVertex - , const QMap> &followers, const QMap &vertexNumber, int verticesNumber); - -private: - typedef int Time; - typedef int VertexNumber; - - /// methods to identify patterns for structural analysis - /// @arg edgesToRemove -- passed by reference. - /// @arg verticesRoles -- passed by reference. - bool isBlock(int v, QSet> &edgesToRemove, QMap &verticesRoles); - bool isIfThenElse(int v, QSet> &edgesToRemove, QMap &verticesRoles); - bool isIfThen(int v, QSet> &edgesToRemove, QMap &verticesRoles); - bool isSwitch(int v, QSet> &edgesToRemove, QMap &verticesRoles); - bool isInfiniteLoop(int v, QSet> &edgesToRemove, QMap &verticesRoles); - bool isWhileLoop(int v, QSet> &edgesToRemove, QMap &verticesRoles); - - /// helper functions for clarifying vertices roles - bool checkIfThenHelper(int thenNumber, int elseNumber); - bool checkWhileLoopHelper(int head, int body); - - /// functions for identifying loops that have "obstructive" vertices with edges going outside loop to EXIT. - /// EXIT --- is a vertex to which control is transfered after loop execution. - /// the main idea is to remove such vertices and edges substituting them with new vertices - /// of class NodeWithBreaks which remember actions to perform before Break. - bool isCycleWithBreaks(QSet &reachUnder, QMap> &nodesWithExits, int &commonExit); - bool isHeadOfCycle(int v, QSet &reachUnder); - bool findCommonExit(QSet &reachUnder, QMap> &nodesWithExits, int &commonExit); - - /// EXIT must be unique. - bool checkCommonExitUniqueness(int commonExit, const QMap> &nodesWithExits); - - /// Vertices with exits must belong only to one loop. - /// This limitation was introduced in order to forbid situation of nested loops when break - /// nodes belong to inner one, because in general such a situation is resolved with - /// introducing new flag-variables. - bool checkNodes(const QSet &verticesWithExits); - - /// methods for reducing recognised pattern - void reduceBlock(QSet> &edgesToRemove, QMap &verticesRoles); - void reduceIfThenElse(QSet> &edgesToRemove, QMap &verticesRoles); - void reduceIfThen(QSet> &edgesToRemove, QMap &verticesRoles); - void reduceSwitch(QSet> &edgesToRemove, QMap &verticesRoles); - void reduceInfiniteLoop(QSet> &edgesToRemove, QMap &verticesRoles); - void reduceWhileLoop(QSet> &edgesToRemove, QMap &verticesRoles); - void reduceConditionsWithBreaks(int &v, QMap> &nodesWithExits, int commonExit); - - /// Replacing some verteces with a new one and proper maintenance of edges - void replace(int newNodeNumber, QSet> &edgesToRemove, QSet &vertices); - void replace(int newNodeNumber, QSet> &edgesToRemove, QMap &verticesRoles); - void updateEdges(int newNodeNumber, QSet> &edgesToRemove, QSet &vertices); - void updatePostOrder(int newNodeNumber, QSet &vertices); - void updateDominators(int newNodeNumber, QSet &vertices); - void updateVertices(int newNodeNumber, QSet &vertices); - - /// methods used before structurization process - void calculateDominators(); - void findStartVertex(); - void calculatePostOrder(); - void createInitialNodesForIds(); - void dfs(int v, int ¤tTime, QMap &used); - - void appendNodesDetectedAsNodeWithExit(QSet &vertices, int cycleHead); - void removeNodesPreviouslyDetectedAsNodeWithExit(QSet &vertices); - int appendVertex(IntermediateStructurizatorNode *node); - - int outgoingEdgesNumber(int v) const; - int incomingEdgesNumber(int v) const; - - QMap mMapIdToInt; - QSet mVertices; - QMap> mFollowers; - QMap> mPredecessors; - QMap> mDominators; - QMap mPostOrder; - QMap mWasPreviouslyDetectedAsNodeWithExit; - - QMap mTrees; - - QSet mInitialIds; - int mVerticesNumber; - int mStartVertex; - int mMaxPostOrderTime; -}; - -} diff --git a/plugins/robots/generators/generatorBase/src/structurizatorNodes/blockStructurizatorNode.cpp b/plugins/robots/generators/generatorBase/src/structurizatorNodes/blockStructurizatorNode.cpp deleted file mode 100644 index 68e6ad29f9..0000000000 --- a/plugins/robots/generators/generatorBase/src/structurizatorNodes/blockStructurizatorNode.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright 2018 Konstantin Batoev - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. */ - -#include "blockStructurizatorNode.h" - -using namespace generatorBase; - -BlockStructurizatorNode::BlockStructurizatorNode(IntermediateStructurizatorNode *firstNode - , IntermediateStructurizatorNode *secondNode - , QObject *parent) - : IntermediateStructurizatorNode(parent) - , mFirstNode(firstNode) - , mSecondNode(secondNode) -{ -} - -IntermediateStructurizatorNode *BlockStructurizatorNode::firstNode() const -{ - return mFirstNode; -} - -IntermediateStructurizatorNode *BlockStructurizatorNode::secondNode() const -{ - return mSecondNode; -} - -bool BlockStructurizatorNode::analyzeBreak() -{ - if (mBreakWasAnalyzed) { - return mHasBreakInside; - } - - mHasBreakInside = mFirstNode->analyzeBreak() || mSecondNode->analyzeBreak(); - mBreakWasAnalyzed = true; - return mHasBreakInside; -} - -IntermediateStructurizatorNode::Type BlockStructurizatorNode::type() const -{ - return Type::block; -} - -qReal::Id BlockStructurizatorNode::firstId() const -{ - return firstNode()->firstId(); -} diff --git a/plugins/robots/generators/generatorBase/src/structurizatorNodes/blockStructurizatorNode.h b/plugins/robots/generators/generatorBase/src/structurizatorNodes/blockStructurizatorNode.h deleted file mode 100644 index 00486706f0..0000000000 --- a/plugins/robots/generators/generatorBase/src/structurizatorNodes/blockStructurizatorNode.h +++ /dev/null @@ -1,41 +0,0 @@ -/* Copyright 2018 Konstantin Batoev - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. */ - -#pragma once - -#include "intermediateStructurizatorNode.h" - -namespace generatorBase { - -class BlockStructurizatorNode : public IntermediateStructurizatorNode -{ - Q_OBJECT - -public: - explicit BlockStructurizatorNode(IntermediateStructurizatorNode *firstNode - , IntermediateStructurizatorNode *secondNode - , QObject *parent); - - IntermediateStructurizatorNode *firstNode() const; - IntermediateStructurizatorNode *secondNode() const; - - bool analyzeBreak(); - Type type() const; - qReal::Id firstId() const; -private: - IntermediateStructurizatorNode *mFirstNode; - IntermediateStructurizatorNode *mSecondNode; -}; - -} diff --git a/plugins/robots/generators/generatorBase/src/structurizatorNodes/breakStructurizatorNode.cpp b/plugins/robots/generators/generatorBase/src/structurizatorNodes/breakStructurizatorNode.cpp deleted file mode 100644 index 1a4f896aa2..0000000000 --- a/plugins/robots/generators/generatorBase/src/structurizatorNodes/breakStructurizatorNode.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* Copyright 2018 Konstantin Batoev - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. */ - -#include "breakStructurizatorNode.h" - -using namespace generatorBase; - -BreakStructurizatorNode::BreakStructurizatorNode(const qReal::Id &id, QObject *parent) - : IntermediateStructurizatorNode(parent) - , mId(id) -{ -} - -IntermediateStructurizatorNode::Type BreakStructurizatorNode::type() const -{ - return breakNode; -} - -qReal::Id BreakStructurizatorNode::firstId() const -{ - return mId; -} - -bool BreakStructurizatorNode::analyzeBreak() -{ - mHasBreakInside = true; - mBreakWasAnalyzed = true; - return mHasBreakInside; -} diff --git a/plugins/robots/generators/generatorBase/src/structurizatorNodes/breakStructurizatorNode.h b/plugins/robots/generators/generatorBase/src/structurizatorNodes/breakStructurizatorNode.h deleted file mode 100644 index 734ba56899..0000000000 --- a/plugins/robots/generators/generatorBase/src/structurizatorNodes/breakStructurizatorNode.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright 2018 Konstantin Batoev - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. */ - -#pragma once - -#include "intermediateStructurizatorNode.h" - -namespace generatorBase { - -class BreakStructurizatorNode : public IntermediateStructurizatorNode -{ - Q_OBJECT - -public: - explicit BreakStructurizatorNode(const qReal::Id &id, QObject *parent); - - Type type() const; - qReal::Id firstId() const; - bool analyzeBreak(); - -private: - const qReal::Id mId; -}; - -} diff --git a/plugins/robots/generators/generatorBase/src/structurizatorNodes/ifStructurizatorNode.cpp b/plugins/robots/generators/generatorBase/src/structurizatorNodes/ifStructurizatorNode.cpp deleted file mode 100644 index 5ec2975d42..0000000000 --- a/plugins/robots/generators/generatorBase/src/structurizatorNodes/ifStructurizatorNode.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* Copyright 2018 Konstantin Batoev - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. */ - -#include "ifStructurizatorNode.h" - -using namespace generatorBase; - -IfStructurizatorNode::IfStructurizatorNode(IntermediateStructurizatorNode *condition - , IntermediateStructurizatorNode *thenBranch - , IntermediateStructurizatorNode *elseBranch - , IntermediateStructurizatorNode *exit - , QObject *parent) - : IntermediateStructurizatorNode(parent) - , mCondition(condition) - , mThenBranch(thenBranch) - , mElseBranch(elseBranch) - , mExit(exit) -{ -} - -IntermediateStructurizatorNode *IfStructurizatorNode::condition() const -{ - return mCondition; -} - -IntermediateStructurizatorNode *IfStructurizatorNode::thenBranch() const -{ - return mThenBranch; -} - -IntermediateStructurizatorNode *IfStructurizatorNode::elseBranch() const -{ - return mElseBranch; -} - -IntermediateStructurizatorNode *IfStructurizatorNode::exit() const -{ - return mExit; -} - -bool IfStructurizatorNode::analyzeBreak() -{ - mHasBreakInside = mThenBranch->analyzeBreak(); - if (mElseBranch) { - mHasBreakInside |= mElseBranch->analyzeBreak(); - } - - return mHasBreakInside; -} - -IntermediateStructurizatorNode::Type IfStructurizatorNode::type() const -{ - return Type::ifThenElseCondition; -} - -qReal::Id IfStructurizatorNode::firstId() const -{ - return mCondition->firstId(); -} diff --git a/plugins/robots/generators/generatorBase/src/structurizatorNodes/ifStructurizatorNode.h b/plugins/robots/generators/generatorBase/src/structurizatorNodes/ifStructurizatorNode.h deleted file mode 100644 index 0443e401bc..0000000000 --- a/plugins/robots/generators/generatorBase/src/structurizatorNodes/ifStructurizatorNode.h +++ /dev/null @@ -1,47 +0,0 @@ -/* Copyright 2018 Konstantin Batoev - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. */ - -#pragma once - -#include "intermediateStructurizatorNode.h" - -namespace generatorBase { - -class IfStructurizatorNode : public IntermediateStructurizatorNode -{ - Q_OBJECT - -public: - explicit IfStructurizatorNode(IntermediateStructurizatorNode *condition - , IntermediateStructurizatorNode *thenBranch - , IntermediateStructurizatorNode *elseBranch - , IntermediateStructurizatorNode *exit - , QObject *parent); - - IntermediateStructurizatorNode *condition() const; - IntermediateStructurizatorNode *thenBranch() const; - IntermediateStructurizatorNode *elseBranch() const; - IntermediateStructurizatorNode *exit() const; - - bool analyzeBreak(); - Type type() const; - qReal::Id firstId() const; -private: - IntermediateStructurizatorNode *mCondition; - IntermediateStructurizatorNode *mThenBranch; - IntermediateStructurizatorNode *mElseBranch; - IntermediateStructurizatorNode *mExit; -}; - -} diff --git a/plugins/robots/generators/generatorBase/src/structurizatorNodes/intermediateStructurizatorNode.cpp b/plugins/robots/generators/generatorBase/src/structurizatorNodes/intermediateStructurizatorNode.cpp deleted file mode 100644 index bfccb7aed8..0000000000 --- a/plugins/robots/generators/generatorBase/src/structurizatorNodes/intermediateStructurizatorNode.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright 2018 Konstantin Batoev - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. */ - -#include "intermediateStructurizatorNode.h" - -using namespace generatorBase; - -IntermediateStructurizatorNode::IntermediateStructurizatorNode(QObject *parent) - : QObject(parent) - , mHasBreakInside(false) - , mBreakWasAnalyzed(false) -{ -} - -IntermediateStructurizatorNode::~IntermediateStructurizatorNode() -{ -} - -bool IntermediateStructurizatorNode::hasBreakInside() const -{ - return mHasBreakInside; -} diff --git a/plugins/robots/generators/generatorBase/src/structurizatorNodes/intermediateStructurizatorNode.h b/plugins/robots/generators/generatorBase/src/structurizatorNodes/intermediateStructurizatorNode.h deleted file mode 100644 index 49b0cd68fa..0000000000 --- a/plugins/robots/generators/generatorBase/src/structurizatorNodes/intermediateStructurizatorNode.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright 2018 Konstantin Batoev - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. */ - -#pragma once - -#include - -namespace generatorBase { - -class IntermediateStructurizatorNode : public QObject -{ - Q_OBJECT - -public: - - enum Type { - simple - , block - , ifThenElseCondition - , switchCondition - , infiniteloop - , whileloop - , breakNode - , nodeWithBreaks - }; - - explicit IntermediateStructurizatorNode(QObject *parent); - virtual ~IntermediateStructurizatorNode(); - - virtual Type type() const = 0; - virtual qReal::Id firstId() const = 0; - virtual bool analyzeBreak() = 0; - bool hasBreakInside() const; - -protected: - bool mHasBreakInside; - bool mBreakWasAnalyzed; -}; - -} diff --git a/plugins/robots/generators/generatorBase/src/structurizatorNodes/selfLoopStructurizatorNode.cpp b/plugins/robots/generators/generatorBase/src/structurizatorNodes/selfLoopStructurizatorNode.cpp deleted file mode 100644 index b69952be83..0000000000 --- a/plugins/robots/generators/generatorBase/src/structurizatorNodes/selfLoopStructurizatorNode.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright 2018 Konstantin Batoev - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. */ - -#include "selfLoopStructurizatorNode.h" - -using namespace generatorBase; - -SelfLoopStructurizatorNode::SelfLoopStructurizatorNode(IntermediateStructurizatorNode *bodyNode, QObject *parent) - : IntermediateStructurizatorNode(parent) - , mBodyNode(bodyNode) -{ -} - -IntermediateStructurizatorNode *SelfLoopStructurizatorNode::bodyNode() const -{ - return mBodyNode; -} - -bool SelfLoopStructurizatorNode::analyzeBreak() -{ - if (mBreakWasAnalyzed) { - return mHasBreakInside; - } - - mHasBreakInside = mBodyNode->analyzeBreak(); - mBreakWasAnalyzed = true; - return mHasBreakInside; -} - -IntermediateStructurizatorNode::Type SelfLoopStructurizatorNode::type() const -{ - return Type::infiniteloop; -} - -qReal::Id SelfLoopStructurizatorNode::firstId() const -{ - return mBodyNode->firstId(); -} diff --git a/plugins/robots/generators/generatorBase/src/structurizatorNodes/selfLoopStructurizatorNode.h b/plugins/robots/generators/generatorBase/src/structurizatorNodes/selfLoopStructurizatorNode.h deleted file mode 100644 index 9dcd65cd48..0000000000 --- a/plugins/robots/generators/generatorBase/src/structurizatorNodes/selfLoopStructurizatorNode.h +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright 2018 Konstantin Batoev - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. */ - -#pragma once - -#include "intermediateStructurizatorNode.h" - -namespace generatorBase { - -class SelfLoopStructurizatorNode : public IntermediateStructurizatorNode -{ - Q_OBJECT - -public: - explicit SelfLoopStructurizatorNode(IntermediateStructurizatorNode *bodyNode, QObject *parent = nullptr); - - IntermediateStructurizatorNode *bodyNode() const; - - bool analyzeBreak(); - Type type() const; - qReal::Id firstId() const; -private: - IntermediateStructurizatorNode *mBodyNode; -}; - -} diff --git a/plugins/robots/generators/generatorBase/src/structurizatorNodes/simpleStructurizatorNode.cpp b/plugins/robots/generators/generatorBase/src/structurizatorNodes/simpleStructurizatorNode.cpp deleted file mode 100644 index 21de08ca06..0000000000 --- a/plugins/robots/generators/generatorBase/src/structurizatorNodes/simpleStructurizatorNode.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright 2018 Konstantin Batoev - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. */ - -#include "simpleStructurizatorNode.h" - -using namespace generatorBase; - -SimpleStructurizatorNode::SimpleStructurizatorNode(const qReal::Id &id, QObject *parent) - : IntermediateStructurizatorNode(parent) - , mId(id) -{ -} - -IntermediateStructurizatorNode::Type SimpleStructurizatorNode::type() const -{ - return Type::simple; -} - -qReal::Id SimpleStructurizatorNode::firstId() const -{ - return mId; -} - -bool SimpleStructurizatorNode::analyzeBreak() -{ - mHasBreakInside = false; - return mHasBreakInside; -} - -qReal::Id SimpleStructurizatorNode::id() const -{ - return mId; -} diff --git a/plugins/robots/generators/generatorBase/src/structurizatorNodes/simpleStructurizatorNode.h b/plugins/robots/generators/generatorBase/src/structurizatorNodes/simpleStructurizatorNode.h deleted file mode 100644 index 6e071fa683..0000000000 --- a/plugins/robots/generators/generatorBase/src/structurizatorNodes/simpleStructurizatorNode.h +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright 2018 Konstantin Batoev - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. */ - -#pragma once - -#include "intermediateStructurizatorNode.h" - -namespace generatorBase { - -class SimpleStructurizatorNode : public IntermediateStructurizatorNode -{ - Q_OBJECT - -public: - explicit SimpleStructurizatorNode(const qReal::Id &id, QObject *parent = nullptr); - - Type type() const; - qReal::Id firstId() const; - bool analyzeBreak(); - - qReal::Id id() const; -private: - const qReal::Id mId; -}; - -} diff --git a/plugins/robots/generators/generatorBase/src/structurizatorNodes/structurizatorNodeWithBreaks.cpp b/plugins/robots/generators/generatorBase/src/structurizatorNodes/structurizatorNodeWithBreaks.cpp deleted file mode 100644 index fd8cac420b..0000000000 --- a/plugins/robots/generators/generatorBase/src/structurizatorNodes/structurizatorNodeWithBreaks.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/* Copyright 2018 Konstantin Batoev - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. */ - -#include "structurizatorNodeWithBreaks.h" - -using namespace generatorBase; - -StructurizatorNodeWithBreaks::StructurizatorNodeWithBreaks(IntermediateStructurizatorNode *condition - , const QList &exitBranches - , QObject *parent) - : IntermediateStructurizatorNode(parent) - , mCondition(condition) - , mExitBranches(exitBranches) -{ -} - -IntermediateStructurizatorNode *StructurizatorNodeWithBreaks::condition() const -{ - return mCondition; -} - -QList StructurizatorNodeWithBreaks::exitBranches() const -{ - return mExitBranches; -} - -QList StructurizatorNodeWithBreaks::restBranches() const -{ - return mRestBranches; -} - -void StructurizatorNodeWithBreaks::setRestBranches(const QList &restBranches) -{ - mRestBranches = restBranches; -} - -bool StructurizatorNodeWithBreaks::analyzeBreak() -{ - mHasBreakInside = true; - mBreakWasAnalyzed = true; - return mHasBreakInside; -} - -IntermediateStructurizatorNode::Type StructurizatorNodeWithBreaks::type() const -{ - return nodeWithBreaks; -} - -qReal::Id StructurizatorNodeWithBreaks::firstId() const -{ - return mCondition->firstId(); -} diff --git a/plugins/robots/generators/generatorBase/src/structurizatorNodes/structurizatorNodeWithBreaks.h b/plugins/robots/generators/generatorBase/src/structurizatorNodes/structurizatorNodeWithBreaks.h deleted file mode 100644 index a82c4ca140..0000000000 --- a/plugins/robots/generators/generatorBase/src/structurizatorNodes/structurizatorNodeWithBreaks.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright 2018 Konstantin Batoev - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. */ - -#pragma once - -#include "intermediateStructurizatorNode.h" - -namespace generatorBase { - -class StructurizatorNodeWithBreaks : public IntermediateStructurizatorNode -{ - Q_OBJECT - -public: - explicit StructurizatorNodeWithBreaks(IntermediateStructurizatorNode *condition - , const QList &exitBranches - , QObject *parent); - - IntermediateStructurizatorNode *condition() const; - QList exitBranches() const; - QList restBranches() const; - - void setRestBranches(const QList &restBranches); - bool analyzeBreak(); - Type type() const; - qReal::Id firstId() const; -private: - IntermediateStructurizatorNode *mCondition; - QList mExitBranches; - QList mRestBranches; -}; - -} diff --git a/plugins/robots/generators/generatorBase/src/structurizatorNodes/switchStructurizatorNode.cpp b/plugins/robots/generators/generatorBase/src/structurizatorNodes/switchStructurizatorNode.cpp deleted file mode 100644 index 8357361eca..0000000000 --- a/plugins/robots/generators/generatorBase/src/structurizatorNodes/switchStructurizatorNode.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* Copyright 2018 Konstantin Batoev - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. */ - -#include "switchStructurizatorNode.h" - -using namespace generatorBase; - -SwitchStructurizatorNode::SwitchStructurizatorNode(IntermediateStructurizatorNode *condition - , const QList &branches - , IntermediateStructurizatorNode *exit - , QObject *parent) - : IntermediateStructurizatorNode(parent) - , mCondition(condition) - , mBranches(QList(branches)) - , mExit(exit) -{ -} - -IntermediateStructurizatorNode *SwitchStructurizatorNode::condition() const -{ - return mCondition; -} - -QList SwitchStructurizatorNode::branches() const -{ - return mBranches; -} - -IntermediateStructurizatorNode *SwitchStructurizatorNode::exit() const -{ - return mExit; -} - -bool SwitchStructurizatorNode::analyzeBreak() -{ - if (mBreakWasAnalyzed) { - return mHasBreakInside; - } - - mHasBreakInside = false; - for (IntermediateStructurizatorNode *node : mBranches) { - mHasBreakInside |= node->analyzeBreak(); - } - - mBreakWasAnalyzed = true; - return mHasBreakInside; -} - -IntermediateStructurizatorNode::Type SwitchStructurizatorNode::type() const -{ - return Type::switchCondition; -} - -qReal::Id SwitchStructurizatorNode::firstId() const -{ - return mCondition->firstId(); -} diff --git a/plugins/robots/generators/generatorBase/src/structurizatorNodes/switchStructurizatorNode.h b/plugins/robots/generators/generatorBase/src/structurizatorNodes/switchStructurizatorNode.h deleted file mode 100644 index e166c58625..0000000000 --- a/plugins/robots/generators/generatorBase/src/structurizatorNodes/switchStructurizatorNode.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright 2018 Konstantin Batoev - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. */ - -#pragma once - -#include "intermediateStructurizatorNode.h" - -namespace generatorBase { - -class SwitchStructurizatorNode : public IntermediateStructurizatorNode -{ - Q_OBJECT - -public: - explicit SwitchStructurizatorNode(IntermediateStructurizatorNode *condition - , const QList &branches - , IntermediateStructurizatorNode *exit - , QObject *parent); - - IntermediateStructurizatorNode *condition() const; - QList branches() const; - IntermediateStructurizatorNode *exit() const; - - bool analyzeBreak(); - Type type() const; - qReal::Id firstId() const; -private: - IntermediateStructurizatorNode *mCondition; - const QList mBranches; - IntermediateStructurizatorNode *mExit; -}; - -} diff --git a/plugins/robots/generators/generatorBase/src/structurizatorNodes/whileStructurizatorNode.cpp b/plugins/robots/generators/generatorBase/src/structurizatorNodes/whileStructurizatorNode.cpp deleted file mode 100644 index cbb7154b8a..0000000000 --- a/plugins/robots/generators/generatorBase/src/structurizatorNodes/whileStructurizatorNode.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/* Copyright 2018 Konstantin Batoev - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. */ - -#include "whileStructurizatorNode.h" - -using namespace generatorBase; - -WhileStructurizatorNode::WhileStructurizatorNode(IntermediateStructurizatorNode *headNode - , IntermediateStructurizatorNode *bodyNode - , IntermediateStructurizatorNode *exitNode - , QObject *parent) - : IntermediateStructurizatorNode(parent) - , mHeadNode(headNode) - , mBodyNode(bodyNode) - , mExitNode(exitNode) -{ -} - -IntermediateStructurizatorNode *WhileStructurizatorNode::headNode() const -{ - return mHeadNode; -} - -IntermediateStructurizatorNode *WhileStructurizatorNode::bodyNode() const -{ - return mBodyNode; -} - -IntermediateStructurizatorNode *WhileStructurizatorNode::exitNode() const -{ - return mExitNode; -} - -bool WhileStructurizatorNode::analyzeBreak() -{ - if (mBreakWasAnalyzed) { - return mHasBreakInside; - } - - mHasBreakInside = mHeadNode->analyzeBreak() || mBodyNode->analyzeBreak(); - mBreakWasAnalyzed = true; - return mHasBreakInside; -} - -IntermediateStructurizatorNode::Type WhileStructurizatorNode::type() const -{ - return Type::whileloop; -} - -qReal::Id WhileStructurizatorNode::firstId() const -{ - return mHeadNode->firstId(); -} diff --git a/plugins/robots/generators/generatorBase/src/structurizatorNodes/whileStructurizatorNode.h b/plugins/robots/generators/generatorBase/src/structurizatorNodes/whileStructurizatorNode.h deleted file mode 100644 index c6721abb11..0000000000 --- a/plugins/robots/generators/generatorBase/src/structurizatorNodes/whileStructurizatorNode.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright 2018 Konstantin Batoev - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. */ - -#pragma once - -#include "intermediateStructurizatorNode.h" - -namespace generatorBase { - -class WhileStructurizatorNode : public IntermediateStructurizatorNode -{ - Q_OBJECT - -public: - explicit WhileStructurizatorNode(IntermediateStructurizatorNode *headNode - , IntermediateStructurizatorNode *bodyNode - , IntermediateStructurizatorNode *exitNode - , QObject *parent); - - IntermediateStructurizatorNode *headNode() const; - IntermediateStructurizatorNode *bodyNode() const; - IntermediateStructurizatorNode *exitNode() const; - - bool analyzeBreak(); - Type type() const; - qReal::Id firstId() const; -private: - IntermediateStructurizatorNode *mHeadNode; - IntermediateStructurizatorNode *mBodyNode; - IntermediateStructurizatorNode *mExitNode; -}; - -} diff --git a/plugins/robots/generators/generatorBase/src/structurizer.cpp b/plugins/robots/generators/generatorBase/src/structurizer.cpp new file mode 100644 index 0000000000..4c2791627e --- /dev/null +++ b/plugins/robots/generators/generatorBase/src/structurizer.cpp @@ -0,0 +1,199 @@ +#include "structurizer.h" + +#include + +#include "structurizerNodes/structurizerNode.h" +#include "structurizerNodes/simpleStructurizerNode.h" +#include "structurizerNodes/continuationStructurizerNode.h" +#include "structurizerNodes/sequenceStructurizerNode.h" +#include "structurizerNodes/ifStructurizerNode.h" +#include "structurizerNodes/loopStructurizerNode.h" +#include "structurizerNodes/switchStructurizerNode.h" + +using namespace generatorBase; + +Structurizer::Structurizer(QObject *parent) + : QObject(parent) +{ +} + +StructurizerNode *Structurizer::performStructurization(const QSet &verticesIds + , qReal::Id startVertex + , const QMap> &followers) +{ + mStartVertex = startVertex; + + for (const Vertex &v : verticesIds) { + mVertices.insert(v); + } + + for (const Vertex &v : mVertices) { + for (const Vertex &u : followers[v]) { + mFollowers[v].append(u); + mPredecessors[u].append(v); + } + } + + for (const Vertex &id : mVertices) { + if (mFollowers[id].size() == 0) { + mExits.insert(id); + } + } + + QMap color; + int time = 0; + for (const Vertex &v : verticesIds) { + color[v] = 0; + } + dfs(startVertex, time, color); + + QVector> vertices = {}; + for (const Vertex &v : verticesIds) { + vertices.append(qMakePair(v, mTopologicalOrder[v])); + } + qSort(vertices.begin(), vertices.end(), + [](const QPair &l, const QPair &r) { + return l.second < r.second; + }); + + QVector orderOfResolution; + for (const QPair &e : vertices) { + orderOfResolution.append(e.first); + } + + reorderLoopHeads(orderOfResolution); + + QMap system = {}; + + //system creating + for (const Vertex &id : orderOfResolution) { + SequenceStructurizerNode *var = new SequenceStructurizerNode(this); + if (mFollowers[id].size() <= 1) { + var->addToTheEnd(new SimpleStructurizerNode(id, this)); + if (mFollowers[id].size() == 1) { + var->addToTheEnd(new ContinuationStructurizerNode(mFollowers[id].first(), this)); + } + } else if (mFollowers[id].size() == 2) { + var->addToTheEnd(new IfStructurizerNode(id, mFollowers[id].first(), mFollowers[id].last(), this)); + } else if (mFollowers[id].size() > 2) { + var->addToTheEnd(new SwitchStructurizerNode(id, mFollowers[id], this)); + } + system[id] = var; + } + + //system solving + for (int i = 0; i < orderOfResolution.size(); ++i) { + Vertex v = orderOfResolution[i]; + + //if recursive + if (system[v]->containsContinuation(v)) { + system[v]->mergeConditionalBranches(mExits, mLoopHeads); + system[v]->derecursivate(v); + + for (int j = orderOfResolution.size() - 1; j > i; --j) { + if (system[v]->containsContinuation(orderOfResolution[j])) { + system[v]->mergeConditionalBranches(mExits, mLoopHeads); + system[v]->factorize(orderOfResolution[j], true); + } + } + } + + //elimination + for (int j = 0; j < orderOfResolution.size(); ++j) { + if (i == j) { + continue; + } + system[orderOfResolution[j]]->mergeConditionalBranches(mExits, mLoopHeads); + + system[orderOfResolution[j]]->factorize(v); + system[orderOfResolution[j]]->replaceContinuation(v, system[v]); + } + } + + return system[mStartVertex]; +} + +void Structurizer::dfs(Vertex v, int ¤tTime, QMap &color) +{ + color[v] = 1; + for (const Vertex &u : mFollowers[v]) { + if (color[u] == 0) { + dfs(u, currentTime, color); + } else if (color[u] == 1) { + mCyclicEdges.append(qMakePair(v, u)); + } + } + mTopologicalOrder[v] = currentTime--; + color[v] = 2; +} + +void Structurizer::reorderLoopHeads(QVector &vertexOrder) +{ + QMap> loopBody = {}; + for (auto &edge : mCyclicEdges) { + QQueue> queue; + queue.enqueue({edge.first, edge.second}); + while (!queue.empty()) { + auto currentPath = queue.dequeue(); + for (auto &nextVertex : mFollowers[currentPath.last()]) { + if (nextVertex == currentPath.first()) { + auto loopHead = currentPath.first(); + for (auto &i : currentPath) { + if (mTopologicalOrder[loopHead] > mTopologicalOrder[i]) { + loopHead = i; + } + } + for (auto &i : currentPath) { + if (i != loopHead) { + loopBody[loopHead].insert(i); + } + } + mLoopHeads.insert(loopHead); + } else if (nextVertex != edge.second && !currentPath.contains(nextVertex)) { + auto newPath = currentPath; + newPath.append(nextVertex); + queue.enqueue(newPath); + } + } + } + } + auto topOrder = vertexOrder; + + for (int i = topOrder.size() - 1; i >= 0; --i) { + Vertex e = topOrder[i]; + bool somethingChanged = true; + while (somethingChanged) { + somethingChanged = false; + for (auto &u : loopBody[e]) { + for (auto &f : mFollowers[u]) { + if (loopBody[e].contains(f) || (f == e)) { + continue; + } + bool isInLoop = true; + for (auto &p : mPredecessors[f]) { + if (!loopBody[e].contains(p)) { + isInLoop = false; + break; + } + } + if (isInLoop) { + somethingChanged = true; + loopBody[e].insert(f); + } + } + } + } + } + + for (int i = topOrder.size() - 1; i >= 0; --i) { + Vertex v = topOrder[i]; + int maxIndex = -1; + for (auto &u : loopBody[v]) { + maxIndex = maxIndex > vertexOrder.lastIndexOf(u) ? maxIndex : vertexOrder.lastIndexOf(u); + } + if (maxIndex > vertexOrder.lastIndexOf(v)) { + vertexOrder.insert(maxIndex + 1, v); + vertexOrder.erase(vertexOrder.begin() + vertexOrder.indexOf(v)); + } + } +} diff --git a/plugins/robots/generators/generatorBase/src/structurizer.h b/plugins/robots/generators/generatorBase/src/structurizer.h new file mode 100644 index 0000000000..9ac8da43b8 --- /dev/null +++ b/plugins/robots/generators/generatorBase/src/structurizer.h @@ -0,0 +1,45 @@ +#pragma once + +#include +#include + +#include + +namespace generatorBase { + +class StructurizerNode; +class SimpleStructurizerNode; +class ContinuationStructurizerNode; +class IfStructurizerNode; +class LoopStructurizerNode; + +class Structurizer : public QObject +{ + Q_OBJECT + +public: + explicit Structurizer(QObject *parent = nullptr); + + /// main function that performs structurization + StructurizerNode *performStructurization(const QSet &verticesIds, qReal::Id startVertex + , const QMap> &followers); + +private: + typedef qReal::Id Vertex; + + void dfs(Vertex v, int ¤tTime, QMap &color); + + QSet mVertices; + QMap> mFollowers; + QMap> mPredecessors; + QMap mTopologicalOrder; + QSet mExits; + QSet mLoopHeads; + + Vertex mStartVertex; + QVector> mCyclicEdges; + + void reorderLoopHeads(QVector &v); +}; + +} diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/breakStructurizerNode.cpp b/plugins/robots/generators/generatorBase/src/structurizerNodes/breakStructurizerNode.cpp new file mode 100644 index 0000000000..f9ea7b77c9 --- /dev/null +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/breakStructurizerNode.cpp @@ -0,0 +1,23 @@ +#include "breakStructurizerNode.h" + +using namespace generatorBase; + +BreakStructurizerNode::BreakStructurizerNode(QObject *parent) + : SimpleStructurizerNode(qReal::Id(), parent) +{ +} + +StructurizerNode::Type BreakStructurizerNode::type() const +{ + return breakFromLoop; +} + +bool BreakStructurizerNode::isEqual(StructurizerNode * other) const +{ + return other->type() == breakFromLoop; +} + +StructurizerNode *BreakStructurizerNode::clone() const +{ + return new BreakStructurizerNode(parent()); +} diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/breakStructurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/breakStructurizerNode.h new file mode 100644 index 0000000000..a722ecfd60 --- /dev/null +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/breakStructurizerNode.h @@ -0,0 +1,19 @@ +#pragma once + +#include "simpleStructurizerNode.h" + +namespace generatorBase { + +class BreakStructurizerNode : public SimpleStructurizerNode +{ + +public: + explicit BreakStructurizerNode(QObject *parent = nullptr); + + Type type() const; + bool isEqual(StructurizerNode *other) const; + + StructurizerNode *clone() const; + +}; +} diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/continuationStructurizerNode.cpp b/plugins/robots/generators/generatorBase/src/structurizerNodes/continuationStructurizerNode.cpp new file mode 100644 index 0000000000..2b08434528 --- /dev/null +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/continuationStructurizerNode.cpp @@ -0,0 +1,102 @@ +#include "continuationStructurizerNode.h" + +using namespace generatorBase; + +ContinuationStructurizerNode::ContinuationStructurizerNode(const Vertex &id, QObject *parent) + : StructurizerNode(parent) + , mId(id) +{ +} + +StructurizerNode::Type ContinuationStructurizerNode::type() const +{ + return Type::continuation; +} + +bool ContinuationStructurizerNode::containsContinuation(const Vertex &id) const +{ + if (id == Vertex()) { + return true; + } + return id == mId; +} + +int ContinuationStructurizerNode::numberOfContinuation(const Vertex &id) const +{ + if (id == Vertex()) { + return 1; + } + return id == mId ? 1 : 0; +} + +StructurizerNode *ContinuationStructurizerNode::clone() const +{ + return new ContinuationStructurizerNode(mId, parent()); +} + +StructurizerNode::Vertex ContinuationStructurizerNode::id() const +{ + return mId; +} + +bool ContinuationStructurizerNode::isEqual(StructurizerNode * other) const +{ + if (other->type() != continuation) { + return false; + } + return mId == other->id(); +} + +void ContinuationStructurizerNode::dropContinuations(const Vertex &id) +{ + Q_UNUSED(id) +} + +void ContinuationStructurizerNode::factorize(const Vertex &id, bool force) +{ + Q_UNUSED(id) + Q_UNUSED(force) +} + +void ContinuationStructurizerNode::derecursivate(const Vertex &id) +{ + Q_UNUSED(id) +} + +bool ContinuationStructurizerNode::mergeConditionalBranches(const QSet &exits, const QSet &loopHeads) +{ + Q_UNUSED(exits) + Q_UNUSED(loopHeads) + return false; +} + +void ContinuationStructurizerNode::transformDoWhile() +{ +} + +void ContinuationStructurizerNode::dropEmptyConditionals() +{ +} + +StructurizerNode::ConditionTree *ContinuationStructurizerNode::findAllContinuations(const Vertex &id) const +{ + Q_UNUSED(id) + return nullptr; +} + +void ContinuationStructurizerNode::replaceContinuation(const Vertex &id, StructurizerNode *value) +{ + Q_UNUSED(id) + Q_UNUSED(value) +} + + +int ContinuationStructurizerNode::numberOfConditionCalculating(const Vertex &id) const +{ + Q_UNUSED(id) + return 0; +} + +void ContinuationStructurizerNode::transformBeforeDerecursivation() +{ +} diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/continuationStructurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/continuationStructurizerNode.h new file mode 100644 index 0000000000..40d14df5e5 --- /dev/null +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/continuationStructurizerNode.h @@ -0,0 +1,42 @@ +#pragma once + +#include "structurizerNode.h" + +#include + +namespace generatorBase { + +class ContinuationStructurizerNode : public StructurizerNode +{ + Q_OBJECT + +public: + explicit ContinuationStructurizerNode(const Vertex &id, QObject *parent); + + Type type() const; + Vertex id() const; + + bool containsContinuation(const Vertex &id = Vertex()) const; + void dropContinuations(const Vertex &id); + int numberOfContinuation(const Vertex &id = Vertex()) const; + + void factorize(const Vertex &id, bool force = false); + void derecursivate(const Vertex &id); + void replaceContinuation(const Vertex &id, StructurizerNode *value); + + bool mergeConditionalBranches(const QSet &exits, const QSet &loopHeads); + void transformDoWhile(); + + void dropEmptyConditionals(); + + ConditionTree *findAllContinuations(const Vertex &id) const; + bool isEqual(StructurizerNode *other) const; + StructurizerNode *clone() const; + int numberOfConditionCalculating(const Vertex &id) const; + void transformBeforeDerecursivation(); + +protected: + const Vertex mId; + +}; +} diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/elementNode.cpp b/plugins/robots/generators/generatorBase/src/structurizerNodes/elementNode.cpp new file mode 100644 index 0000000000..1ec2b004f4 --- /dev/null +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/elementNode.cpp @@ -0,0 +1,436 @@ +#include "structurizerNode.h" + +using namespace generatorBase; + +StructurizerNode::StructurizerNode(QObject *parent) + : QObject(parent) +{ +} + +SimpleStructurizerNode::SimpleStructurizerNode(const qReal::Id &id, QObject *parent) + : StructurizerNode(parent) + , mId(id) +{ +} + +ContinuationStructurizerNode::ContinuationStructurizerNode(const qReal::Id &id, QObject *parent) + : StructurizerNode(parent) + , mId(id) +{ +} + +StructurizerNode::Type SimpleStructurizerNode::type() const +{ + return Type::simple; +} + +StructurizerNode::Type ContinuationStructurizerNode::type() const +{ + return Type::continuation; +} + +StructurizerNode::Type IfStructurizerNode::type() const +{ + return Type::ifThenElse; +} + +StructurizerNode::Type LoopStructurizerNode::type() const +{ + return Type::loop; +} + +bool SimpleStructurizerNode::containsContinuation(const Vertex &id) { + Q_UNUSED(id) + return false; +} + +bool ContinuationStructurizerNode::containsContinuation(const Vertex &id) { + if (id == qReal::Id()) { + return true; + } + return id == mId; +} + +bool IfStructurizerNode::containsContinuation(const Vertex &id) { + for (auto e : *mThenBranch) { + if (e->containsContinuation(id)) { + return true; + } + } + for (auto e : *mElseBranch) { + if (e->containsContinuation(id)) { + return true; + } + } + return false; +} + +bool LoopStructurizerNode::containsContinuation(const Vertex &id) { + for (auto e : *mBody) { + if (e->containsContinuation(id)) { + return true; + } + } + return false; +} + +bool SimpleStructurizerNode::containsNonContinuation() { + return true; +} + +bool ContinuationStructurizerNode::containsNonContinuation() { + return false; +} + +bool IfStructurizerNode::containsNonContinuation() { + for (auto e : *mThenBranch) { + if (e->containsNonContinuation()) { + return true; + } + } + for (auto e : *mElseBranch) { + if (e->containsNonContinuation()) { + return true; + } + } + return false; +} + +bool LoopStructurizerNode::containsNonContinuation() { + for (auto e : *mBody) { + if (e->containsNonContinuation()) { + return true; + } + } + return false; +} + +IfStructurizerNode::IfStructurizerNode(const Vertex &id, const Vertex &firstId, const Vertex &secondId, QObject *parent) + : StructurizerNode(parent) +{ + mThenBranch = new QVector(); + mThenBranch->append(new ContinuationStructurizerNode(firstId, parent)); + + mElseBranch = new QVector(); + mElseBranch->append(new ContinuationStructurizerNode(secondId, parent)); + + mCondition = new ConditionTree({id, firstId}); +} + +IfStructurizerNode::IfStructurizerNode(QObject *parent) + : StructurizerNode(parent) + , mCondition(nullptr) + , mThenBranch(new QVector()) + , mElseBranch(new QVector()) +{ +} + +IfStructurizerNode::IfStructurizerNode(ConditionTree * ifCondition, QObject *parent) + : StructurizerNode(parent) + , mCondition(ifCondition) + , mThenBranch(new QVector()) + , mElseBranch(new QVector()) +{ +} + +LoopStructurizerNode::LoopStructurizerNode(QObject *parent) + : StructurizerNode(parent) + , mCondition(nullptr) + , mDoWhileForm(true) +{ +} + +LoopStructurizerNode::LoopStructurizerNode(ConditionTree *c, QObject *parent) + : StructurizerNode(parent) + , mCondition(c) + , mDoWhileForm(true) +{ +} + + +StructurizerNode::~StructurizerNode() +{ + //qDebug() << "destructor element"; +} + + +StructurizerNode *SimpleStructurizerNode::clone() { + return new SimpleStructurizerNode(this->id(), this->parent()); +} + +StructurizerNode *ContinuationStructurizerNode::clone() { + return new ContinuationStructurizerNode(this->id(), this->parent()); +} + +StructurizerNode *IfStructurizerNode::clone() { + IfStructurizerNode *newCondition = new IfStructurizerNode(parent()); + newCondition->mCondition = mCondition->clone(); + for (auto e : *mThenBranch) { + newCondition->mThenBranch->append(e->clone()); + } + for (auto e : *mElseBranch) { + newCondition->mElseBranch->append(e->clone()); + } + return newCondition; +} + +StructurizerNode *LoopStructurizerNode::clone() { + LoopStructurizerNode *x = new LoopStructurizerNode(parent()); + auto xBody = new QVector(); + for (auto e : *mBody) { + xBody->append(e); + } + x->setBody(xBody); + x->mDoWhileForm = mDoWhileForm; + x->mCondition = mCondition == nullptr ? nullptr :mCondition->clone(); + return x; +} + +QVector *LoopStructurizerNode::body() { + return mBody; +} + +StructurizerNode::Vertex SimpleStructurizerNode::id() const +{ + return this->mId; +} + +StructurizerNode::Vertex ContinuationStructurizerNode::id() const +{ + return this->mId; +} + +StructurizerNode::Vertex LoopStructurizerNode::id() const +{ + if (mCondition == nullptr) + return qReal::Id(); + return mCondition->isValue() ? mCondition->value().first : qReal::Id(); +} + +StructurizerNode::Vertex IfStructurizerNode::id() const +{ + return mCondition->isValue() ? mCondition->value().first : qReal::Id(); +} + +void LoopStructurizerNode::setBody(QVector *body, int to) { + mBody = new QVector(); + for (int i = 0; i < (to == -1 ? body->size() : to); ++i) { + auto z = (*body)[i]->clone(); + mBody->append(z); + } +} + +QVector *IfStructurizerNode::thenBranch() { + return mThenBranch; +} + +QVector *IfStructurizerNode::elseBranch() { + return mElseBranch; +} + + +void IfStructurizerNode::dropContinuations(const Vertex &id) { + for (int i = 0; i < mThenBranch->size(); ++i) { + if ((*mThenBranch)[i]->type() == continuation) { + if ((id == qReal::Id()) || (id == (*mThenBranch)[i]->id())) { + mThenBranch->erase(mThenBranch->begin()+i--); + } + } else if ((*mThenBranch)[i]->type() == ifThenElse) { + dynamic_cast((*mThenBranch)[i])->dropContinuations(id); + } + } + for (int i = 0; i < mElseBranch->size(); ++i) { + if ((*mElseBranch)[i]->type() == continuation) { + if ((id == qReal::Id()) || (id == (*mElseBranch)[i]->id())) { + mElseBranch->erase(mElseBranch->begin()+i--); + } + } else if ((*mElseBranch)[i]->type() == ifThenElse) { + dynamic_cast((*mElseBranch)[i])->dropContinuations(id); + } + } +} + +void IfStructurizerNode::dropNonContinuations() { + for (int i = 0; i < mThenBranch->size(); ++i) { + if ((*mThenBranch)[i]->type() == simple || (*mThenBranch)[i]->type() == loop) { + mThenBranch->erase(mThenBranch->begin()+i--); + } else if ((*mThenBranch)[i]->type() == ifThenElse) { + dynamic_cast((*mThenBranch)[i])->dropNonContinuations(); + } + } + for (int i = 0; i < mElseBranch->size(); ++i) { + if ((*mElseBranch)[i]->type() == simple || (*mElseBranch)[i]->type() == loop) { + mElseBranch->erase(mElseBranch->begin()+i--); + } else if ((*mElseBranch)[i]->type() == ifThenElse) { + dynamic_cast((*mElseBranch)[i])->dropNonContinuations(); + } + } +} + +bool IfStructurizerNode::hasSameCondition(IfStructurizerNode *x) { + if ((mCondition == nullptr) && (x->mCondition == nullptr)) + return true; + if ((mCondition == nullptr) xor (x->mCondition == nullptr)) + return false; + return mCondition->isEqual(x->mCondition); +} + +bool LoopStructurizerNode::hasSameCondition(LoopStructurizerNode *x) { + if ((mCondition == nullptr) && (x->mCondition == nullptr)) + return true; + if ((mCondition == nullptr) xor (x->mCondition == nullptr)) + return false; + return mCondition->isEqual(x->mCondition); +} + +bool SimpleStructurizerNode::isEqual(StructurizerNode * another) { + if (another->type() != simple) { + return false; + } + return mId == another->id(); +} + +bool ContinuationStructurizerNode::isEqual(StructurizerNode * another) { + if (another->type() != continuation) { + return false; + } + return mId == another->id(); +} + +bool IfStructurizerNode::isEqual(StructurizerNode * another) { + if (another->type() != ifThenElse) { + return false; + } + if (!hasSameCondition(dynamic_cast(another))) { + return false; + } + if (mThenBranch->size() != dynamic_cast(another)->thenBranch()->size() + || mElseBranch->size() != dynamic_cast(another)->elseBranch()->size()) { + return false; + } + for (int i = 0; i < mThenBranch->size(); ++i) { + if (!(*mThenBranch)[i]->isEqual((*dynamic_cast(another)->thenBranch())[i])) { + return false; + } + } + for (int i = 0; i < mElseBranch->size(); ++i) { + if (!(*mElseBranch)[i]->isEqual((*dynamic_cast(another)->elseBranch())[i])) { + return false; + } + } + return true; +} + +bool LoopStructurizerNode::isEqual(StructurizerNode * another) { + if (another->type() != loop) { + return false; + } + if (!hasSameCondition(dynamic_cast(another))) { + return false; + } + if (mBody->size() != dynamic_cast(another)->body()->size()) { + return false; + } + for (int i = 0; i < mBody->size(); ++i) { + if (!(*mBody)[i]->isEqual((*dynamic_cast(another)->body())[i])) { + return false; + } + } + return true; +} + +StructurizerNode::ConditionTree *IfStructurizerNode::findAllContinuations(const Vertex &id) { + ConditionTree *trueCases = nullptr; + ConditionTree *falseCases = nullptr; + bool alwaysTrue = false; + for (auto i : *mThenBranch) { + if (i->containsContinuation(id)) { + ConditionTree *found = nullptr; + if (i->type() == continuation) { + alwaysTrue = true; + trueCases = nullptr; + break; + } else if (i->type() == ifThenElse) { + found = dynamic_cast(i)->findAllContinuations(id); + if (found == nullptr) { + alwaysTrue = true; + trueCases = nullptr; + break; + } + } + if (trueCases == nullptr) { + trueCases = found; + } else { + trueCases = new ConditionTree(OR, trueCases, found); + } + } + } + bool alwaysFalse = false; + for (auto i : *mElseBranch) { + if (i->containsContinuation(id)) { + ConditionTree *found = nullptr; + if (i->type() == continuation) { + alwaysFalse = true; + falseCases = nullptr; + break; + } else if (i->type() == ifThenElse) { + found = dynamic_cast(i)->findAllContinuations(id); + if (found == nullptr) { + alwaysFalse = true; + falseCases = nullptr; + break; + } + } + if (falseCases == nullptr) { + falseCases = found; + } else { + falseCases = new ConditionTree(OR, falseCases, found); + } + } + } + if (alwaysTrue && alwaysFalse) { + return nullptr; + } + if (trueCases != nullptr && falseCases != nullptr) { + if (trueCases->isNegativeTo(falseCases)) + return nullptr; + auto invertedTree = mCondition->clone(); + invertedTree->invert(); + if (falseCases != nullptr) + return new ConditionTree(OR, new ConditionTree(AND, mCondition->clone(), trueCases), new ConditionTree(AND, invertedTree, falseCases)); + } + if (alwaysTrue) { + if (falseCases != nullptr) { + auto invertedTree = mCondition->clone(); + invertedTree->invert(); + return new ConditionTree(OR, mCondition->clone(), new ConditionTree(AND, invertedTree, falseCases)); + } + return mCondition->clone(); + } + if (alwaysFalse) { + auto invertedTree = mCondition->clone(); + invertedTree->invert(); + if (trueCases != nullptr) { + return new ConditionTree(OR, new ConditionTree(AND, mCondition->clone(), trueCases), invertedTree); + } + return invertedTree; + } + if ((trueCases == nullptr) && (falseCases != nullptr)) { + auto invertedTree = mCondition->clone(); + invertedTree->invert(); + return new ConditionTree(AND, invertedTree, falseCases); + } + if ((trueCases != nullptr) && (falseCases == nullptr)) { + return new ConditionTree(AND, mCondition->clone(), trueCases); + } + qDebug() << "INAPROPRITE CONDITIONNODE"; + return nullptr; +} + +StructurizerNode::ConditionTree *IfStructurizerNode::condition() { + return mCondition; +} + +StructurizerNode::ConditionTree *LoopStructurizerNode::condition() { + return mCondition; +} diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/elementNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/elementNode.h new file mode 100644 index 0000000000..ab54f6c5f9 --- /dev/null +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/elementNode.h @@ -0,0 +1,49 @@ +#pragma once + +#include "structurizerNode.h" + +#include + +namespace generatorBase { + +class IfStructurizerNode : public StructurizerNode +{ + Q_OBJECT + +public: + explicit IfStructurizerNode(const qReal::Id &id, const qReal::Id &firstId, const qReal::Id &secondId, QObject *parent); + explicit IfStructurizerNode(ConditionTree *ifCondition, QObject *parent); + explicit IfStructurizerNode(QObject *parent); + + Type type() const; + Vertex id() const; + + QVector *thenBranch(); + QVector *elseBranch(); + + ConditionTree *condition(); + + bool containsContinuation(const Vertex &id = qReal::Id()); + bool containsNonContinuation(); + bool isEqual(StructurizerNode * another); + ConditionTree *findAllContinuations(const Vertex &id); + + StructurizerNode *clone(); + + bool hasSameCondition(IfStructurizerNode *x); + + //StructurizerNode copy(); + + void dropContinuations(const Vertex &id = qReal::Id()); + void dropNonContinuations(); + + +protected: + + ConditionTree *mCondition; + + QVector *mThenBranch; + QVector *mElseBranch; +}; + +} diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/ifStructurizerNode.cpp b/plugins/robots/generators/generatorBase/src/structurizerNodes/ifStructurizerNode.cpp new file mode 100644 index 0000000000..511c6e1f73 --- /dev/null +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/ifStructurizerNode.cpp @@ -0,0 +1,203 @@ +#include "ifStructurizerNode.h" +#include "simpleStructurizerNode.h" +#include "continuationStructurizerNode.h" +#include "sequenceStructurizerNode.h" + +using namespace generatorBase; + +StructurizerNode::Type IfStructurizerNode::type() const +{ + return Type::ifThenElse; +} + +bool IfStructurizerNode::isEmpty() const +{ + return (static_cast(mThenBranch)->children().size() == 0) + && (static_cast(mElseBranch)->children().size() == 0); +} + +bool IfStructurizerNode::containsContinuation(const Vertex &id) const +{ + return mThenBranch->containsContinuation(id) || mElseBranch->containsContinuation(id); +} + +int IfStructurizerNode::numberOfContinuation(const Vertex &id) const +{ + return mThenBranch->numberOfContinuation(id) + mElseBranch->numberOfContinuation(id); +} + +IfStructurizerNode::IfStructurizerNode(const Vertex &id, const Vertex &firstId, const Vertex &secondId, QObject *parent) + : StructurizerNode(parent) +{ + mThenBranch = new SequenceStructurizerNode(parent); + static_cast(mThenBranch)->addToTheEnd(new ContinuationStructurizerNode(firstId, parent)); + + mElseBranch = new SequenceStructurizerNode(parent); + static_cast(mElseBranch)->addToTheEnd(new ContinuationStructurizerNode(secondId, parent)); + + mCondition = new ConditionTree({id, firstId}); +} + +/*IfStructurizerNode::IfStructurizerNode(QObject *parent) + : StructurizerNode(parent) + , mCondition(nullptr) + , mThenBranch(new SequenceStructurizerNode(parent)) + , mElseBranch(new SequenceStructurizerNode(parent)) +{ +}*/ + +IfStructurizerNode::IfStructurizerNode(const ConditionTree * ifCondition, QObject *parent) + : StructurizerNode(parent) + , mCondition(ifCondition) + , mThenBranch(new SequenceStructurizerNode(parent)) + , mElseBranch(new SequenceStructurizerNode(parent)) +{ +} + +StructurizerNode *IfStructurizerNode::clone() const +{ + IfStructurizerNode *newIf = new IfStructurizerNode(mCondition->clone(), parent()); + for (auto &e : static_cast(mThenBranch)->children()) { + static_cast(newIf->mThenBranch)->addToTheEnd(e->clone()); + } + for (auto &e : static_cast(mElseBranch)->children()) { + static_cast(newIf->mElseBranch)->addToTheEnd(e->clone()); + } + return newIf; +} + +StructurizerNode::Vertex IfStructurizerNode::id() const +{ + return mCondition->isValue() ? mCondition->value().first : Vertex(); +} + + +StructurizerNode *IfStructurizerNode::thenBranch() +{ + return mThenBranch; +} + +StructurizerNode *IfStructurizerNode::elseBranch() +{ + return mElseBranch; +} + +void IfStructurizerNode::dropContinuations(const Vertex &id) +{ + mThenBranch->dropContinuations(id); + mElseBranch->dropContinuations(id); +} + +bool IfStructurizerNode::isEqual(StructurizerNode * other) const +{ + if (other->type() != ifThenElse) { + return false; + } + if (!mCondition->isEqual(static_cast(other)->mCondition)) { + return false; + } + if (!mThenBranch->isEqual(static_cast(other)->mThenBranch)) { + return false; + } + if (!mElseBranch->isEqual(static_cast(other)->mElseBranch)) { + return false; + } + return true; +} + +StructurizerNode::ConditionTree *IfStructurizerNode::findAllContinuations(const Vertex &id) const +{ + ConditionTree *tree = nullptr; + if (mThenBranch->containsContinuation(id)) { + ConditionTree *thenTree = mThenBranch->findAllContinuations(id); + if (thenTree == nullptr) { + tree = mCondition->clone(); + } else { + tree = new ConditionTree(ConditionTree::AND, mCondition->clone(), thenTree); + } + } + + if (mElseBranch->containsContinuation(id)) { + ConditionTree *invertedCondition = mCondition->clone(); + invertedCondition->invert(); + ConditionTree *elseTree = mElseBranch->findAllContinuations(id); + if (elseTree == nullptr) { + elseTree = invertedCondition; + } else { + elseTree = new ConditionTree(ConditionTree::AND, invertedCondition, elseTree); + } + if (tree == nullptr) { + tree = elseTree; + } else { + tree = new ConditionTree(ConditionTree::OR, tree, elseTree); + } + } + + if (tree == nullptr || tree->isTrue()) { + delete tree; + return nullptr; + } + return tree; +} + +void IfStructurizerNode::factorize(const Vertex &id, bool force) +{ + Q_UNUSED(id) + Q_UNUSED(force) +} + +void IfStructurizerNode::derecursivate(const Vertex &id) +{ + Q_UNUSED(id) +} + +bool IfStructurizerNode::mergeConditionalBranches(const QSet &exits, const QSet &loopHeads) +{ + if (mThenBranch->mergeConditionalBranches(exits, loopHeads)) + return true; + if (mElseBranch->mergeConditionalBranches(exits, loopHeads)) + return true; + return false; +} + +void IfStructurizerNode::transformDoWhile() +{ + mThenBranch->transformDoWhile(); + mElseBranch->transformDoWhile(); +} + +void IfStructurizerNode::dropEmptyConditionals() +{ + mThenBranch->dropEmptyConditionals(); + mElseBranch->dropEmptyConditionals(); +} + +StructurizerNode::ConditionTree *IfStructurizerNode::condition() const +{ + return mCondition->clone(); +} + +IfStructurizerNode::~IfStructurizerNode() +{ + delete mCondition; +} + +void IfStructurizerNode::replaceContinuation(const Vertex &id, StructurizerNode *value) +{ + mThenBranch->replaceContinuation(id, value); + mElseBranch->replaceContinuation(id, value); +} + +int IfStructurizerNode::numberOfConditionCalculating(const Vertex &id) const +{ + int count = mCondition->numberOfFirstVertex(id); + count += mThenBranch->numberOfConditionCalculating(id); + count += mElseBranch->numberOfConditionCalculating(id); + return count; +} + +void IfStructurizerNode::transformBeforeDerecursivation() +{ + mThenBranch->transformBeforeDerecursivation(); + mElseBranch->transformBeforeDerecursivation(); +} diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/ifStructurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/ifStructurizerNode.h new file mode 100644 index 0000000000..589c87eb9a --- /dev/null +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/ifStructurizerNode.h @@ -0,0 +1,53 @@ +#pragma once + +#include "structurizerNode.h" + +#include + +namespace generatorBase { + +class IfStructurizerNode : public StructurizerNode +{ + Q_OBJECT + +public: + explicit IfStructurizerNode(const Vertex &id, const Vertex &firstId, const Vertex &secondId, QObject *parent); + explicit IfStructurizerNode(const ConditionTree *ifCondition, QObject *parent); + + Type type() const; + Vertex id() const; + + bool containsContinuation(const Vertex &id = Vertex()) const; + void dropContinuations(const Vertex &id); + int numberOfContinuation(const Vertex &id = Vertex()) const; + + void factorize(const Vertex &id, bool force = false); + void derecursivate(const Vertex &id); + void replaceContinuation(const Vertex &id, StructurizerNode *value); + + bool mergeConditionalBranches(const QSet &exits, const QSet &loopHeads); + void transformDoWhile(); + + ConditionTree *findAllContinuations(const Vertex &id) const; + bool isEqual(StructurizerNode *other) const; + StructurizerNode *clone() const; + int numberOfConditionCalculating(const Vertex &id) const; + + void dropEmptyConditionals(); + + ConditionTree *condition() const; + StructurizerNode *thenBranch(); + StructurizerNode *elseBranch(); + bool isEmpty() const; + void transformBeforeDerecursivation(); + ~IfStructurizerNode(); + +protected: + + const ConditionTree *mCondition; + StructurizerNode *mThenBranch; + StructurizerNode *mElseBranch; + +}; + +} diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/loopStructurizerNode.cpp b/plugins/robots/generators/generatorBase/src/structurizerNodes/loopStructurizerNode.cpp new file mode 100644 index 0000000000..dc9c860ecf --- /dev/null +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/loopStructurizerNode.cpp @@ -0,0 +1,139 @@ +#include "loopStructurizerNode.h" +#include "sequenceStructurizerNode.h" +#include "ifStructurizerNode.h" + +using namespace generatorBase; + +StructurizerNode::Type LoopStructurizerNode::type() const +{ + return Type::loop; +} + +bool LoopStructurizerNode::containsContinuation(const Vertex &id) const +{ + return mBody->containsContinuation(id); +} + +int LoopStructurizerNode::numberOfContinuation(const Vertex &id) const +{ + return mBody->numberOfContinuation(id); +} + +LoopStructurizerNode::LoopStructurizerNode(QObject *parent) + : StructurizerNode(parent) + , mId(Vertex()) + , mInvertedCondition(false) + , mBody(new SequenceStructurizerNode(parent)) +{ +} + +LoopStructurizerNode::LoopStructurizerNode(const Vertex &id, bool invertCondition, QObject *parent) + : StructurizerNode(parent) + , mId(id) + , mInvertedCondition(invertCondition) + , mBody(new SequenceStructurizerNode(parent)) +{ +} + +StructurizerNode *LoopStructurizerNode::clone() const +{ + LoopStructurizerNode *loop = nullptr; + if (!mId.isNull()) { + loop = new LoopStructurizerNode(mId, mInvertedCondition, parent()); + } else { + loop = new LoopStructurizerNode(parent()); + } + for (StructurizerNode *&e : static_cast(mBody)->children()) { + loop->addToBody(e->clone()); + } + return loop; +} + +StructurizerNode::Vertex LoopStructurizerNode::id() const +{ + return mId; +} + +bool LoopStructurizerNode::isEqual(StructurizerNode * other) const +{ + if (other->type() != loop) { + return false; + } + if (mId != other->id()) { + return false; + } + if (mInvertedCondition != static_cast(other)->mInvertedCondition) { + return false; + } + if (!mBody->isEqual(static_cast(other)->mBody)) { + return false; + } + return true; +} + +void LoopStructurizerNode::dropContinuations(const Vertex &id) +{ + mBody->dropContinuations(id); +} + +void LoopStructurizerNode::factorize(const Vertex &id, bool force) +{ + Q_UNUSED(id) + Q_UNUSED(force) +} + +void LoopStructurizerNode::derecursivate(const Vertex &id) +{ + Q_UNUSED(id) +} + +bool LoopStructurizerNode::mergeConditionalBranches(const QSet &exits, const QSet &loopHeads) +{ + return mBody->mergeConditionalBranches(exits, loopHeads); +} + +void LoopStructurizerNode::transformDoWhile() +{ + mBody->transformDoWhile(); +} + +void LoopStructurizerNode::dropEmptyConditionals() +{ + mBody->dropEmptyConditionals(); +} + +StructurizerNode::ConditionTree *LoopStructurizerNode::findAllContinuations(const Vertex &id) const +{ + Q_UNUSED(id); + qDebug() << "WANT FACTORIZE FROM LOOP"; + return nullptr; +} + +StructurizerNode *LoopStructurizerNode::body() +{ + return mBody; +} + +void LoopStructurizerNode::addToBody(StructurizerNode *e) +{ + static_cast(mBody)->addToTheEnd(e); +} + +void LoopStructurizerNode::replaceContinuation(const Vertex &id, StructurizerNode *value) +{ + mBody->replaceContinuation(id, value); +} + +int LoopStructurizerNode::numberOfConditionCalculating(const Vertex &id) const +{ + return (mId == id ? 1 : 0) + mBody->numberOfConditionCalculating(id); +} + +void LoopStructurizerNode::transformBeforeDerecursivation() +{ +} + +bool LoopStructurizerNode::isInverted() const +{ + return mInvertedCondition; +} diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/loopStructurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/loopStructurizerNode.h new file mode 100644 index 0000000000..bea01bb290 --- /dev/null +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/loopStructurizerNode.h @@ -0,0 +1,51 @@ +#pragma once + +#include "structurizerNode.h" + +#include + +namespace generatorBase { + +class LoopStructurizerNode : public StructurizerNode +{ + Q_OBJECT + +public: + explicit LoopStructurizerNode(QObject *parent); + explicit LoopStructurizerNode(const Vertex &id, bool invertCondition, QObject *parent); + + Type type() const; + Vertex id() const; + + bool containsContinuation(const Vertex &id = Vertex()) const; + void dropContinuations(const Vertex &id); + int numberOfContinuation(const Vertex &id = Vertex()) const; + + void factorize(const Vertex &id, bool force = false); + void derecursivate(const Vertex &id); + void replaceContinuation(const Vertex &id, StructurizerNode *value); + + bool mergeConditionalBranches(const QSet &exits, const QSet &loopHeads); + void transformDoWhile(); + + ConditionTree *findAllContinuations(const Vertex &id) const; + bool isEqual(StructurizerNode *other) const; + StructurizerNode *clone() const; + int numberOfConditionCalculating(const Vertex &id) const; + + void dropEmptyConditionals(); + + bool isInverted() const; + StructurizerNode *body(); + void addToBody(StructurizerNode *e); + void transformBeforeDerecursivation(); + +protected: + + const Vertex mId; + const bool mInvertedCondition; + StructurizerNode *mBody; + +}; + +} diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/sequenceStructurizerNode.cpp b/plugins/robots/generators/generatorBase/src/structurizerNodes/sequenceStructurizerNode.cpp new file mode 100644 index 0000000000..415e0d0980 --- /dev/null +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/sequenceStructurizerNode.cpp @@ -0,0 +1,367 @@ +#include "sequenceStructurizerNode.h" + +#include "continuationStructurizerNode.h" +#include "ifStructurizerNode.h" +#include "loopStructurizerNode.h" +#include "switchStructurizerNode.h" + +using namespace generatorBase; + +SequenceStructurizerNode::SequenceStructurizerNode(QObject *parent) + : StructurizerNode(parent) + , mChildren({}) +{ +} + +StructurizerNode::Type SequenceStructurizerNode::type() const +{ + return sequence; +} + +StructurizerNode::Vertex SequenceStructurizerNode::id() const +{ + return Vertex(); +} + +bool SequenceStructurizerNode::containsContinuation(const Vertex &id) const +{ + for (auto e : mChildren) { + if (e->containsContinuation(id)) { + return true; + } + } + return false; +} + +void SequenceStructurizerNode::dropContinuations(const Vertex &id) +{ + for (int i = 0; i < mChildren.size(); ++i) { + if (mChildren[i]->type() == StructurizerNode::continuation) { + if (mChildren[i]->id() == id) { + mChildren.erase(mChildren.begin() + i--); + } + } else { + mChildren[i]->dropContinuations(id); + } + } +} + +int SequenceStructurizerNode::numberOfContinuation(const Vertex &id) const +{ + int count = 0; + for (auto e : mChildren) { + count = count + e->numberOfContinuation(id); + } + return count; +} + + + +void SequenceStructurizerNode::addToTheEnd(StructurizerNode *s) { + if (s->type() == sequence) { + for (StructurizerNode *e : static_cast(s)->mChildren) { + mChildren.append(e); + } + } else { + mChildren.append(s); + } +} + + + +StructurizerNode *SequenceStructurizerNode::clone() const +{ + SequenceStructurizerNode *x = new SequenceStructurizerNode(parent()); + for (auto e : mChildren) { + x->addToTheEnd(e); + } + return x; +} + +QVector SequenceStructurizerNode::children() +{ + return mChildren; +} + + +bool SequenceStructurizerNode::isEqual(StructurizerNode *other) const +{ + if (other->type() != sequence) { + return false; + } + for (int i = 0; i < mChildren.size(); ++i) { + if (!mChildren[i]->isEqual(static_cast(other)->mChildren[i])) { + return false; + } + } + return true; +} + +StructurizerNode::ConditionTree *SequenceStructurizerNode::findAllContinuations(const Vertex &id) const +{ + ConditionTree *finalTree = nullptr; + for (int i = 0; i < mChildren.size(); ++i) { + if (mChildren[i]->containsContinuation(id)) { + ConditionTree *tree = mChildren[i]->findAllContinuations(id); + if (tree == nullptr) { + delete finalTree; + return nullptr; + } + if (finalTree == nullptr) { + finalTree = tree; + } else { + finalTree = new ConditionTree(ConditionTree::OR, finalTree, tree); + if (finalTree->isTrue()) { + delete finalTree; + return nullptr; + } + } + } + } + return finalTree; +} + +void SequenceStructurizerNode::factorize(const Vertex &id, bool force) +{ + int totalCount = 0; + ConditionTree *ifCondition = nullptr; + int lastIndex = -1; + bool always = false; + for (int i = 0; i < mChildren.size(); ++i) { + if (mChildren[i]->containsContinuation(id)) { + totalCount += mChildren[i]->numberOfContinuation(id); + lastIndex = i; + if (always) { + continue; + } + ConditionTree *tree = mChildren[i]->findAllContinuations(id); + if (tree == nullptr) { + //we always come to it + always = true; + delete ifCondition; + ifCondition = nullptr; + } else { + if (ifCondition == nullptr) { + ifCondition = tree; + } else { + if (ifCondition->isNegativeTo(tree)) { + always = true; + delete ifCondition; + ifCondition = nullptr; + } + else { + ifCondition = new ConditionTree(ConditionTree::OR, tree, ifCondition); + } + } + } + } + } + if ((!force && totalCount < 2) || (totalCount == 0)) { + delete ifCondition; + return; + } + for (int i = 0; i <= lastIndex; ++i) { + if (mChildren[i]->containsContinuation(id) && mChildren[i]->type() == continuation) { + mChildren.erase(mChildren.begin() + i--); + --lastIndex; + } else { + mChildren[i]->dropContinuations(id); + } + } + if ((ifCondition == nullptr) || (ifCondition->isTrue())) { + mChildren.insert(lastIndex + 1, new ContinuationStructurizerNode(id, parent())); + } else { + StructurizerNode *t = new IfStructurizerNode(ifCondition, parent()); + StructurizerNode *thenBranch = static_cast(t)->thenBranch(); + static_cast(thenBranch)->addToTheEnd(new ContinuationStructurizerNode(id, parent())); + //wtf + mChildren.insert(lastIndex + 1, t); + } + dropEmptyConditionals(); +} + +void SequenceStructurizerNode::derecursivate(const Vertex &id) +{ + if (mChildren.size() == 1 && mChildren[0]->type() == ifThenElse) { + auto onlyIf = static_cast(mChildren[0]); + if (onlyIf->thenBranch()->containsContinuation(id) + && !onlyIf->elseBranch()->containsContinuation(id)) + { + onlyIf->thenBranch()->dropContinuations(id); + auto ifCondition = onlyIf->condition(); + auto loop = new LoopStructurizerNode(ifCondition->value().first + , ifCondition->isInverted(), parent()); + + for (auto &e : static_cast(onlyIf->thenBranch())->mChildren) { + loop->addToBody(e); + } + for (auto &e : static_cast(onlyIf->elseBranch())->mChildren) { + mChildren.append(e); + } + mChildren.pop_front(); + mChildren.prepend(loop); + return; + } + + if (onlyIf->elseBranch()->containsContinuation(id) + && !onlyIf->thenBranch()->containsContinuation(id)) + { + onlyIf->elseBranch()->dropContinuations(id); + auto invertedCondition = onlyIf->condition(); + invertedCondition->invert(); + + auto loop = new LoopStructurizerNode(invertedCondition->value().first + , invertedCondition->isInverted(), parent()); + + for (auto &e : static_cast(onlyIf->elseBranch())->mChildren) { + loop->addToBody(e); + } + for (auto &e : static_cast(onlyIf->thenBranch())->mChildren) { + mChildren.append(e); + } + mChildren.pop_front(); + mChildren.prepend(loop); + return; + } + } + + dropContinuations(id); + LoopStructurizerNode *loop = new LoopStructurizerNode(parent()); + for (auto &e : mChildren) { + loop->addToBody(e); + } + mChildren.clear(); + mChildren.append(loop); +} + +bool SequenceStructurizerNode::mergeConditionalBranches(const QSet &exits, const QSet &loopHeads) +{ + bool result = false; + for (int i = 0; i < mChildren.size(); ++i) { + if (mChildren[i]->mergeConditionalBranches(exits, loopHeads)) { + result = true; + } + if (mChildren[i]->type() == ifThenElse) { + SequenceStructurizerNode *first = static_cast(static_cast(mChildren[i])->thenBranch()); + SequenceStructurizerNode *second = static_cast(static_cast(mChildren[i])->elseBranch()); + if (first->mChildren.size() == 0 || second->mChildren.size() == 0) { + continue; + } + if (!loopHeads.contains(mChildren[i]->id())) { + if ((first->mChildren.last()->type() == continuation) + && (second->mChildren.last()->type() == simple) + && exits.contains(second->mChildren.last()->id())) + { + second->addToTheEnd(first->mChildren.last()->clone()); + } else if ((second->mChildren.last()->type() == continuation) + && (first->mChildren.last()->type() == simple) + && exits.contains(first->mChildren.last()->id())) + { + first->addToTheEnd(second->mChildren.last()->clone()); + } + } + if (first->mChildren.last()->type() == continuation + && second->mChildren.last()->type() == continuation + && first->mChildren.last()->id() == second->mChildren.last()->id()) + { + result = true; + mChildren.insert(i + 1, first->mChildren.last()->clone()); + first->mChildren.pop_back(); + second->mChildren.pop_back(); + } + } else if (mChildren[i]->type() == switchCase) { + auto thisSwitch = static_cast(mChildren[i]); + QSet endContinuations; + int nonExitCount = 0; + for (auto &e : thisSwitch->branches()) { + if (static_cast(e)->mChildren.size() > 0 + && static_cast(e)->mChildren.last()->type() == continuation) { + endContinuations.insert(static_cast(e)->mChildren.last()->id()); + } + if (static_cast(e)->mChildren.size() > 0 + && static_cast(e)->mChildren.last()->type() == simple + && !exits.contains(static_cast(e)->mChildren.last()->id())) { + nonExitCount += 1; + } + if (static_cast(e)->mChildren.size() == 0) { + nonExitCount += 1; + } + } + if ((endContinuations.size() == 1) && (nonExitCount == 0)) { + result = true; + mChildren.insert(i + 1, new ContinuationStructurizerNode(*endContinuations.begin(), parent())); + thisSwitch->dropContinuations(*endContinuations.begin()); + } + } + } + return result; +} + +void SequenceStructurizerNode::transformDoWhile() +{ +} + +void SequenceStructurizerNode::dropEmptyConditionals() +{ + for (int j = 0; j < mChildren.size(); ++j) { + if (mChildren[j]->type() == ifThenElse && static_cast(mChildren[j])->isEmpty()) { + mChildren.erase(mChildren.begin() + j--); + } else if (mChildren[j]->type() == switchCase && static_cast(mChildren[j])->isEmpty()) { + mChildren.erase(mChildren.begin() + j--); + } else { + mChildren[j]->dropEmptyConditionals(); + } + } +} + +void SequenceStructurizerNode::replaceContinuation(const Vertex &id, StructurizerNode *value) +{ + for (int i = 0; i < mChildren.size(); ++i) { + if (mChildren[i]->type() == continuation && mChildren[i]->id() == id) { + mChildren.erase(mChildren.begin() + i--); + if (value->type() == sequence) { + for (StructurizerNode *e : static_cast(value)->mChildren) { + mChildren.insert(mChildren.begin() + ++i, e->clone()); + } + } else { + mChildren.insert(mChildren.begin() + ++i, value->clone()); + } + } else { + mChildren[i]->replaceContinuation(id, value); + } + } +} + +int SequenceStructurizerNode::numberOfConditionCalculating(const Vertex &id) const +{ + int count = 0; + for (StructurizerNode *e : mChildren) { + count += e->numberOfConditionCalculating(id); + } + return count; +} + +void SequenceStructurizerNode::transformBeforeDerecursivation() +{ + for (int i = 0; i < mChildren.size(); ++i) { + auto &e = mChildren[i]; + e->transformBeforeDerecursivation(); + if (e->type() == ifThenElse) { + auto first = static_cast(static_cast(e)->thenBranch()); + auto second = static_cast(static_cast(e)->elseBranch()); + if (first->mChildren.size() > 0 && second->mChildren.size() > 0) { + if (first->mChildren.last()->type() == continuation) { + for (int j = second->mChildren.size() - 1; j >= 0; --j) { + mChildren.insert(i + 1, second->mChildren[j]); + } + second->mChildren.clear(); + } else if (second->mChildren.last()->type() == continuation) { + for (int j = first->mChildren.size() - 1; j >= 0; --j) { + mChildren.insert(i + 1, first->mChildren[j]); + } + first->mChildren.clear(); + } + } + } + } +} diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/sequenceStructurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/sequenceStructurizerNode.h new file mode 100644 index 0000000000..cfad576691 --- /dev/null +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/sequenceStructurizerNode.h @@ -0,0 +1,44 @@ +#pragma once + +#include "structurizerNode.h" + +#include + +namespace generatorBase { + +class SequenceStructurizerNode : public StructurizerNode +{ + Q_OBJECT + +public: + explicit SequenceStructurizerNode(QObject *parent); + + Type type() const; + Vertex id() const; + + bool containsContinuation(const Vertex &id = Vertex()) const; + void dropContinuations(const Vertex &id); + int numberOfContinuation(const Vertex &id = Vertex()) const; + + void factorize(const Vertex &id, bool force = false); + void derecursivate(const Vertex &id); + void replaceContinuation(const Vertex &id, StructurizerNode *value); + + bool mergeConditionalBranches(const QSet &exits, const QSet &loopHeads); + void transformDoWhile(); + + ConditionTree *findAllContinuations(const Vertex &id) const; + bool isEqual(StructurizerNode *other) const; + StructurizerNode *clone() const; + int numberOfConditionCalculating(const Vertex &id) const; + void dropEmptyConditionals(); + + void addToTheEnd(StructurizerNode *); + QVector children(); + void transformBeforeDerecursivation(); + +protected: + QVector mChildren; + +}; +} diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/simpleStructurizerNode.cpp b/plugins/robots/generators/generatorBase/src/structurizerNodes/simpleStructurizerNode.cpp new file mode 100644 index 0000000000..c09426e026 --- /dev/null +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/simpleStructurizerNode.cpp @@ -0,0 +1,98 @@ +#include "simpleStructurizerNode.h" + +using namespace generatorBase; + +SimpleStructurizerNode::SimpleStructurizerNode(const Vertex &id, QObject *parent) + : StructurizerNode(parent) + , mId(id) +{ +} + +StructurizerNode::Type SimpleStructurizerNode::type() const +{ + return Type::simple; +} + +bool SimpleStructurizerNode::containsContinuation(const Vertex &id) const +{ + Q_UNUSED(id) + return false; +} + +int SimpleStructurizerNode::numberOfContinuation(const Vertex &id) const +{ + Q_UNUSED(id) + return 0; +} + +StructurizerNode *SimpleStructurizerNode::clone() const +{ + return new SimpleStructurizerNode(mId, parent()); +} + +StructurizerNode::Vertex SimpleStructurizerNode::id() const +{ + return mId; +} + +bool SimpleStructurizerNode::isEqual(StructurizerNode * other) const +{ + if (other->type() != simple) { + return false; + } + return mId == other->id(); +} + +void SimpleStructurizerNode::dropContinuations(const Vertex &id) +{ + Q_UNUSED(id) +} + +void SimpleStructurizerNode::factorize(const Vertex &id, bool force) +{ + Q_UNUSED(id) + Q_UNUSED(force) +} + +void SimpleStructurizerNode::derecursivate(const Vertex &id) +{ + Q_UNUSED(id) +} + +bool SimpleStructurizerNode::mergeConditionalBranches(const QSet &exits, const QSet &loopHeads) +{ + Q_UNUSED(exits) + Q_UNUSED(loopHeads) + return false; +} + +void SimpleStructurizerNode::transformDoWhile() +{ +} + +void SimpleStructurizerNode::dropEmptyConditionals() +{ +} + +StructurizerNode::ConditionTree *SimpleStructurizerNode::findAllContinuations(const Vertex &id) const +{ + Q_UNUSED(id) + return nullptr; +} + +void SimpleStructurizerNode::replaceContinuation(const Vertex &id, StructurizerNode *value) +{ + Q_UNUSED(id) + Q_UNUSED(value) +} + + +int SimpleStructurizerNode::numberOfConditionCalculating(const Vertex &id) const +{ + Q_UNUSED(id) + return 0; +} + +void SimpleStructurizerNode::transformBeforeDerecursivation() +{ +} diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/simpleStructurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/simpleStructurizerNode.h new file mode 100644 index 0000000000..33cc9494a3 --- /dev/null +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/simpleStructurizerNode.h @@ -0,0 +1,41 @@ +#pragma once + +#include "structurizerNode.h" + +#include + +namespace generatorBase { + +class SimpleStructurizerNode : public StructurizerNode +{ + Q_OBJECT + +public: + explicit SimpleStructurizerNode(const Vertex &id, QObject *parent); + + Vertex id() const; + Type type() const; + + bool containsContinuation(const Vertex &id = Vertex()) const; + void dropContinuations(const Vertex &id); + int numberOfContinuation(const Vertex &id = Vertex()) const; + + void factorize(const Vertex &id, bool force = false); + void derecursivate(const Vertex &id); + void replaceContinuation(const Vertex &id, StructurizerNode *value); + + bool mergeConditionalBranches(const QSet &exits, const QSet &loopHeads); + void transformDoWhile(); + + ConditionTree *findAllContinuations(const Vertex &id) const; + bool isEqual(StructurizerNode *other) const; + StructurizerNode *clone() const; + int numberOfConditionCalculating(const Vertex &id) const; + void dropEmptyConditionals(); + void transformBeforeDerecursivation(); + +protected: + const Vertex mId; + +}; +} diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/structurizerNode.cpp b/plugins/robots/generators/generatorBase/src/structurizerNodes/structurizerNode.cpp new file mode 100644 index 0000000000..ba14b267b2 --- /dev/null +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/structurizerNode.cpp @@ -0,0 +1,182 @@ +#include "structurizerNode.h" + +using namespace generatorBase; + +StructurizerNode::StructurizerNode(QObject *parent) + : QObject(parent) +{ +} + +StructurizerNode::~StructurizerNode() +{ +} + +StructurizerNode::ConditionTree::ConditionTree(const QPair &idPair) + : mInverted(false), mIsOperator(false),mIsValue(true), mValue(idPair), mLeft(nullptr), mRight(nullptr) +{} + +StructurizerNode::ConditionTree::ConditionTree(Operator o, ConditionTree *left, ConditionTree *right) + : mInverted(false), mIsOperator(true), mIsValue(false), mOperator(o), mLeft(left), mRight(right) +{} + +void StructurizerNode::ConditionTree::invert() +{ + mInverted = true; +} + +bool StructurizerNode::ConditionTree::isValue() const +{ + return mIsValue; +} + +bool StructurizerNode::ConditionTree::isBoolOperator() const +{ + return mIsOperator; +} + +bool StructurizerNode::ConditionTree::isInverted() const +{ + return mInverted; +} + +bool StructurizerNode::ConditionTree::isEqual(const ConditionTree *x) const +{ + if (x == nullptr) { + return false; + } + if ((mInverted != x->mInverted) || (mIsOperator != x->mIsOperator) || (mIsValue != x->mIsValue)) { + return false; + } + if ((mIsOperator && !(mOperator == x->mOperator)) || (mIsValue && !(mValue == x->mValue))) { + return false; + } + if ((mLeft != nullptr) xor (x->mLeft != nullptr)) + return false; + if ((mLeft != nullptr) && !mLeft->isEqual(x->mLeft)) + return false; + if ((mRight != nullptr) xor (x->mRight != nullptr)) + return false; + if ((mRight != nullptr) && !mRight->isEqual(x->mRight)) + return false; + return true; +} + +bool StructurizerNode::ConditionTree::isNegativeTo(const ConditionTree *x) const +{ + if (x == nullptr) { + return false; + } + if (mInverted == x->mInverted) { + return false; + } + if ((mLeft == nullptr && x->mLeft != nullptr) || (mLeft != nullptr && !mLeft->isEqual(x->mLeft))) { + return false; + } + if ((mRight == nullptr && x->mRight != nullptr) || (mRight != nullptr && !mRight->isEqual(x->mRight))) { + return false; + } + return true; +} + +StructurizerNode::ConditionTree *StructurizerNode::ConditionTree::clone() const +{ + ConditionTree *a = nullptr; + if (mIsOperator) { + a = new ConditionTree(mOperator + , (mLeft != nullptr) ? mLeft->clone() : nullptr + , (mRight != nullptr) ? mRight->clone() : nullptr); + } else { + a = new ConditionTree(mValue); + } + a->mInverted = mInverted; + return a; +} + +QPair StructurizerNode::ConditionTree::value() const +{ + return mValue; +} + +StructurizerNode::ConditionTree::Operator StructurizerNode::ConditionTree::boolOperator() const +{ + return mOperator; +} + +StructurizerNode::ConditionTree *StructurizerNode::ConditionTree::left() +{ + return mLeft; +} + +StructurizerNode::ConditionTree *StructurizerNode::ConditionTree::right() +{ + return mRight; +} + + +StructurizerNode::ConditionTree::~ConditionTree() +{ + delete mLeft; + delete mRight; +} + +int StructurizerNode::ConditionTree::numberOfFirstVertex(const Vertex &id) const +{ + if (mIsValue) { + return (mValue.first == id) ? 1 : 0; + } + if (mIsOperator) { + return mLeft->numberOfFirstVertex(id) + mRight->numberOfFirstVertex(id); + } + return false; +} + +bool StructurizerNode::ConditionTree::isTrue() const +{ + QSet> allValues; + findAllValues(allValues); + QVector> listValues; + QMap, bool> boolMapValues; + for (auto &v : allValues) { + listValues.append(v); + } + QVector binSubset = QVector(listValues.size() + 1, 0); + while (binSubset[0] == 0) { + for (int i = 0; i < listValues.size(); ++i) { + boolMapValues[listValues[i]] = binSubset[i + 1]; + } + if (!calculateValue(boolMapValues)) { + return false; + } + int i = binSubset.size() - 1; + while (binSubset[i] == 1) { + binSubset[i] = 0; + --i; + } + binSubset[i] = 1; + } + return true; +} + +void StructurizerNode::ConditionTree::findAllValues(QSet> &values) const +{ + if (mIsValue) { + values.insert(mValue); + return; + } + mRight->findAllValues(values); + mLeft->findAllValues(values); +} + +bool StructurizerNode::ConditionTree::calculateValue(const QMap, bool> &values) const +{ + if (mIsValue) { + return mInverted ? !values[mValue] : values[mValue]; + } + + bool right = mRight->calculateValue(values); + bool left = mLeft->calculateValue(values); + + bool result = (mOperator == OR) ? (right || left) : (right && left); + + return mInverted ? !result : result; +} diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/structurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/structurizerNode.h new file mode 100644 index 0000000000..57a3468223 --- /dev/null +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/structurizerNode.h @@ -0,0 +1,87 @@ +#pragma once + +#include + +namespace generatorBase { + +class StructurizerNode : public QObject +{ + Q_OBJECT + +public: + + enum Type { + simple + , continuation + , loop + , ifThenElse + , switchCase + , sequence + , breakFromLoop + }; + + typedef qReal::Id Vertex; + + class ConditionTree { + public: + enum Operator {OR, AND}; + + ConditionTree(const QPair &idPair); + ConditionTree(Operator o, ConditionTree *left, ConditionTree *right); + void invert(); + bool isValue() const; + bool isBoolOperator() const; + bool isInverted() const; + QPair value() const; + Operator boolOperator() const; + ConditionTree *left(); + ConditionTree *right(); + bool isEqual(const ConditionTree *x) const; + bool isNegativeTo(const ConditionTree *x) const; + bool isTrue() const; + ConditionTree *clone() const; + + int numberOfFirstVertex(const Vertex &id) const; + ~ConditionTree(); + private: + bool calculateValue(const QMap, bool> &values) const; + void findAllValues(QSet> &values) const; + + bool mInverted; + const bool mIsOperator; + const bool mIsValue; + QPair mValue; + Operator mOperator; + ConditionTree *mLeft; + ConditionTree *mRight; + }; + + explicit StructurizerNode(QObject *parent); + ~StructurizerNode(); + + virtual Type type() const = 0; + virtual Vertex id() const = 0; + + virtual bool containsContinuation(const Vertex &id = Vertex()) const = 0; + virtual void dropContinuations(const Vertex &id) = 0; + virtual int numberOfContinuation(const Vertex &id = Vertex()) const = 0; + + virtual void factorize(const Vertex &id, bool force = false) = 0; + virtual void derecursivate(const Vertex &id) = 0; + virtual void replaceContinuation(const Vertex &id, StructurizerNode *value) = 0; + + virtual bool mergeConditionalBranches(const QSet &exits, const QSet &loopHeads) = 0; + + virtual void transformDoWhile() = 0; + virtual ConditionTree *findAllContinuations(const Vertex &id) const = 0; + virtual bool isEqual(StructurizerNode *other) const = 0; + virtual StructurizerNode *clone() const = 0; + virtual int numberOfConditionCalculating(const Vertex &id) const = 0; + + virtual void dropEmptyConditionals() = 0; + virtual void transformBeforeDerecursivation() = 0; + +protected: + +}; +} diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.cpp b/plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.cpp new file mode 100644 index 0000000000..d1084267f9 --- /dev/null +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.cpp @@ -0,0 +1,228 @@ +#include "switchStructurizerNode.h" +#include "simpleStructurizerNode.h" +#include "continuationStructurizerNode.h" +#include "sequenceStructurizerNode.h" + +using namespace generatorBase; + +StructurizerNode::Type SwitchStructurizerNode::type() const +{ + return Type::switchCase; +} + +bool SwitchStructurizerNode::isEmpty() const +{ + for (auto *t : mBranches) { + if (static_cast(t)->children().size() > 0) { + return false; + } + } + if (static_cast(mDefaultBranch.second)->children().size() > 0) { + return false; + } + return true; +} + +bool SwitchStructurizerNode::containsContinuation(const Vertex &id) const +{ + for (auto *t : mBranches) { + if (t->containsContinuation(id)) { + return true; + } + } + if (mDefaultBranch.second->containsContinuation(id)) { + return true; + } + return false; +} + +int SwitchStructurizerNode::numberOfContinuation(const Vertex &id) const +{ + int count = 0; + for (auto *t : mBranches) { + count += t->numberOfContinuation(id); + } + count += mDefaultBranch.second->numberOfContinuation(id); + return count; +} + +SwitchStructurizerNode::SwitchStructurizerNode(const Vertex &id, const QVector &branches, QObject *parent) + : StructurizerNode(parent) + , mId(id) +{ + auto defaultBranch = new SequenceStructurizerNode(parent); + defaultBranch->addToTheEnd(new ContinuationStructurizerNode(branches.last(), parent)); + mDefaultBranch = qMakePair(branches.last(), defaultBranch); + for (int i = 0; i < branches.size() - 1; ++i) { + auto branch = new SequenceStructurizerNode(parent); + branch->addToTheEnd(new ContinuationStructurizerNode(branches[i], parent)); + mBranches[branches[i]] = branch; + } +} + +StructurizerNode *SwitchStructurizerNode::clone() const +{ + QVector branches; + for (const Vertex &e : mBranches.keys()) { + branches.append(e); + } + branches.append(mDefaultBranch.first); + SwitchStructurizerNode *newSwitch = new SwitchStructurizerNode(mId, branches, parent()); + + for (const Vertex &e : mBranches.keys()) { + newSwitch->mBranches[e] = mBranches[e]->clone(); + } + newSwitch->mDefaultBranch.second = mDefaultBranch.second->clone(); + return newSwitch; +} + +StructurizerNode::Vertex SwitchStructurizerNode::id() const +{ + return mId; +} + + +QMap SwitchStructurizerNode::branches() const +{ + return mBranches; +} + +void SwitchStructurizerNode::dropContinuations(const Vertex &id) +{ + for (auto *&t : mBranches) { + t->dropContinuations(id); + } + mDefaultBranch.second->dropContinuations(id); +} + +bool SwitchStructurizerNode::isEqual(StructurizerNode *other) const +{ + if (other->type() != switchCase) { + return false; + } + if (mId != other->id()) { + return false; + } + for (const Vertex &e : mBranches.keys()) { + if (!static_cast(other)->mBranches.keys().contains(e) + || !static_cast(other)->mBranches[e]->isEqual(mBranches[e])) + { + return false; + } + } + if (static_cast(other)->mDefaultBranch.first != mDefaultBranch.first + || !static_cast(other)->mBranches[mDefaultBranch.first]->isEqual(mBranches[mDefaultBranch.first])) + { + return false; + } + return true; +} + +StructurizerNode::ConditionTree *SwitchStructurizerNode::findAllContinuations(const Vertex &id) const +{ + ConditionTree *tree = nullptr; + for (const Vertex &e : mBranches.keys()) { + if (mBranches[e]->containsContinuation(id)) { + ConditionTree *branchCondition = new ConditionTree(qMakePair(mId, e)); + ConditionTree *newCase = mBranches[e]->findAllContinuations(id); + if (newCase == nullptr) { + newCase = branchCondition; + } else { + newCase = new ConditionTree(ConditionTree::AND, branchCondition, newCase); + } + if (tree == nullptr) { + tree = newCase; + } else { + tree = new ConditionTree(ConditionTree::OR, tree, newCase); + } + } + } + if (mDefaultBranch.second->containsContinuation(id)) { + ConditionTree *branchCondition = nullptr; + for (const Vertex &e : mBranches.keys()) { + if (branchCondition == nullptr) { + branchCondition = new ConditionTree(qMakePair(mId, e)); + } else { + branchCondition = new ConditionTree(ConditionTree::OR, branchCondition, new ConditionTree(qMakePair(mId, e))); + } + } + if (branchCondition != nullptr) { + branchCondition->invert(); + + ConditionTree *newCase = mDefaultBranch.second->findAllContinuations(id); + if (newCase == nullptr) { + newCase = branchCondition; + } else { + newCase = new ConditionTree(ConditionTree::AND, branchCondition, newCase); + } + if (tree == nullptr) { + tree = newCase; + } else { + tree = new ConditionTree(ConditionTree::OR, tree, newCase); + } + } + } + if (tree == nullptr || tree->isTrue()) { + delete tree; + return nullptr; + } + return tree; +} + +void SwitchStructurizerNode::factorize(const Vertex &id, bool force) +{ + Q_UNUSED(id) + Q_UNUSED(force) +} + +void SwitchStructurizerNode::derecursivate(const Vertex &id) +{ + Q_UNUSED(id) +} + +bool SwitchStructurizerNode::mergeConditionalBranches(const QSet &exits, const QSet &loopHeads) +{ + for (auto *&t : mBranches) { + if (t->mergeConditionalBranches(exits, loopHeads)) { + return true; + } + } + if (mDefaultBranch.second->mergeConditionalBranches(exits, loopHeads)) { + return true; + } + return false; +} + +void SwitchStructurizerNode::transformDoWhile() +{ +} + +void SwitchStructurizerNode::dropEmptyConditionals() +{ + for (auto *&t : mBranches) { + t->dropEmptyConditionals(); + } + mDefaultBranch.second->dropEmptyConditionals(); +} + +void SwitchStructurizerNode::replaceContinuation(const Vertex &id, StructurizerNode *value) +{ + for (auto *&t : mBranches) { + t->replaceContinuation(id, value); + } + mDefaultBranch.second->replaceContinuation(id, value); +} + +int SwitchStructurizerNode::numberOfConditionCalculating(const Vertex &id) const +{ + int count = mId == id ? 1 : 0; + for (auto *t : mBranches) { + count += t->numberOfConditionCalculating(id); + } + count += mDefaultBranch.second->numberOfConditionCalculating(id); + return count; +} + +void SwitchStructurizerNode::transformBeforeDerecursivation() +{ +} diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.h new file mode 100644 index 0000000000..c0e1a2b7ce --- /dev/null +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.h @@ -0,0 +1,52 @@ +#pragma once + +#include "structurizerNode.h" + +#include + +namespace generatorBase { + +class SwitchStructurizerNode : public StructurizerNode +{ + Q_OBJECT + +public: + explicit SwitchStructurizerNode(const Vertex &id, const QVector &branches, QObject *parent); + + //explicit SwitchStructurizerNode(const Vertex &id, QObject *parent); + + Type type() const; + Vertex id() const; + QMap branches() const; + QPair defaultBranch() const; + + bool containsContinuation(const Vertex &id = Vertex()) const; + void dropContinuations(const Vertex &id); + int numberOfContinuation(const Vertex &id = Vertex()) const; + + void factorize(const Vertex &id, bool force = false); + void derecursivate(const Vertex &id); + void replaceContinuation(const Vertex &id, StructurizerNode *value); + + bool mergeConditionalBranches(const QSet &exits, const QSet &loopHeads); + void transformDoWhile(); + + ConditionTree *findAllContinuations(const Vertex &id) const; + bool isEqual(StructurizerNode *other) const; + StructurizerNode *clone() const; + int numberOfConditionCalculating(const Vertex &id) const; + + void dropEmptyConditionals(); + + bool isEmpty() const; + void transformBeforeDerecursivation(); + +protected: + + const Vertex mId; + QMap mBranches; + QPair mDefaultBranch; + +}; + +} diff --git a/plugins/robots/generators/nxt/nxtGeneratorBase/include/nxtGeneratorBase/nxtGeneratorFactory.h b/plugins/robots/generators/nxt/nxtGeneratorBase/include/nxtGeneratorBase/nxtGeneratorFactory.h index b75c17f0b9..8b7c649102 100644 --- a/plugins/robots/generators/nxt/nxtGeneratorBase/include/nxtGeneratorBase/nxtGeneratorFactory.h +++ b/plugins/robots/generators/nxt/nxtGeneratorBase/include/nxtGeneratorBase/nxtGeneratorFactory.h @@ -28,6 +28,7 @@ class ROBOTS_NXT_GENERATOR_BASE_EXPORT NxtGeneratorFactory : public generatorBas , qReal::ErrorReporterInterface &errorReporter , const kitBase::robotModel::RobotModelManagerInterface &robotModelManager , generatorBase::lua::LuaProcessor &luaProcessor + , generatorBase::ReadableLabelManager &readableLabelManager , const QString &generatorName); ~NxtGeneratorFactory() override; diff --git a/plugins/robots/generators/nxt/nxtGeneratorBase/src/nxtGeneratorCustomizer.cpp b/plugins/robots/generators/nxt/nxtGeneratorBase/src/nxtGeneratorCustomizer.cpp index d47f29daef..780ea6fd6e 100644 --- a/plugins/robots/generators/nxt/nxtGeneratorBase/src/nxtGeneratorCustomizer.cpp +++ b/plugins/robots/generators/nxt/nxtGeneratorBase/src/nxtGeneratorCustomizer.cpp @@ -20,9 +20,10 @@ NxtGeneratorCustomizer::NxtGeneratorCustomizer(const qrRepo::RepoApi &repo , qReal::ErrorReporterInterface &errorReporter , const kitBase::robotModel::RobotModelManagerInterface &robotModelManager , generatorBase::lua::LuaProcessor &luaProcessor + , generatorBase::ReadableLabelManager &readableLabelManager , const QString &generatorName , bool supportsSwitchUnstableToBreaks) - : mFactory(repo, errorReporter, robotModelManager, luaProcessor, generatorName) + : mFactory(repo, errorReporter, robotModelManager, luaProcessor, readableLabelManager, generatorName) , mSupportsSwitchUnstableToBreaks(supportsSwitchUnstableToBreaks) { } diff --git a/plugins/robots/generators/nxt/nxtGeneratorBase/src/nxtGeneratorCustomizer.h b/plugins/robots/generators/nxt/nxtGeneratorBase/src/nxtGeneratorCustomizer.h index e63547aee5..0a4cc95cff 100644 --- a/plugins/robots/generators/nxt/nxtGeneratorBase/src/nxtGeneratorCustomizer.h +++ b/plugins/robots/generators/nxt/nxtGeneratorBase/src/nxtGeneratorCustomizer.h @@ -27,6 +27,7 @@ class NxtGeneratorCustomizer : public generatorBase::GeneratorCustomizer , qReal::ErrorReporterInterface &errorReporter , const kitBase::robotModel::RobotModelManagerInterface &robotModelManager , generatorBase::lua::LuaProcessor &luaProcessor + , generatorBase::ReadableLabelManager &readableLabelManager , const QString &generatorName , bool supportsSwitchUnstableToBreaks); diff --git a/plugins/robots/generators/nxt/nxtGeneratorBase/src/nxtGeneratorFactory.cpp b/plugins/robots/generators/nxt/nxtGeneratorBase/src/nxtGeneratorFactory.cpp index 6bb2f3f87a..157bf61ec8 100644 --- a/plugins/robots/generators/nxt/nxtGeneratorBase/src/nxtGeneratorFactory.cpp +++ b/plugins/robots/generators/nxt/nxtGeneratorBase/src/nxtGeneratorFactory.cpp @@ -32,8 +32,9 @@ NxtGeneratorFactory::NxtGeneratorFactory(const qrRepo::RepoApi &repo , qReal::ErrorReporterInterface &errorReporter , const kitBase::robotModel::RobotModelManagerInterface &robotModelManager , generatorBase::lua::LuaProcessor &luaProcessor + , generatorBase::ReadableLabelManager &readableLabelManager , const QString &generatorName) - : GeneratorFactoryBase(repo, errorReporter, robotModelManager, luaProcessor) + : GeneratorFactoryBase(repo, errorReporter, robotModelManager, luaProcessor, readableLabelManager) , mGeneratorName(generatorName) , mImages(pathsToTemplates()) { diff --git a/plugins/robots/generators/nxt/nxtGeneratorBase/src/nxtMasterGeneratorBase.cpp b/plugins/robots/generators/nxt/nxtGeneratorBase/src/nxtMasterGeneratorBase.cpp index d4e89ae6ab..3442e44659 100644 --- a/plugins/robots/generators/nxt/nxtGeneratorBase/src/nxtMasterGeneratorBase.cpp +++ b/plugins/robots/generators/nxt/nxtGeneratorBase/src/nxtMasterGeneratorBase.cpp @@ -34,7 +34,7 @@ NxtMasterGeneratorBase::NxtMasterGeneratorBase(const qrRepo::RepoApi &repo generatorBase::GeneratorCustomizer *NxtMasterGeneratorBase::createCustomizer() { return new NxtGeneratorCustomizer(mRepo, mErrorReporter, mRobotModelManager, *createLuaProcessor() - , mGeneratorName, supportsSwitchUnstableToBreaks()); + , *mReadableLabelManager , mGeneratorName, supportsSwitchUnstableToBreaks()); } void NxtMasterGeneratorBase::beforeGeneration() diff --git a/plugins/robots/generators/pioneer/pioneerLuaGenerator/pioneerLuaGenerator.pro b/plugins/robots/generators/pioneer/pioneerLuaGenerator/pioneerLuaGenerator.pro index 7a46e3fe6a..1e67e6c042 100644 --- a/plugins/robots/generators/pioneer/pioneerLuaGenerator/pioneerLuaGenerator.pro +++ b/plugins/robots/generators/pioneer/pioneerLuaGenerator/pioneerLuaGenerator.pro @@ -44,7 +44,6 @@ HEADERS += \ $$PWD/communicator/communicatorInterface.h \ $$PWD/communicator/communicationManager.h \ $$PWD/communicator/httpCommunicator.h \ - $$PWD/generators/gotoLabelManager.h \ $$PWD/generators/pioneerStateMachineGenerator.h \ $$PWD/generators/randomFunctionChecker.h \ $$PWD/generators/semanticTreeManager.h \ @@ -78,7 +77,6 @@ SOURCES += \ $$PWD/pioneerLuaMasterGenerator.cpp \ $$PWD/communicator/communicationManager.cpp \ $$PWD/communicator/httpCommunicator.cpp \ - $$PWD/generators/gotoLabelManager.cpp \ $$PWD/generators/pioneerStateMachineGenerator.cpp \ $$PWD/generators/randomFunctionChecker.cpp \ $$PWD/generators/semanticTreeManager.cpp \ diff --git a/plugins/robots/generators/pioneer/pioneerLuaGenerator/pioneerLuaGeneratorCustomizer.cpp b/plugins/robots/generators/pioneer/pioneerLuaGenerator/pioneerLuaGeneratorCustomizer.cpp index ba46327adf..8721ce6b9c 100644 --- a/plugins/robots/generators/pioneer/pioneerLuaGenerator/pioneerLuaGeneratorCustomizer.cpp +++ b/plugins/robots/generators/pioneer/pioneerLuaGenerator/pioneerLuaGeneratorCustomizer.cpp @@ -22,8 +22,8 @@ PioneerLuaGeneratorCustomizer::PioneerLuaGeneratorCustomizer(const qrRepo::RepoA , qReal::ErrorReporterInterface &errorReporter , const kitBase::robotModel::RobotModelManagerInterface &robotModelManager , generatorBase::lua::LuaProcessor &luaProcessor + , generatorBase::ReadableLabelManager &readableLabelManager , const QString &generatorName - , GotoLabelManager &gotoLabelManager , bool supportsSwitchUnstableToBreaks) : mFactory( new PioneerLuaGeneratorFactory( @@ -31,8 +31,8 @@ PioneerLuaGeneratorCustomizer::PioneerLuaGeneratorCustomizer(const qrRepo::RepoA , errorReporter , robotModelManager , luaProcessor + , readableLabelManager , generatorName - , gotoLabelManager )) , mSupportsSwitchUnstableToBreaks(supportsSwitchUnstableToBreaks) { diff --git a/plugins/robots/generators/pioneer/pioneerLuaGenerator/pioneerLuaGeneratorCustomizer.h b/plugins/robots/generators/pioneer/pioneerLuaGenerator/pioneerLuaGeneratorCustomizer.h index c10ceebb95..b2b80275a0 100644 --- a/plugins/robots/generators/pioneer/pioneerLuaGenerator/pioneerLuaGeneratorCustomizer.h +++ b/plugins/robots/generators/pioneer/pioneerLuaGenerator/pioneerLuaGeneratorCustomizer.h @@ -22,7 +22,6 @@ namespace pioneer { namespace lua { class PioneerLuaGeneratorFactory; -class GotoLabelManager; /// Customizer for Pioneer generator. Provides factory that can create simple generators for blocks. class PioneerLuaGeneratorCustomizer : public generatorBase::GeneratorCustomizer @@ -32,8 +31,8 @@ class PioneerLuaGeneratorCustomizer : public generatorBase::GeneratorCustomizer , qReal::ErrorReporterInterface &errorReporter , const kitBase::robotModel::RobotModelManagerInterface &robotModelManager , generatorBase::lua::LuaProcessor &luaProcessor + , generatorBase::ReadableLabelManager &readableLabelManager , const QString &generatorName - , GotoLabelManager &gotoLabelManager , bool supportsSwitchUnstableToBreaks); generatorBase::GeneratorFactoryBase *factory() override; diff --git a/plugins/robots/generators/pioneer/pioneerLuaGenerator/pioneerLuaGeneratorFactory.cpp b/plugins/robots/generators/pioneer/pioneerLuaGenerator/pioneerLuaGeneratorFactory.cpp index b2a29135af..4b364e3152 100644 --- a/plugins/robots/generators/pioneer/pioneerLuaGenerator/pioneerLuaGeneratorFactory.cpp +++ b/plugins/robots/generators/pioneer/pioneerLuaGenerator/pioneerLuaGeneratorFactory.cpp @@ -20,7 +20,7 @@ #include "parts/tofPart.h" #include "parts/magnetPart.h" #include "parts/randomGeneratorPart.h" -#include "generators/gotoLabelManager.h" +#include "src/readableLabelManager.h" #include "simpleGenerators/endOfHandlerGenerator.h" #include "simpleGenerators/geoLandingGenerator.h" #include "simpleGenerators/geoTakeoffGenerator.h" @@ -45,11 +45,10 @@ PioneerLuaGeneratorFactory::PioneerLuaGeneratorFactory(const qrRepo::RepoApi &re , qReal::ErrorReporterInterface &errorReporter , const kitBase::robotModel::RobotModelManagerInterface &robotModelManager , generatorBase::lua::LuaProcessor &luaProcessor - , const QString &generatorName - , GotoLabelManager &gotoLabelManager) - : GeneratorFactoryBase(repo, errorReporter, robotModelManager, luaProcessor) + , generatorBase::ReadableLabelManager &readableLabelManager + , const QString &generatorName) + : GeneratorFactoryBase(repo, errorReporter, robotModelManager, luaProcessor, readableLabelManager) , mGeneratorName(generatorName) - , mGotoLabelManager(gotoLabelManager) { } @@ -132,13 +131,13 @@ RandomGeneratorPart& PioneerLuaGeneratorFactory::randomGeneratorPart() generatorBase::simple::AbstractSimpleGenerator *PioneerLuaGeneratorFactory::labelGenerator(const qReal::Id &id , generatorBase::GeneratorCustomizer &customizer) { - return new LabelGenerator(mRepo, customizer, id, this, mGotoLabelManager); + return new LabelGenerator(mRepo, customizer, id, this, mReadableLabelManager); } generatorBase::simple::AbstractSimpleGenerator *PioneerLuaGeneratorFactory::gotoSimpleGenerator(const qReal::Id &id , generatorBase::GeneratorCustomizer &customizer) { - return new GotoGenerator(mRepo, customizer, id, this, mGotoLabelManager); + return new GotoGenerator(mRepo, customizer, id, this, mReadableLabelManager); } QList PioneerLuaGeneratorFactory::initTerminateGenerators() diff --git a/plugins/robots/generators/pioneer/pioneerLuaGenerator/pioneerLuaGeneratorFactory.h b/plugins/robots/generators/pioneer/pioneerLuaGenerator/pioneerLuaGeneratorFactory.h index 6760e543a6..923dc43edf 100644 --- a/plugins/robots/generators/pioneer/pioneerLuaGenerator/pioneerLuaGeneratorFactory.h +++ b/plugins/robots/generators/pioneer/pioneerLuaGenerator/pioneerLuaGeneratorFactory.h @@ -19,7 +19,6 @@ namespace pioneer { namespace lua { -class GotoLabelManager; class LedPart; class TofPart; class MagnetPart; @@ -33,8 +32,8 @@ class PioneerLuaGeneratorFactory : public generatorBase::GeneratorFactoryBase , qReal::ErrorReporterInterface &errorReporter , const kitBase::robotModel::RobotModelManagerInterface &robotModelManager , generatorBase::lua::LuaProcessor &luaProcessor - , const QString &generatorName - , GotoLabelManager &gotoLabelManager); + , generatorBase::ReadableLabelManager &readableLabelManager + , const QString &generatorName); ~PioneerLuaGeneratorFactory() override; @@ -72,10 +71,6 @@ class PioneerLuaGeneratorFactory : public generatorBase::GeneratorFactoryBase /// Generator name is used as a prefix to a path to templates in resources. const QString mGeneratorName; - /// Storage and generator for human-readable goto labels. Used in label ganerator and goto generator created by - /// this factory. - GotoLabelManager &mGotoLabelManager; - /// Generator part that tracks LED usage and initializes it if needed. QScopedPointer mLedPart; diff --git a/plugins/robots/generators/pioneer/pioneerLuaGenerator/pioneerLuaMasterGenerator.cpp b/plugins/robots/generators/pioneer/pioneerLuaGenerator/pioneerLuaMasterGenerator.cpp index 293bb0467b..abaa6f744b 100644 --- a/plugins/robots/generators/pioneer/pioneerLuaGenerator/pioneerLuaMasterGenerator.cpp +++ b/plugins/robots/generators/pioneer/pioneerLuaGenerator/pioneerLuaMasterGenerator.cpp @@ -29,7 +29,6 @@ #include "pioneerLuaGeneratorCustomizer.h" #include "pioneerLuaGeneratorFactory.h" #include "generators/pioneerStateMachineGenerator.h" -#include "generators/gotoLabelManager.h" #include "generators/randomFunctionChecker.h" using namespace pioneer::lua; @@ -48,7 +47,6 @@ PioneerLuaMasterGenerator::PioneerLuaMasterGenerator(const qrRepo::RepoApi &repo : MasterGeneratorBase(repo, errorReporter, robotModelManager, textLanguage, parserErrorReporter, diagramId) , mGeneratorName(generatorName) , mMetamodel(metamodel) - , mGotoLabelManager(new GotoLabelManager()) { } @@ -82,8 +80,8 @@ generatorBase::GeneratorCustomizer *PioneerLuaMasterGenerator::createCustomizer( , mErrorReporter , mRobotModelManager , *createLuaProcessor() + , *mReadableLabelManager , mGeneratorName - , *mGotoLabelManager , supportsSwitchUnstableToBreaks()); } @@ -114,7 +112,7 @@ QString PioneerLuaMasterGenerator::generate(const QString &indentString) QLOG_INFO() << "Starting Pioneer program generation to " << mProjectDir; - mGotoLabelManager->reinit(); + mReadableLabelManager->reinit(); beforeGeneration(); diff --git a/plugins/robots/generators/pioneer/pioneerLuaGenerator/pioneerLuaMasterGenerator.h b/plugins/robots/generators/pioneer/pioneerLuaGenerator/pioneerLuaMasterGenerator.h index cf64ad7d9e..2445e56233 100644 --- a/plugins/robots/generators/pioneer/pioneerLuaGenerator/pioneerLuaMasterGenerator.h +++ b/plugins/robots/generators/pioneer/pioneerLuaGenerator/pioneerLuaMasterGenerator.h @@ -15,6 +15,7 @@ #pragma once #include +#include "src/readableLabelManager.h" #include @@ -26,7 +27,6 @@ namespace pioneer { namespace lua { class PioneerStateMachineGenerator; -class GotoLabelManager; class RandomFunctionChecker; /// Main generator that directs generation process (mainly by configuring its base class that does actual job). @@ -66,9 +66,6 @@ class PioneerLuaMasterGenerator : public generatorBase::MasterGeneratorBase /// for a node. const qReal::EditorManagerInterface &mMetamodel; - /// Storage and generator for human-readable goto labels. - QScopedPointer mGotoLabelManager; - /// Object that tracks "random()" function usage in Lua code of properties, to be able to properly initialize /// random number generator if needed. QScopedPointer mRandomFunctionChecker; diff --git a/plugins/robots/generators/pioneer/pioneerLuaGenerator/simpleGenerators/gotoGenerator.cpp b/plugins/robots/generators/pioneer/pioneerLuaGenerator/simpleGenerators/gotoGenerator.cpp index 8e40ec5b97..b77dce301f 100644 --- a/plugins/robots/generators/pioneer/pioneerLuaGenerator/simpleGenerators/gotoGenerator.cpp +++ b/plugins/robots/generators/pioneer/pioneerLuaGenerator/simpleGenerators/gotoGenerator.cpp @@ -17,8 +17,6 @@ #include #include -#include "generators/gotoLabelManager.h" - using namespace pioneer::lua; using namespace generatorBase::simple; @@ -26,9 +24,9 @@ GotoGenerator::GotoGenerator(const qrRepo::RepoApi &repo , generatorBase::GeneratorCustomizer &customizer , const qReal::Id &id , QObject *parent - , GotoLabelManager &gotoLabelManager) + , generatorBase::ReadableLabelManager &readableLabelManager) : BindingGenerator(repo, customizer, id, "goto.t" - , { Binding::createStaticConverting("@@ID@@", gotoLabelManager.labelFor(id) + , { Binding::createStaticConverting("@@ID@@", readableLabelManager.labelFor(id) , customizer.factory()->nameNormalizerConverter()) } , parent) { diff --git a/plugins/robots/generators/pioneer/pioneerLuaGenerator/simpleGenerators/gotoGenerator.h b/plugins/robots/generators/pioneer/pioneerLuaGenerator/simpleGenerators/gotoGenerator.h index d02ed46477..10589ee008 100644 --- a/plugins/robots/generators/pioneer/pioneerLuaGenerator/simpleGenerators/gotoGenerator.h +++ b/plugins/robots/generators/pioneer/pioneerLuaGenerator/simpleGenerators/gotoGenerator.h @@ -15,12 +15,11 @@ #pragma once #include +#include "src/readableLabelManager.h" namespace pioneer { namespace lua { -class GotoLabelManager; - /// Generates goto to a human-readable label. class GotoGenerator : public generatorBase::simple::BindingGenerator { @@ -29,7 +28,7 @@ class GotoGenerator : public generatorBase::simple::BindingGenerator , generatorBase::GeneratorCustomizer &customizer , const qReal::Id &id , QObject *parent - , GotoLabelManager &gotoLabelManager + , generatorBase::ReadableLabelManager &readableLabelManager ); }; diff --git a/plugins/robots/generators/pioneer/pioneerLuaGenerator/simpleGenerators/labelGenerator.cpp b/plugins/robots/generators/pioneer/pioneerLuaGenerator/simpleGenerators/labelGenerator.cpp index 838626bc86..94a61381b6 100644 --- a/plugins/robots/generators/pioneer/pioneerLuaGenerator/simpleGenerators/labelGenerator.cpp +++ b/plugins/robots/generators/pioneer/pioneerLuaGenerator/simpleGenerators/labelGenerator.cpp @@ -17,8 +17,6 @@ #include #include -#include "generators/gotoLabelManager.h" - using namespace pioneer::lua; using namespace generatorBase::simple; @@ -26,11 +24,11 @@ LabelGenerator::LabelGenerator(const qrRepo::RepoApi &repo , generatorBase::GeneratorCustomizer &customizer , const qReal::Id &id , QObject *parent - , GotoLabelManager &gotoLabelManager) + , generatorBase::ReadableLabelManager &readableLabelManager) : BindingGenerator(repo, customizer, id, "label.t" , { Binding::createStaticConverting( "@@ID@@" - , gotoLabelManager.labelFor(id) + , readableLabelManager.labelFor(id) , customizer.factory()->nameNormalizerConverter() ) } diff --git a/plugins/robots/generators/pioneer/pioneerLuaGenerator/simpleGenerators/labelGenerator.h b/plugins/robots/generators/pioneer/pioneerLuaGenerator/simpleGenerators/labelGenerator.h index fbcf4fb7f3..535ad23709 100644 --- a/plugins/robots/generators/pioneer/pioneerLuaGenerator/simpleGenerators/labelGenerator.h +++ b/plugins/robots/generators/pioneer/pioneerLuaGenerator/simpleGenerators/labelGenerator.h @@ -15,12 +15,11 @@ #pragma once #include +#include "src/readableLabelManager.h" namespace pioneer { namespace lua { -class GotoLabelManager; - /// Generates human-readable label for a node. class LabelGenerator : public generatorBase::simple::BindingGenerator { @@ -29,7 +28,7 @@ class LabelGenerator : public generatorBase::simple::BindingGenerator , generatorBase::GeneratorCustomizer &customizer , const qReal::Id &id , QObject *parent - , GotoLabelManager &gotoLabelManager); + , generatorBase::ReadableLabelManager &readableLabelManager); }; } diff --git a/plugins/robots/generators/trik/trikGeneratorBase/src/trikGeneratorCustomizer.cpp b/plugins/robots/generators/trik/trikGeneratorBase/src/trikGeneratorCustomizer.cpp index 5e11fe8e7b..7de66108d0 100644 --- a/plugins/robots/generators/trik/trikGeneratorBase/src/trikGeneratorCustomizer.cpp +++ b/plugins/robots/generators/trik/trikGeneratorBase/src/trikGeneratorCustomizer.cpp @@ -20,9 +20,10 @@ TrikGeneratorCustomizer::TrikGeneratorCustomizer(const qrRepo::RepoApi &repo , qReal::ErrorReporterInterface &errorReporter , const kitBase::robotModel::RobotModelManagerInterface &robotModelManager , generatorBase::lua::LuaProcessor &luaProcessor + , generatorBase::ReadableLabelManager &readableLabelManager , const QStringList &pathsToTemplates , bool supportsSwitchUnstableToBreaks) - : mFactory(repo, errorReporter, robotModelManager, luaProcessor, pathsToTemplates) + : mFactory(repo, errorReporter, robotModelManager, luaProcessor, readableLabelManager, pathsToTemplates) , mSupportsSwitchUnstableToBreaks(supportsSwitchUnstableToBreaks) { } diff --git a/plugins/robots/generators/trik/trikGeneratorBase/src/trikGeneratorCustomizer.h b/plugins/robots/generators/trik/trikGeneratorBase/src/trikGeneratorCustomizer.h index 94ee1cf40a..2df5767663 100644 --- a/plugins/robots/generators/trik/trikGeneratorBase/src/trikGeneratorCustomizer.h +++ b/plugins/robots/generators/trik/trikGeneratorBase/src/trikGeneratorCustomizer.h @@ -27,6 +27,7 @@ class TrikGeneratorCustomizer : public generatorBase::GeneratorCustomizer , qReal::ErrorReporterInterface &errorReporter , const kitBase::robotModel::RobotModelManagerInterface &robotModelManager , generatorBase::lua::LuaProcessor &luaProcessor + , generatorBase::ReadableLabelManager &readableLabelManager , const QStringList &pathsToTemplates , bool supportsSwitchUnstableToBreaks); diff --git a/plugins/robots/generators/trik/trikGeneratorBase/src/trikGeneratorFactory.cpp b/plugins/robots/generators/trik/trikGeneratorBase/src/trikGeneratorFactory.cpp index 713ee112c0..74b10e77ab 100644 --- a/plugins/robots/generators/trik/trikGeneratorBase/src/trikGeneratorFactory.cpp +++ b/plugins/robots/generators/trik/trikGeneratorBase/src/trikGeneratorFactory.cpp @@ -64,8 +64,9 @@ TrikGeneratorFactory::TrikGeneratorFactory(const qrRepo::RepoApi &repo , qReal::ErrorReporterInterface &errorReporter , const kitBase::robotModel::RobotModelManagerInterface &robotModelManager , lua::LuaProcessor &luaProcessor + , generatorBase::ReadableLabelManager &readableLabelManager , const QStringList &pathsToTemplates) - : GeneratorFactoryBase(repo, errorReporter, robotModelManager, luaProcessor) + : GeneratorFactoryBase(repo, errorReporter, robotModelManager, luaProcessor, readableLabelManager) , mPathsToTemplates(pathsToTemplates) { mDeviceVariables.reset(new trik::parts::TrikDeviceVariables()); diff --git a/plugins/robots/generators/trik/trikGeneratorBase/src/trikGeneratorFactory.h b/plugins/robots/generators/trik/trikGeneratorBase/src/trikGeneratorFactory.h index 4ca4149fb1..32c62cadd6 100644 --- a/plugins/robots/generators/trik/trikGeneratorBase/src/trikGeneratorFactory.h +++ b/plugins/robots/generators/trik/trikGeneratorBase/src/trikGeneratorFactory.h @@ -26,6 +26,7 @@ class TrikGeneratorFactory : public generatorBase::GeneratorFactoryBase , qReal::ErrorReporterInterface &errorReporter , const kitBase::robotModel::RobotModelManagerInterface &robotModelManager , generatorBase::lua::LuaProcessor &luaProcessor + , generatorBase::ReadableLabelManager &readableLabelManager , const QStringList &pathsToTemplates); ~TrikGeneratorFactory() override; diff --git a/plugins/robots/generators/trik/trikGeneratorBase/src/trikMasterGeneratorBase.cpp b/plugins/robots/generators/trik/trikGeneratorBase/src/trikMasterGeneratorBase.cpp index c1b1e4bf45..dcca8c49f5 100644 --- a/plugins/robots/generators/trik/trikGeneratorBase/src/trikMasterGeneratorBase.cpp +++ b/plugins/robots/generators/trik/trikGeneratorBase/src/trikMasterGeneratorBase.cpp @@ -32,5 +32,5 @@ TrikMasterGeneratorBase::TrikMasterGeneratorBase(const qrRepo::RepoApi &repo generatorBase::GeneratorCustomizer *TrikMasterGeneratorBase::createCustomizer() { return new TrikGeneratorCustomizer(mRepo, mErrorReporter - , mRobotModelManager, *createLuaProcessor(), mPathsToTemplates, supportsSwitchUnstableToBreaks()); + , mRobotModelManager, *createLuaProcessor(), *mReadableLabelManager, mPathsToTemplates, supportsSwitchUnstableToBreaks()); } From 9579062c8610efd8387beb92c6a666edf3e4d50f Mon Sep 17 00:00:00 2001 From: Anna Zinovyeva Date: Mon, 7 Jun 2021 10:36:13 +0300 Subject: [PATCH 03/12] remove empty lines --- .../generatorBase/src/readableLabelManager.h | 1 - .../simpleGenerators/syntheticIfGenerator.cpp | 1 - .../generatorBase/src/structurizer.h | 3 - .../structurizerNodes/breakStructurizerNode.h | 2 - .../continuationStructurizerNode.h | 3 - .../src/structurizerNodes/elementNode.cpp | 436 ------------------ .../src/structurizerNodes/elementNode.h | 49 -- .../structurizerNodes/ifStructurizerNode.h | 5 - .../structurizerNodes/loopStructurizerNode.h | 5 - .../sequenceStructurizerNode.h | 3 - .../simpleStructurizerNode.h | 3 - .../structurizerNodes/structurizerNode.cpp | 6 +- .../src/structurizerNodes/structurizerNode.h | 7 +- .../switchStructurizerNode.h | 7 - 14 files changed, 5 insertions(+), 526 deletions(-) delete mode 100644 plugins/robots/generators/generatorBase/src/structurizerNodes/elementNode.cpp delete mode 100644 plugins/robots/generators/generatorBase/src/structurizerNodes/elementNode.h diff --git a/plugins/robots/generators/generatorBase/src/readableLabelManager.h b/plugins/robots/generators/generatorBase/src/readableLabelManager.h index cb6265f9d6..b1b9e8f903 100644 --- a/plugins/robots/generators/generatorBase/src/readableLabelManager.h +++ b/plugins/robots/generators/generatorBase/src/readableLabelManager.h @@ -37,7 +37,6 @@ class ReadableLabelManager QHash mNodeTypesCount; QHash mLabels; - }; } diff --git a/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticIfGenerator.cpp b/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticIfGenerator.cpp index 7ce2036ab4..0e2f04bad8 100644 --- a/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticIfGenerator.cpp +++ b/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticIfGenerator.cpp @@ -33,7 +33,6 @@ SyntheticIfGenerator::SyntheticIfGenerator(const qrRepo::RepoApi &repo , mNeedInverting(needInverting) , mNameManager(nameManager) { - } QString SyntheticIfGenerator::generate() diff --git a/plugins/robots/generators/generatorBase/src/structurizer.h b/plugins/robots/generators/generatorBase/src/structurizer.h index 9ac8da43b8..81d229d664 100644 --- a/plugins/robots/generators/generatorBase/src/structurizer.h +++ b/plugins/robots/generators/generatorBase/src/structurizer.h @@ -15,8 +15,6 @@ class LoopStructurizerNode; class Structurizer : public QObject { - Q_OBJECT - public: explicit Structurizer(QObject *parent = nullptr); @@ -41,5 +39,4 @@ class Structurizer : public QObject void reorderLoopHeads(QVector &v); }; - } diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/breakStructurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/breakStructurizerNode.h index a722ecfd60..833e863b38 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/breakStructurizerNode.h +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/breakStructurizerNode.h @@ -6,7 +6,6 @@ namespace generatorBase { class BreakStructurizerNode : public SimpleStructurizerNode { - public: explicit BreakStructurizerNode(QObject *parent = nullptr); @@ -14,6 +13,5 @@ class BreakStructurizerNode : public SimpleStructurizerNode bool isEqual(StructurizerNode *other) const; StructurizerNode *clone() const; - }; } diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/continuationStructurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/continuationStructurizerNode.h index 40d14df5e5..be6a45e123 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/continuationStructurizerNode.h +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/continuationStructurizerNode.h @@ -8,8 +8,6 @@ namespace generatorBase { class ContinuationStructurizerNode : public StructurizerNode { - Q_OBJECT - public: explicit ContinuationStructurizerNode(const Vertex &id, QObject *parent); @@ -37,6 +35,5 @@ class ContinuationStructurizerNode : public StructurizerNode protected: const Vertex mId; - }; } diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/elementNode.cpp b/plugins/robots/generators/generatorBase/src/structurizerNodes/elementNode.cpp deleted file mode 100644 index 1ec2b004f4..0000000000 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/elementNode.cpp +++ /dev/null @@ -1,436 +0,0 @@ -#include "structurizerNode.h" - -using namespace generatorBase; - -StructurizerNode::StructurizerNode(QObject *parent) - : QObject(parent) -{ -} - -SimpleStructurizerNode::SimpleStructurizerNode(const qReal::Id &id, QObject *parent) - : StructurizerNode(parent) - , mId(id) -{ -} - -ContinuationStructurizerNode::ContinuationStructurizerNode(const qReal::Id &id, QObject *parent) - : StructurizerNode(parent) - , mId(id) -{ -} - -StructurizerNode::Type SimpleStructurizerNode::type() const -{ - return Type::simple; -} - -StructurizerNode::Type ContinuationStructurizerNode::type() const -{ - return Type::continuation; -} - -StructurizerNode::Type IfStructurizerNode::type() const -{ - return Type::ifThenElse; -} - -StructurizerNode::Type LoopStructurizerNode::type() const -{ - return Type::loop; -} - -bool SimpleStructurizerNode::containsContinuation(const Vertex &id) { - Q_UNUSED(id) - return false; -} - -bool ContinuationStructurizerNode::containsContinuation(const Vertex &id) { - if (id == qReal::Id()) { - return true; - } - return id == mId; -} - -bool IfStructurizerNode::containsContinuation(const Vertex &id) { - for (auto e : *mThenBranch) { - if (e->containsContinuation(id)) { - return true; - } - } - for (auto e : *mElseBranch) { - if (e->containsContinuation(id)) { - return true; - } - } - return false; -} - -bool LoopStructurizerNode::containsContinuation(const Vertex &id) { - for (auto e : *mBody) { - if (e->containsContinuation(id)) { - return true; - } - } - return false; -} - -bool SimpleStructurizerNode::containsNonContinuation() { - return true; -} - -bool ContinuationStructurizerNode::containsNonContinuation() { - return false; -} - -bool IfStructurizerNode::containsNonContinuation() { - for (auto e : *mThenBranch) { - if (e->containsNonContinuation()) { - return true; - } - } - for (auto e : *mElseBranch) { - if (e->containsNonContinuation()) { - return true; - } - } - return false; -} - -bool LoopStructurizerNode::containsNonContinuation() { - for (auto e : *mBody) { - if (e->containsNonContinuation()) { - return true; - } - } - return false; -} - -IfStructurizerNode::IfStructurizerNode(const Vertex &id, const Vertex &firstId, const Vertex &secondId, QObject *parent) - : StructurizerNode(parent) -{ - mThenBranch = new QVector(); - mThenBranch->append(new ContinuationStructurizerNode(firstId, parent)); - - mElseBranch = new QVector(); - mElseBranch->append(new ContinuationStructurizerNode(secondId, parent)); - - mCondition = new ConditionTree({id, firstId}); -} - -IfStructurizerNode::IfStructurizerNode(QObject *parent) - : StructurizerNode(parent) - , mCondition(nullptr) - , mThenBranch(new QVector()) - , mElseBranch(new QVector()) -{ -} - -IfStructurizerNode::IfStructurizerNode(ConditionTree * ifCondition, QObject *parent) - : StructurizerNode(parent) - , mCondition(ifCondition) - , mThenBranch(new QVector()) - , mElseBranch(new QVector()) -{ -} - -LoopStructurizerNode::LoopStructurizerNode(QObject *parent) - : StructurizerNode(parent) - , mCondition(nullptr) - , mDoWhileForm(true) -{ -} - -LoopStructurizerNode::LoopStructurizerNode(ConditionTree *c, QObject *parent) - : StructurizerNode(parent) - , mCondition(c) - , mDoWhileForm(true) -{ -} - - -StructurizerNode::~StructurizerNode() -{ - //qDebug() << "destructor element"; -} - - -StructurizerNode *SimpleStructurizerNode::clone() { - return new SimpleStructurizerNode(this->id(), this->parent()); -} - -StructurizerNode *ContinuationStructurizerNode::clone() { - return new ContinuationStructurizerNode(this->id(), this->parent()); -} - -StructurizerNode *IfStructurizerNode::clone() { - IfStructurizerNode *newCondition = new IfStructurizerNode(parent()); - newCondition->mCondition = mCondition->clone(); - for (auto e : *mThenBranch) { - newCondition->mThenBranch->append(e->clone()); - } - for (auto e : *mElseBranch) { - newCondition->mElseBranch->append(e->clone()); - } - return newCondition; -} - -StructurizerNode *LoopStructurizerNode::clone() { - LoopStructurizerNode *x = new LoopStructurizerNode(parent()); - auto xBody = new QVector(); - for (auto e : *mBody) { - xBody->append(e); - } - x->setBody(xBody); - x->mDoWhileForm = mDoWhileForm; - x->mCondition = mCondition == nullptr ? nullptr :mCondition->clone(); - return x; -} - -QVector *LoopStructurizerNode::body() { - return mBody; -} - -StructurizerNode::Vertex SimpleStructurizerNode::id() const -{ - return this->mId; -} - -StructurizerNode::Vertex ContinuationStructurizerNode::id() const -{ - return this->mId; -} - -StructurizerNode::Vertex LoopStructurizerNode::id() const -{ - if (mCondition == nullptr) - return qReal::Id(); - return mCondition->isValue() ? mCondition->value().first : qReal::Id(); -} - -StructurizerNode::Vertex IfStructurizerNode::id() const -{ - return mCondition->isValue() ? mCondition->value().first : qReal::Id(); -} - -void LoopStructurizerNode::setBody(QVector *body, int to) { - mBody = new QVector(); - for (int i = 0; i < (to == -1 ? body->size() : to); ++i) { - auto z = (*body)[i]->clone(); - mBody->append(z); - } -} - -QVector *IfStructurizerNode::thenBranch() { - return mThenBranch; -} - -QVector *IfStructurizerNode::elseBranch() { - return mElseBranch; -} - - -void IfStructurizerNode::dropContinuations(const Vertex &id) { - for (int i = 0; i < mThenBranch->size(); ++i) { - if ((*mThenBranch)[i]->type() == continuation) { - if ((id == qReal::Id()) || (id == (*mThenBranch)[i]->id())) { - mThenBranch->erase(mThenBranch->begin()+i--); - } - } else if ((*mThenBranch)[i]->type() == ifThenElse) { - dynamic_cast((*mThenBranch)[i])->dropContinuations(id); - } - } - for (int i = 0; i < mElseBranch->size(); ++i) { - if ((*mElseBranch)[i]->type() == continuation) { - if ((id == qReal::Id()) || (id == (*mElseBranch)[i]->id())) { - mElseBranch->erase(mElseBranch->begin()+i--); - } - } else if ((*mElseBranch)[i]->type() == ifThenElse) { - dynamic_cast((*mElseBranch)[i])->dropContinuations(id); - } - } -} - -void IfStructurizerNode::dropNonContinuations() { - for (int i = 0; i < mThenBranch->size(); ++i) { - if ((*mThenBranch)[i]->type() == simple || (*mThenBranch)[i]->type() == loop) { - mThenBranch->erase(mThenBranch->begin()+i--); - } else if ((*mThenBranch)[i]->type() == ifThenElse) { - dynamic_cast((*mThenBranch)[i])->dropNonContinuations(); - } - } - for (int i = 0; i < mElseBranch->size(); ++i) { - if ((*mElseBranch)[i]->type() == simple || (*mElseBranch)[i]->type() == loop) { - mElseBranch->erase(mElseBranch->begin()+i--); - } else if ((*mElseBranch)[i]->type() == ifThenElse) { - dynamic_cast((*mElseBranch)[i])->dropNonContinuations(); - } - } -} - -bool IfStructurizerNode::hasSameCondition(IfStructurizerNode *x) { - if ((mCondition == nullptr) && (x->mCondition == nullptr)) - return true; - if ((mCondition == nullptr) xor (x->mCondition == nullptr)) - return false; - return mCondition->isEqual(x->mCondition); -} - -bool LoopStructurizerNode::hasSameCondition(LoopStructurizerNode *x) { - if ((mCondition == nullptr) && (x->mCondition == nullptr)) - return true; - if ((mCondition == nullptr) xor (x->mCondition == nullptr)) - return false; - return mCondition->isEqual(x->mCondition); -} - -bool SimpleStructurizerNode::isEqual(StructurizerNode * another) { - if (another->type() != simple) { - return false; - } - return mId == another->id(); -} - -bool ContinuationStructurizerNode::isEqual(StructurizerNode * another) { - if (another->type() != continuation) { - return false; - } - return mId == another->id(); -} - -bool IfStructurizerNode::isEqual(StructurizerNode * another) { - if (another->type() != ifThenElse) { - return false; - } - if (!hasSameCondition(dynamic_cast(another))) { - return false; - } - if (mThenBranch->size() != dynamic_cast(another)->thenBranch()->size() - || mElseBranch->size() != dynamic_cast(another)->elseBranch()->size()) { - return false; - } - for (int i = 0; i < mThenBranch->size(); ++i) { - if (!(*mThenBranch)[i]->isEqual((*dynamic_cast(another)->thenBranch())[i])) { - return false; - } - } - for (int i = 0; i < mElseBranch->size(); ++i) { - if (!(*mElseBranch)[i]->isEqual((*dynamic_cast(another)->elseBranch())[i])) { - return false; - } - } - return true; -} - -bool LoopStructurizerNode::isEqual(StructurizerNode * another) { - if (another->type() != loop) { - return false; - } - if (!hasSameCondition(dynamic_cast(another))) { - return false; - } - if (mBody->size() != dynamic_cast(another)->body()->size()) { - return false; - } - for (int i = 0; i < mBody->size(); ++i) { - if (!(*mBody)[i]->isEqual((*dynamic_cast(another)->body())[i])) { - return false; - } - } - return true; -} - -StructurizerNode::ConditionTree *IfStructurizerNode::findAllContinuations(const Vertex &id) { - ConditionTree *trueCases = nullptr; - ConditionTree *falseCases = nullptr; - bool alwaysTrue = false; - for (auto i : *mThenBranch) { - if (i->containsContinuation(id)) { - ConditionTree *found = nullptr; - if (i->type() == continuation) { - alwaysTrue = true; - trueCases = nullptr; - break; - } else if (i->type() == ifThenElse) { - found = dynamic_cast(i)->findAllContinuations(id); - if (found == nullptr) { - alwaysTrue = true; - trueCases = nullptr; - break; - } - } - if (trueCases == nullptr) { - trueCases = found; - } else { - trueCases = new ConditionTree(OR, trueCases, found); - } - } - } - bool alwaysFalse = false; - for (auto i : *mElseBranch) { - if (i->containsContinuation(id)) { - ConditionTree *found = nullptr; - if (i->type() == continuation) { - alwaysFalse = true; - falseCases = nullptr; - break; - } else if (i->type() == ifThenElse) { - found = dynamic_cast(i)->findAllContinuations(id); - if (found == nullptr) { - alwaysFalse = true; - falseCases = nullptr; - break; - } - } - if (falseCases == nullptr) { - falseCases = found; - } else { - falseCases = new ConditionTree(OR, falseCases, found); - } - } - } - if (alwaysTrue && alwaysFalse) { - return nullptr; - } - if (trueCases != nullptr && falseCases != nullptr) { - if (trueCases->isNegativeTo(falseCases)) - return nullptr; - auto invertedTree = mCondition->clone(); - invertedTree->invert(); - if (falseCases != nullptr) - return new ConditionTree(OR, new ConditionTree(AND, mCondition->clone(), trueCases), new ConditionTree(AND, invertedTree, falseCases)); - } - if (alwaysTrue) { - if (falseCases != nullptr) { - auto invertedTree = mCondition->clone(); - invertedTree->invert(); - return new ConditionTree(OR, mCondition->clone(), new ConditionTree(AND, invertedTree, falseCases)); - } - return mCondition->clone(); - } - if (alwaysFalse) { - auto invertedTree = mCondition->clone(); - invertedTree->invert(); - if (trueCases != nullptr) { - return new ConditionTree(OR, new ConditionTree(AND, mCondition->clone(), trueCases), invertedTree); - } - return invertedTree; - } - if ((trueCases == nullptr) && (falseCases != nullptr)) { - auto invertedTree = mCondition->clone(); - invertedTree->invert(); - return new ConditionTree(AND, invertedTree, falseCases); - } - if ((trueCases != nullptr) && (falseCases == nullptr)) { - return new ConditionTree(AND, mCondition->clone(), trueCases); - } - qDebug() << "INAPROPRITE CONDITIONNODE"; - return nullptr; -} - -StructurizerNode::ConditionTree *IfStructurizerNode::condition() { - return mCondition; -} - -StructurizerNode::ConditionTree *LoopStructurizerNode::condition() { - return mCondition; -} diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/elementNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/elementNode.h deleted file mode 100644 index ab54f6c5f9..0000000000 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/elementNode.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include "structurizerNode.h" - -#include - -namespace generatorBase { - -class IfStructurizerNode : public StructurizerNode -{ - Q_OBJECT - -public: - explicit IfStructurizerNode(const qReal::Id &id, const qReal::Id &firstId, const qReal::Id &secondId, QObject *parent); - explicit IfStructurizerNode(ConditionTree *ifCondition, QObject *parent); - explicit IfStructurizerNode(QObject *parent); - - Type type() const; - Vertex id() const; - - QVector *thenBranch(); - QVector *elseBranch(); - - ConditionTree *condition(); - - bool containsContinuation(const Vertex &id = qReal::Id()); - bool containsNonContinuation(); - bool isEqual(StructurizerNode * another); - ConditionTree *findAllContinuations(const Vertex &id); - - StructurizerNode *clone(); - - bool hasSameCondition(IfStructurizerNode *x); - - //StructurizerNode copy(); - - void dropContinuations(const Vertex &id = qReal::Id()); - void dropNonContinuations(); - - -protected: - - ConditionTree *mCondition; - - QVector *mThenBranch; - QVector *mElseBranch; -}; - -} diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/ifStructurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/ifStructurizerNode.h index 589c87eb9a..1ddb936a00 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/ifStructurizerNode.h +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/ifStructurizerNode.h @@ -8,8 +8,6 @@ namespace generatorBase { class IfStructurizerNode : public StructurizerNode { - Q_OBJECT - public: explicit IfStructurizerNode(const Vertex &id, const Vertex &firstId, const Vertex &secondId, QObject *parent); explicit IfStructurizerNode(const ConditionTree *ifCondition, QObject *parent); @@ -43,11 +41,8 @@ class IfStructurizerNode : public StructurizerNode ~IfStructurizerNode(); protected: - const ConditionTree *mCondition; StructurizerNode *mThenBranch; StructurizerNode *mElseBranch; - }; - } diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/loopStructurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/loopStructurizerNode.h index bea01bb290..9ea5cbfce9 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/loopStructurizerNode.h +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/loopStructurizerNode.h @@ -8,8 +8,6 @@ namespace generatorBase { class LoopStructurizerNode : public StructurizerNode { - Q_OBJECT - public: explicit LoopStructurizerNode(QObject *parent); explicit LoopStructurizerNode(const Vertex &id, bool invertCondition, QObject *parent); @@ -41,11 +39,8 @@ class LoopStructurizerNode : public StructurizerNode void transformBeforeDerecursivation(); protected: - const Vertex mId; const bool mInvertedCondition; StructurizerNode *mBody; - }; - } diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/sequenceStructurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/sequenceStructurizerNode.h index cfad576691..528722c7ba 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/sequenceStructurizerNode.h +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/sequenceStructurizerNode.h @@ -8,8 +8,6 @@ namespace generatorBase { class SequenceStructurizerNode : public StructurizerNode { - Q_OBJECT - public: explicit SequenceStructurizerNode(QObject *parent); @@ -39,6 +37,5 @@ class SequenceStructurizerNode : public StructurizerNode protected: QVector mChildren; - }; } diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/simpleStructurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/simpleStructurizerNode.h index 33cc9494a3..e177a61b79 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/simpleStructurizerNode.h +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/simpleStructurizerNode.h @@ -8,8 +8,6 @@ namespace generatorBase { class SimpleStructurizerNode : public StructurizerNode { - Q_OBJECT - public: explicit SimpleStructurizerNode(const Vertex &id, QObject *parent); @@ -36,6 +34,5 @@ class SimpleStructurizerNode : public StructurizerNode protected: const Vertex mId; - }; } diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/structurizerNode.cpp b/plugins/robots/generators/generatorBase/src/structurizerNodes/structurizerNode.cpp index ba14b267b2..d271f6103a 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/structurizerNode.cpp +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/structurizerNode.cpp @@ -13,11 +13,13 @@ StructurizerNode::~StructurizerNode() StructurizerNode::ConditionTree::ConditionTree(const QPair &idPair) : mInverted(false), mIsOperator(false),mIsValue(true), mValue(idPair), mLeft(nullptr), mRight(nullptr) -{} +{ +} StructurizerNode::ConditionTree::ConditionTree(Operator o, ConditionTree *left, ConditionTree *right) : mInverted(false), mIsOperator(true), mIsValue(false), mOperator(o), mLeft(left), mRight(right) -{} +{ +} void StructurizerNode::ConditionTree::invert() { diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/structurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/structurizerNode.h index 57a3468223..1d061e1031 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/structurizerNode.h +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/structurizerNode.h @@ -6,10 +6,7 @@ namespace generatorBase { class StructurizerNode : public QObject { - Q_OBJECT - public: - enum Type { simple , continuation @@ -43,6 +40,7 @@ class StructurizerNode : public QObject int numberOfFirstVertex(const Vertex &id) const; ~ConditionTree(); + private: bool calculateValue(const QMap, bool> &values) const; void findAllValues(QSet> &values) const; @@ -80,8 +78,5 @@ class StructurizerNode : public QObject virtual void dropEmptyConditionals() = 0; virtual void transformBeforeDerecursivation() = 0; - -protected: - }; } diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.h index c0e1a2b7ce..fc5fbed37b 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.h +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.h @@ -8,13 +8,9 @@ namespace generatorBase { class SwitchStructurizerNode : public StructurizerNode { - Q_OBJECT - public: explicit SwitchStructurizerNode(const Vertex &id, const QVector &branches, QObject *parent); - //explicit SwitchStructurizerNode(const Vertex &id, QObject *parent); - Type type() const; Vertex id() const; QMap branches() const; @@ -42,11 +38,8 @@ class SwitchStructurizerNode : public StructurizerNode void transformBeforeDerecursivation(); protected: - const Vertex mId; QMap mBranches; QPair mDefaultBranch; - }; - } From 17ee38b5348424de1b91807a6f48bd6bc306b0f8 Mon Sep 17 00:00:00 2001 From: Anna Zinovyeva Date: Mon, 7 Jun 2021 14:36:25 +0300 Subject: [PATCH 04/12] switch branches are created with ZoneNodes now --- .../generatorBase/semanticTree/switchNode.h | 7 ++-- .../src/gotoControlFlowGenerator.cpp | 3 +- .../src/semanticTree/switchNode.cpp | 34 +++++++++---------- .../src/structuralControlFlowGenerator.cpp | 30 +++++++++++----- .../switchStructurizerNode.cpp | 5 +++ 5 files changed, 49 insertions(+), 30 deletions(-) diff --git a/plugins/robots/generators/generatorBase/include/generatorBase/semanticTree/switchNode.h b/plugins/robots/generators/generatorBase/include/generatorBase/semanticTree/switchNode.h index 812d80e105..0b609d8a75 100644 --- a/plugins/robots/generators/generatorBase/include/generatorBase/semanticTree/switchNode.h +++ b/plugins/robots/generators/generatorBase/include/generatorBase/semanticTree/switchNode.h @@ -28,10 +28,10 @@ class ROBOTS_GENERATOR_EXPORT SwitchNode : public NonZoneNode explicit SwitchNode(const qReal::Id &idBinded, QObject *parent = nullptr); /// Adds new branch for the switch value (i.e. branch zone will be created for the given value). - void addBranch(const QString &value, SemanticNode * const node); + void addBranch(const QString &value); - /// Binds existing branch with the switch value (i.e. value will be binded with the parent zone of the node). - void mergeBranch(const QString &value, NonZoneNode * const node); + /// Binds existing branch with the switch value (i.e. value will be binded with zone node of the branch). + void mergeBranch(const QString &value, ZoneNode * const zone); /// Returns true if branches for this switch block were already merged. /// This can help to resolve confusion in case when one branch enter into the middle of another. @@ -43,6 +43,7 @@ class ROBOTS_GENERATOR_EXPORT SwitchNode : public NonZoneNode void setGenerateIfs(); + /// Returns branch zone node by guard value. ZoneNode *branchZoneByValue(const QString &value); protected: diff --git a/plugins/robots/generators/generatorBase/src/gotoControlFlowGenerator.cpp b/plugins/robots/generators/generatorBase/src/gotoControlFlowGenerator.cpp index 0a5dfe6a29..e103b8803f 100644 --- a/plugins/robots/generators/generatorBase/src/gotoControlFlowGenerator.cpp +++ b/plugins/robots/generators/generatorBase/src/gotoControlFlowGenerator.cpp @@ -100,7 +100,8 @@ void GotoControlFlowGenerator::visitSwitch(const Id &id, const QList & SwitchNode * const thisNode = static_cast(mSemanticTree->findNodeFor(id)); for (const LinkInfo &branch : links) { const QString value = mRepo.property(branch.linkId, "Guard").toString(); - thisNode->addBranch(value, produceGotoNode(branch.target)); + thisNode->addBranch(value); + thisNode->branchZoneByValue(value)->appendChild(produceGotoNode(branch.target)); produceNextNodeIfNeeded(branch, thisNode); } } diff --git a/plugins/robots/generators/generatorBase/src/semanticTree/switchNode.cpp b/plugins/robots/generators/generatorBase/src/semanticTree/switchNode.cpp index 2e33fb637c..7b95990ac6 100644 --- a/plugins/robots/generators/generatorBase/src/semanticTree/switchNode.cpp +++ b/plugins/robots/generators/generatorBase/src/semanticTree/switchNode.cpp @@ -27,20 +27,17 @@ SwitchNode::SwitchNode(const Id &idBinded, QObject *parent) { } -void SwitchNode::addBranch(const QString &value, SemanticNode * const node) +void SwitchNode::addBranch(const QString &value) { ZoneNode * const zone = new ZoneNode(this); zone->setParentNode(this); bind(value, zone); - if (node) { - zone->appendChild(node); - } } -void SwitchNode::mergeBranch(const QString &value, NonZoneNode * const node) +void SwitchNode::mergeBranch(const QString &value, ZoneNode * const zone) { - Q_ASSERT(node); - bind(value, node->parentZone()); + Q_ASSERT(zone); + bind(value, zone); } bool SwitchNode::branchesMerged() const @@ -58,6 +55,18 @@ void SwitchNode::setGenerateIfs() mGenerateIfs = true; } + +ZoneNode *SwitchNode::branchZoneByValue(const QString &value) +{ + if (value.isEmpty()) { + return mDefaultBranch; + } + if (mBranches.contains(value)) { + return mBranches[value]; + } + return nullptr; +} + QString SwitchNode::toStringImpl(GeneratorCustomizer &customizer, int indent, const QString &indentString) const { QString result; @@ -121,14 +130,3 @@ QLinkedList SwitchNode::children() const return result; } - -ZoneNode *SwitchNode::branchZoneByValue(const QString &value) -{ - if ((value == "") && (mDefaultBranch != nullptr)) { - return mDefaultBranch; - } - if (mBranches.keys().contains(value)) { - return mBranches[value]; - } - return nullptr; -} diff --git a/plugins/robots/generators/generatorBase/src/structuralControlFlowGenerator.cpp b/plugins/robots/generators/generatorBase/src/structuralControlFlowGenerator.cpp index f581a17e7c..e2462ddf3a 100644 --- a/plugins/robots/generators/generatorBase/src/structuralControlFlowGenerator.cpp +++ b/plugins/robots/generators/generatorBase/src/structuralControlFlowGenerator.cpp @@ -211,14 +211,26 @@ void StructuralControlFlowGenerator::addSwitch(StructurizerNode *node, semantics auto switchNode = static_cast(mSemanticTree->produceNodeFor(switchElement->id())); zone->appendChild(switchNode); - for (auto &link : mRepo.outgoingLinks(switchElement->id())) { + QMap addedBranches; + for (const Id &link : mRepo.outgoingLinks(switchElement->id())) { const QString value = mRepo.property(link, "Guard").toString(); - switchNode->addBranch(value, nullptr); - auto target = mRepo.otherEntityFromLink(link, switchElement->id()); - makeSemanticTree(switchElement->branches()[target] - , switchNode->branchZoneByValue(value) - , numberOfOccurrences - , alreadyCalculated); + const Id targetId = mRepo.otherEntityFromLink(link, switchElement->id()); + + if (addedBranches.contains(targetId)) { + ZoneNode * const targetZone = addedBranches[targetId]; + switchNode->mergeBranch(value, targetZone); + } else { + switchNode->addBranch(value); + ZoneNode *zoneForBranch = switchNode->branchZoneByValue(value); + addedBranches[targetId] = zoneForBranch; + StructurizerNode *branchElement = nullptr; + if (targetId == (switchElement->defaultBranch().first)) { + branchElement = switchElement->defaultBranch().second; + } else { + branchElement = switchElement->branches().value(targetId); + } + makeSemanticTree(branchElement, zoneForBranch, numberOfOccurrences, alreadyCalculated); + } } } @@ -273,7 +285,9 @@ void StructuralControlFlowGenerator::appendVertex(const Id &vertex) void StructuralControlFlowGenerator::addEdgeIntoGraph(const Id &from, const Id &to) { - mFollowers[from].append(to); + if (!mFollowers[from].contains(to)) { + mFollowers[from].append(to); + } } void StructuralControlFlowGenerator::appendEdgesAndVertices(const Id &vertex, const QList &links) diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.cpp b/plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.cpp index d1084267f9..10769cd273 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.cpp +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.cpp @@ -87,6 +87,11 @@ QMap SwitchStructurizerNode::branc return mBranches; } +QPair SwitchStructurizerNode::defaultBranch() const +{ + return mDefaultBranch; +} + void SwitchStructurizerNode::dropContinuations(const Vertex &id) { for (auto *&t : mBranches) { From fd08deb503f672fdb1c6d2d224c8879dec4a97a2 Mon Sep 17 00:00:00 2001 From: Anna Zinovyeva Date: Mon, 7 Jun 2021 19:09:49 +0300 Subject: [PATCH 05/12] add one more case for synth if --- .../generatorBase/src/structuralControlFlowGenerator.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/robots/generators/generatorBase/src/structuralControlFlowGenerator.cpp b/plugins/robots/generators/generatorBase/src/structuralControlFlowGenerator.cpp index e2462ddf3a..3cec79599e 100644 --- a/plugins/robots/generators/generatorBase/src/structuralControlFlowGenerator.cpp +++ b/plugins/robots/generators/generatorBase/src/structuralControlFlowGenerator.cpp @@ -320,13 +320,14 @@ QString StructuralControlFlowGenerator::syntheticConditionToString(StructurizerN result = head.id(); } else if (mCustomizer.semanticsOf(head) == enums::semantics::switchBlock) { //it is switch + QList cases; for (auto &link : mRepo.outgoingLinks(head)) { if (mRepo.otherEntityFromLink(link, head) == target) { QString guard = mRepo.property(link, "Guard").toString(); - result = QString("(%1==%2)").arg(head.id(), guard); - break; + cases << QString("(%1==%2)").arg(head.id(), guard); } } + result = cases.join(" or "); } else { //strange case result = head.id(); From 228151d6ca2780ef6b4cab4936a2fbd8fb3b6b77 Mon Sep 17 00:00:00 2001 From: Anna Zinovyeva Date: Tue, 8 Jun 2021 20:20:38 +0300 Subject: [PATCH 06/12] add correct but kind of ugly loops with breaks --- .../generatorBase/src/structurizer.cpp | 14 +- .../continuationStructurizerNode.cpp | 4 - .../continuationStructurizerNode.h | 1 - .../structurizerNodes/ifStructurizerNode.cpp | 22 +-- .../structurizerNodes/ifStructurizerNode.h | 1 - .../loopStructurizerNode.cpp | 7 +- .../structurizerNodes/loopStructurizerNode.h | 1 - .../sequenceStructurizerNode.cpp | 139 +++++++++--------- .../sequenceStructurizerNode.h | 3 +- .../simpleStructurizerNode.cpp | 4 - .../simpleStructurizerNode.h | 1 - .../src/structurizerNodes/structurizerNode.h | 1 - .../switchStructurizerNode.cpp | 4 - .../switchStructurizerNode.h | 1 - 14 files changed, 81 insertions(+), 122 deletions(-) diff --git a/plugins/robots/generators/generatorBase/src/structurizer.cpp b/plugins/robots/generators/generatorBase/src/structurizer.cpp index 4c2791627e..92d86c8046 100644 --- a/plugins/robots/generators/generatorBase/src/structurizer.cpp +++ b/plugins/robots/generators/generatorBase/src/structurizer.cpp @@ -87,15 +87,7 @@ StructurizerNode *Structurizer::performStructurization(const QSet &ve //if recursive if (system[v]->containsContinuation(v)) { - system[v]->mergeConditionalBranches(mExits, mLoopHeads); system[v]->derecursivate(v); - - for (int j = orderOfResolution.size() - 1; j > i; --j) { - if (system[v]->containsContinuation(orderOfResolution[j])) { - system[v]->mergeConditionalBranches(mExits, mLoopHeads); - system[v]->factorize(orderOfResolution[j], true); - } - } } //elimination @@ -171,7 +163,8 @@ void Structurizer::reorderLoopHeads(QVector &vertexOrder) } bool isInLoop = true; for (auto &p : mPredecessors[f]) { - if (!loopBody[e].contains(p)) { + if (!loopBody[e].contains(p) + && !(loopBody.contains(f) && loopBody[f].contains(p))) { isInLoop = false; break; } @@ -179,6 +172,9 @@ void Structurizer::reorderLoopHeads(QVector &vertexOrder) if (isInLoop) { somethingChanged = true; loopBody[e].insert(f); + if (loopBody.contains(f)) { + loopBody[e].unite(loopBody[f]); + } } } } diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/continuationStructurizerNode.cpp b/plugins/robots/generators/generatorBase/src/structurizerNodes/continuationStructurizerNode.cpp index 2b08434528..045c858f5e 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/continuationStructurizerNode.cpp +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/continuationStructurizerNode.cpp @@ -96,7 +96,3 @@ int ContinuationStructurizerNode::numberOfConditionCalculating(const Vertex &id) Q_UNUSED(id) return 0; } - -void ContinuationStructurizerNode::transformBeforeDerecursivation() -{ -} diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/continuationStructurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/continuationStructurizerNode.h index be6a45e123..c0b75e71bb 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/continuationStructurizerNode.h +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/continuationStructurizerNode.h @@ -31,7 +31,6 @@ class ContinuationStructurizerNode : public StructurizerNode bool isEqual(StructurizerNode *other) const; StructurizerNode *clone() const; int numberOfConditionCalculating(const Vertex &id) const; - void transformBeforeDerecursivation(); protected: const Vertex mId; diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/ifStructurizerNode.cpp b/plugins/robots/generators/generatorBase/src/structurizerNodes/ifStructurizerNode.cpp index 511c6e1f73..b5ce0e6b75 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/ifStructurizerNode.cpp +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/ifStructurizerNode.cpp @@ -7,7 +7,7 @@ using namespace generatorBase; StructurizerNode::Type IfStructurizerNode::type() const { - return Type::ifThenElse; + return ifThenElse; } bool IfStructurizerNode::isEmpty() const @@ -38,14 +38,6 @@ IfStructurizerNode::IfStructurizerNode(const Vertex &id, const Vertex &firstId, mCondition = new ConditionTree({id, firstId}); } -/*IfStructurizerNode::IfStructurizerNode(QObject *parent) - : StructurizerNode(parent) - , mCondition(nullptr) - , mThenBranch(new SequenceStructurizerNode(parent)) - , mElseBranch(new SequenceStructurizerNode(parent)) -{ -}*/ - IfStructurizerNode::IfStructurizerNode(const ConditionTree * ifCondition, QObject *parent) : StructurizerNode(parent) , mCondition(ifCondition) @@ -88,7 +80,7 @@ void IfStructurizerNode::dropContinuations(const Vertex &id) mElseBranch->dropContinuations(id); } -bool IfStructurizerNode::isEqual(StructurizerNode * other) const +bool IfStructurizerNode::isEqual(StructurizerNode *other) const { if (other->type() != ifThenElse) { return false; @@ -142,8 +134,8 @@ StructurizerNode::ConditionTree *IfStructurizerNode::findAllContinuations(const void IfStructurizerNode::factorize(const Vertex &id, bool force) { - Q_UNUSED(id) - Q_UNUSED(force) + mThenBranch->factorize(id, force); + mElseBranch->factorize(id, force); } void IfStructurizerNode::derecursivate(const Vertex &id) @@ -195,9 +187,3 @@ int IfStructurizerNode::numberOfConditionCalculating(const Vertex &id) const count += mElseBranch->numberOfConditionCalculating(id); return count; } - -void IfStructurizerNode::transformBeforeDerecursivation() -{ - mThenBranch->transformBeforeDerecursivation(); - mElseBranch->transformBeforeDerecursivation(); -} diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/ifStructurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/ifStructurizerNode.h index 1ddb936a00..5a64c85dca 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/ifStructurizerNode.h +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/ifStructurizerNode.h @@ -37,7 +37,6 @@ class IfStructurizerNode : public StructurizerNode StructurizerNode *thenBranch(); StructurizerNode *elseBranch(); bool isEmpty() const; - void transformBeforeDerecursivation(); ~IfStructurizerNode(); protected: diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/loopStructurizerNode.cpp b/plugins/robots/generators/generatorBase/src/structurizerNodes/loopStructurizerNode.cpp index dc9c860ecf..d28a0c189e 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/loopStructurizerNode.cpp +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/loopStructurizerNode.cpp @@ -54,7 +54,7 @@ StructurizerNode::Vertex LoopStructurizerNode::id() const return mId; } -bool LoopStructurizerNode::isEqual(StructurizerNode * other) const +bool LoopStructurizerNode::isEqual(StructurizerNode *other) const { if (other->type() != loop) { return false; @@ -105,7 +105,6 @@ void LoopStructurizerNode::dropEmptyConditionals() StructurizerNode::ConditionTree *LoopStructurizerNode::findAllContinuations(const Vertex &id) const { Q_UNUSED(id); - qDebug() << "WANT FACTORIZE FROM LOOP"; return nullptr; } @@ -129,10 +128,6 @@ int LoopStructurizerNode::numberOfConditionCalculating(const Vertex &id) const return (mId == id ? 1 : 0) + mBody->numberOfConditionCalculating(id); } -void LoopStructurizerNode::transformBeforeDerecursivation() -{ -} - bool LoopStructurizerNode::isInverted() const { return mInvertedCondition; diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/loopStructurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/loopStructurizerNode.h index 9ea5cbfce9..19483c7de9 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/loopStructurizerNode.h +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/loopStructurizerNode.h @@ -36,7 +36,6 @@ class LoopStructurizerNode : public StructurizerNode bool isInverted() const; StructurizerNode *body(); void addToBody(StructurizerNode *e); - void transformBeforeDerecursivation(); protected: const Vertex mId; diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/sequenceStructurizerNode.cpp b/plugins/robots/generators/generatorBase/src/structurizerNodes/sequenceStructurizerNode.cpp index 415e0d0980..9419a65764 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/sequenceStructurizerNode.cpp +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/sequenceStructurizerNode.cpp @@ -4,6 +4,7 @@ #include "ifStructurizerNode.h" #include "loopStructurizerNode.h" #include "switchStructurizerNode.h" +#include "breakStructurizerNode.h" using namespace generatorBase; @@ -123,59 +124,59 @@ StructurizerNode::ConditionTree *SequenceStructurizerNode::findAllContinuations( void SequenceStructurizerNode::factorize(const Vertex &id, bool force) { - int totalCount = 0; + if (numberOfContinuation(id) == 0 + || (!force && (numberOfContinuation(id) == 1))) { + return; + } ConditionTree *ifCondition = nullptr; - int lastIndex = -1; bool always = false; for (int i = 0; i < mChildren.size(); ++i) { if (mChildren[i]->containsContinuation(id)) { - totalCount += mChildren[i]->numberOfContinuation(id); - lastIndex = i; - if (always) { - continue; - } - ConditionTree *tree = mChildren[i]->findAllContinuations(id); - if (tree == nullptr) { - //we always come to it - always = true; - delete ifCondition; - ifCondition = nullptr; + if (mChildren[i]->type() == loop) { + auto loopBody = static_cast(mChildren[i])->body(); + static_cast(loopBody)->addBreaksToLoopFor(id); + ConditionTree *newIf = loopBody->findAllContinuations(id); + loopBody->replaceContinuation(id, new BreakStructurizerNode(parent())); + mChildren.insert(i + 1, new IfStructurizerNode(newIf, parent())); } else { - if (ifCondition == nullptr) { - ifCondition = tree; + mChildren[i]->factorize(id, true); + if (always) { + continue; + } + ConditionTree *newCase = mChildren[i]->findAllContinuations(id); + if (newCase == nullptr) { + always = true; + delete ifCondition; + ifCondition = nullptr; } else { - if (ifCondition->isNegativeTo(tree)) { - always = true; - delete ifCondition; - ifCondition = nullptr; - } - else { - ifCondition = new ConditionTree(ConditionTree::OR, tree, ifCondition); + if (ifCondition == nullptr) { + ifCondition = newCase; + } else { + ifCondition = new ConditionTree(ConditionTree::OR, newCase, ifCondition); } } } } } - if ((!force && totalCount < 2) || (totalCount == 0)) { - delete ifCondition; - return; - } - for (int i = 0; i <= lastIndex; ++i) { - if (mChildren[i]->containsContinuation(id) && mChildren[i]->type() == continuation) { - mChildren.erase(mChildren.begin() + i--); - --lastIndex; - } else { - mChildren[i]->dropContinuations(id); + + for (int i = 0; i < mChildren.size(); ++i) { + if (mChildren[i]->containsContinuation(id)) { + if (mChildren[i]->type() == continuation) { + mChildren.erase(mChildren.begin() + i--); + } else { + mChildren[i]->dropContinuations(id); + } } } - if ((ifCondition == nullptr) || (ifCondition->isTrue())) { - mChildren.insert(lastIndex + 1, new ContinuationStructurizerNode(id, parent())); + + if (ifCondition == nullptr || ifCondition->isTrue()) { + delete ifCondition; + mChildren.append(new ContinuationStructurizerNode(id, parent())); } else { - StructurizerNode *t = new IfStructurizerNode(ifCondition, parent()); - StructurizerNode *thenBranch = static_cast(t)->thenBranch(); + StructurizerNode *newIf = new IfStructurizerNode(ifCondition, parent()); + StructurizerNode *thenBranch = static_cast(newIf)->thenBranch(); static_cast(thenBranch)->addToTheEnd(new ContinuationStructurizerNode(id, parent())); - //wtf - mChildren.insert(lastIndex + 1, t); + mChildren.append(newIf); } dropEmptyConditionals(); } @@ -184,18 +185,21 @@ void SequenceStructurizerNode::derecursivate(const Vertex &id) { if (mChildren.size() == 1 && mChildren[0]->type() == ifThenElse) { auto onlyIf = static_cast(mChildren[0]); - if (onlyIf->thenBranch()->containsContinuation(id) - && !onlyIf->elseBranch()->containsContinuation(id)) + auto thenBranch = static_cast(onlyIf->thenBranch()); + auto elseBranch = static_cast(onlyIf->elseBranch()); + if (thenBranch->containsContinuation(id) + && thenBranch->numberOfContinuation(id) == thenBranch->numberOfContinuation() + && !elseBranch->containsContinuation(id)) { - onlyIf->thenBranch()->dropContinuations(id); + thenBranch->dropContinuations(id); auto ifCondition = onlyIf->condition(); auto loop = new LoopStructurizerNode(ifCondition->value().first , ifCondition->isInverted(), parent()); - for (auto &e : static_cast(onlyIf->thenBranch())->mChildren) { + for (auto &e : thenBranch->mChildren) { loop->addToBody(e); } - for (auto &e : static_cast(onlyIf->elseBranch())->mChildren) { + for (auto &e : elseBranch->mChildren) { mChildren.append(e); } mChildren.pop_front(); @@ -203,20 +207,21 @@ void SequenceStructurizerNode::derecursivate(const Vertex &id) return; } - if (onlyIf->elseBranch()->containsContinuation(id) - && !onlyIf->thenBranch()->containsContinuation(id)) + if (elseBranch->containsContinuation(id) + && elseBranch->numberOfContinuation(id) == elseBranch->numberOfContinuation() + && !thenBranch->containsContinuation(id)) { - onlyIf->elseBranch()->dropContinuations(id); + elseBranch->dropContinuations(id); auto invertedCondition = onlyIf->condition(); invertedCondition->invert(); auto loop = new LoopStructurizerNode(invertedCondition->value().first , invertedCondition->isInverted(), parent()); - for (auto &e : static_cast(onlyIf->elseBranch())->mChildren) { + for (auto &e : elseBranch->mChildren) { loop->addToBody(e); } - for (auto &e : static_cast(onlyIf->thenBranch())->mChildren) { + for (auto &e : thenBranch->mChildren) { mChildren.append(e); } mChildren.pop_front(); @@ -227,8 +232,8 @@ void SequenceStructurizerNode::derecursivate(const Vertex &id) dropContinuations(id); LoopStructurizerNode *loop = new LoopStructurizerNode(parent()); - for (auto &e : mChildren) { - loop->addToBody(e); + for (int i = 0; i <= mChildren.size() - 1; ++i) { + loop->addToBody(mChildren[i]); } mChildren.clear(); mChildren.append(loop); @@ -320,7 +325,7 @@ void SequenceStructurizerNode::replaceContinuation(const Vertex &id, Structurize if (mChildren[i]->type() == continuation && mChildren[i]->id() == id) { mChildren.erase(mChildren.begin() + i--); if (value->type() == sequence) { - for (StructurizerNode *e : static_cast(value)->mChildren) { + for (StructurizerNode *&e : static_cast(value)->mChildren) { mChildren.insert(mChildren.begin() + ++i, e->clone()); } } else { @@ -341,27 +346,21 @@ int SequenceStructurizerNode::numberOfConditionCalculating(const Vertex &id) con return count; } -void SequenceStructurizerNode::transformBeforeDerecursivation() +void SequenceStructurizerNode::addBreaksToLoopFor(const Vertex &id) { for (int i = 0; i < mChildren.size(); ++i) { - auto &e = mChildren[i]; - e->transformBeforeDerecursivation(); - if (e->type() == ifThenElse) { - auto first = static_cast(static_cast(e)->thenBranch()); - auto second = static_cast(static_cast(e)->elseBranch()); - if (first->mChildren.size() > 0 && second->mChildren.size() > 0) { - if (first->mChildren.last()->type() == continuation) { - for (int j = second->mChildren.size() - 1; j >= 0; --j) { - mChildren.insert(i + 1, second->mChildren[j]); - } - second->mChildren.clear(); - } else if (second->mChildren.last()->type() == continuation) { - for (int j = first->mChildren.size() - 1; j >= 0; --j) { - mChildren.insert(i + 1, first->mChildren[j]); - } - first->mChildren.clear(); - } - } + if (mChildren[i]->type() == ifThenElse) { + auto thisIf = static_cast(mChildren[i]); + static_cast(thisIf->thenBranch())->addBreaksToLoopFor(id); + static_cast(thisIf->elseBranch())->addBreaksToLoopFor(id); + } else if (mChildren[i]->type() == loop) { + auto thisLoop = static_cast(mChildren[i]); + static_cast(thisLoop->body())->addBreaksToLoopFor(id); + ConditionTree *breakCondition = static_cast(thisLoop->body())->findAllContinuations(id); + thisLoop->replaceContinuation(id, new BreakStructurizerNode(parent())); + auto breakIf = new IfStructurizerNode(breakCondition, parent()); + mChildren.insert(++i, breakIf); + static_cast(breakIf->thenBranch())->addToTheEnd(new ContinuationStructurizerNode(id, parent())); } } } diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/sequenceStructurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/sequenceStructurizerNode.h index 528722c7ba..0b1504947c 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/sequenceStructurizerNode.h +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/sequenceStructurizerNode.h @@ -33,9 +33,10 @@ class SequenceStructurizerNode : public StructurizerNode void addToTheEnd(StructurizerNode *); QVector children(); - void transformBeforeDerecursivation(); protected: QVector mChildren; + + void addBreaksToLoopFor(const Vertex &id); }; } diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/simpleStructurizerNode.cpp b/plugins/robots/generators/generatorBase/src/structurizerNodes/simpleStructurizerNode.cpp index c09426e026..62c779eab8 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/simpleStructurizerNode.cpp +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/simpleStructurizerNode.cpp @@ -92,7 +92,3 @@ int SimpleStructurizerNode::numberOfConditionCalculating(const Vertex &id) const Q_UNUSED(id) return 0; } - -void SimpleStructurizerNode::transformBeforeDerecursivation() -{ -} diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/simpleStructurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/simpleStructurizerNode.h index e177a61b79..1891a24feb 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/simpleStructurizerNode.h +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/simpleStructurizerNode.h @@ -30,7 +30,6 @@ class SimpleStructurizerNode : public StructurizerNode StructurizerNode *clone() const; int numberOfConditionCalculating(const Vertex &id) const; void dropEmptyConditionals(); - void transformBeforeDerecursivation(); protected: const Vertex mId; diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/structurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/structurizerNode.h index 1d061e1031..7c21ee44bb 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/structurizerNode.h +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/structurizerNode.h @@ -77,6 +77,5 @@ class StructurizerNode : public QObject virtual int numberOfConditionCalculating(const Vertex &id) const = 0; virtual void dropEmptyConditionals() = 0; - virtual void transformBeforeDerecursivation() = 0; }; } diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.cpp b/plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.cpp index 10769cd273..460eb98391 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.cpp +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.cpp @@ -227,7 +227,3 @@ int SwitchStructurizerNode::numberOfConditionCalculating(const Vertex &id) const count += mDefaultBranch.second->numberOfConditionCalculating(id); return count; } - -void SwitchStructurizerNode::transformBeforeDerecursivation() -{ -} diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.h index fc5fbed37b..c5c81abb61 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.h +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.h @@ -35,7 +35,6 @@ class SwitchStructurizerNode : public StructurizerNode void dropEmptyConditionals(); bool isEmpty() const; - void transformBeforeDerecursivation(); protected: const Vertex mId; From 1bbc925284b3c5fb645f2d6c656de66a9008e53b Mon Sep 17 00:00:00 2001 From: Anna Zinovyeva Date: Tue, 8 Jun 2021 23:42:39 +0300 Subject: [PATCH 07/12] add prefix in label manager --- .../generatorBase/src/readableLabelManager.cpp | 9 +++++---- .../generators/generatorBase/src/readableLabelManager.h | 5 +++-- .../src/simpleGenerators/syntheticIfGenerator.cpp | 2 +- .../simpleGenerators/syntheticVariableNameGenerator.cpp | 2 +- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/plugins/robots/generators/generatorBase/src/readableLabelManager.cpp b/plugins/robots/generators/generatorBase/src/readableLabelManager.cpp index 0a4bf08211..658cd0d1b0 100644 --- a/plugins/robots/generators/generatorBase/src/readableLabelManager.cpp +++ b/plugins/robots/generators/generatorBase/src/readableLabelManager.cpp @@ -19,7 +19,7 @@ using namespace generatorBase; -QString ReadableLabelManager::labelFor(const qReal::Id &id) +QString ReadableLabelManager::labelFor(const qReal::Id &id, const QString &prefix) { qReal::Id actualId = id; if (actualId.editor().startsWith("label_")) { @@ -34,15 +34,16 @@ QString ReadableLabelManager::labelFor(const qReal::Id &id) return mLabels.value(actualId); } - const auto type = actualId.type(); + const auto type = prefix == "" + ? QString("%1_").arg(beautify(actualId.element())) + : prefix; if (mNodeTypesCount.contains(type)) { ++mNodeTypesCount[type]; } else { mNodeTypesCount.insert(type, 1); } - const auto label = QString("__temp_%1").arg(mLabels.size() + 1); - //beautify(QString("%1_%2").arg(actualId.element()).arg(mNodeTypesCount.value(type))); + const auto label = QString("%1%2").arg(type).arg(mNodeTypesCount.value(type)); mLabels.insert(actualId, label); return label; } diff --git a/plugins/robots/generators/generatorBase/src/readableLabelManager.h b/plugins/robots/generators/generatorBase/src/readableLabelManager.h index b1b9e8f903..db84f6ff2f 100644 --- a/plugins/robots/generators/generatorBase/src/readableLabelManager.h +++ b/plugins/robots/generators/generatorBase/src/readableLabelManager.h @@ -26,7 +26,8 @@ class ReadableLabelManager { public: /// Returns existing or generates new label for a node with given id. - QString labelFor(const qReal::Id &id); + /// For new ids label starts with given prefix or uses node type. + QString labelFor(const qReal::Id &id, const QString &prefix = ""); /// Clears all stored labels. void reinit(); @@ -35,7 +36,7 @@ class ReadableLabelManager /// Makes given string CAPS_WITH_UNDERSCORES. static QString beautify(const QString &label); - QHash mNodeTypesCount; + QHash mNodeTypesCount; QHash mLabels; }; diff --git a/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticIfGenerator.cpp b/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticIfGenerator.cpp index 0e2f04bad8..af1b113b07 100644 --- a/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticIfGenerator.cpp +++ b/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticIfGenerator.cpp @@ -40,7 +40,7 @@ QString SyntheticIfGenerator::generate() QString result = mSyntheticCondition; for (const qReal::Id &id : mUseVariable.keys()) { if (mUseVariable[id]) { - result.replace(id.id(), mNameManager.labelFor(id)); + result.replace(id.id(), mNameManager.labelFor(id, "__temp_")); } else { result.replace(id.id(), mRepo.property(id, "Condition").toString()); } diff --git a/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticVariableNameGenerator.cpp b/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticVariableNameGenerator.cpp index 5feab9d3d5..8c63d571d9 100644 --- a/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticVariableNameGenerator.cpp +++ b/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticVariableNameGenerator.cpp @@ -11,7 +11,7 @@ simple::SyntheticVariableNameGenerator::SyntheticVariableNameGenerator(const qrR , QObject *parent) : BindingGenerator(repo, customizer, id, "function.t" , { Binding::createStaticConverting("@@BODY@@" - , nameManager.labelFor(id) + "=" + + , nameManager.labelFor(id, "__temp_") + "=" + repo.property(id, repo.hasProperty(id, "Condition") ? "Condition" : "Expression").toString() , customizer.factory()->functionBlockConverter(id, "Condition")) } , parent) From 88185baec75aab7681792463b47be1725e256ea4 Mon Sep 17 00:00:00 2001 From: Anna Zinovyeva Date: Wed, 9 Jun 2021 00:20:02 +0300 Subject: [PATCH 08/12] trying to avoid duplication in constructors --- .../generatorBase/semanticTree/ifNode.h | 4 +++- .../generatorBase/src/semanticTree/ifNode.cpp | 20 ++++++++++--------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/plugins/robots/generators/generatorBase/include/generatorBase/semanticTree/ifNode.h b/plugins/robots/generators/generatorBase/include/generatorBase/semanticTree/ifNode.h index d8ae256445..66ce79e19b 100644 --- a/plugins/robots/generators/generatorBase/include/generatorBase/semanticTree/ifNode.h +++ b/plugins/robots/generators/generatorBase/include/generatorBase/semanticTree/ifNode.h @@ -41,9 +41,11 @@ class ROBOTS_GENERATOR_EXPORT IfNode : public ConditionalNode QString toStringImpl(GeneratorCustomizer &customizer, int indent, const QString &indentString) const override; private: + void init(); + ZoneNode *mThenZone; // Takes ownership ZoneNode *mElseZone; // Takes ownership - bool mIsSimple; + bool mIsSimple {false}; bool mIsSynthetic; QString mSyntheticCondition; QMap mIdWasUsedBefore; diff --git a/plugins/robots/generators/generatorBase/src/semanticTree/ifNode.cpp b/plugins/robots/generators/generatorBase/src/semanticTree/ifNode.cpp index 612899f4d2..639ef07863 100644 --- a/plugins/robots/generators/generatorBase/src/semanticTree/ifNode.cpp +++ b/plugins/robots/generators/generatorBase/src/semanticTree/ifNode.cpp @@ -21,23 +21,24 @@ using namespace qReal; IfNode::IfNode(const Id &idBinded, QObject *parent) : ConditionalNode(idBinded, parent) - , mThenZone(new ZoneNode(this)) - , mElseZone(new ZoneNode(this)) - , mIsSimple(false) , mIsSynthetic(false) { - mThenZone->setParentNode(this); - mElseZone->setParentNode(this); + init(); } IfNode::IfNode(QObject *parent) : ConditionalNode(qReal::Id(), parent) - , mThenZone(new ZoneNode(this)) - , mElseZone(new ZoneNode(this)) - , mIsSimple(false) , mIsSynthetic(true) { + init(); +} + +void IfNode::init() +{ + mThenZone = new ZoneNode(parent()); mThenZone->setParentNode(this); + + mElseZone = new ZoneNode(parent()); mElseZone->setParentNode(this); } @@ -76,7 +77,8 @@ QString IfNode::toStringImpl(GeneratorCustomizer &customizer, int indent, const const bool elseIsEmpty = mElseZone->isEmpty(); QString result = mIsSynthetic ? utils::StringUtils::addIndent(customizer.factory()-> - syntheticIfGenerator(mId, mIdWasUsedBefore, customizer, elseIsEmpty, mSyntheticCondition, mAddNotToCondition)->generate(), indent, indentString) + syntheticIfGenerator(mId, mIdWasUsedBefore, customizer, elseIsEmpty + , mSyntheticCondition, mAddNotToCondition)->generate(), indent, indentString) : utils::StringUtils::addIndent(customizer.factory()-> ifGenerator(mId, customizer, elseIsEmpty, mAddNotToCondition)->generate(), indent, indentString); From 871aece84c825282e7403b822cd8ccfecb19fd0f Mon Sep 17 00:00:00 2001 From: Anna Zinovyeva Date: Wed, 9 Jun 2021 18:22:18 +0300 Subject: [PATCH 09/12] fix switch with breaks and elif for python --- .../src/structuralControlFlowGenerator.cpp | 17 ++++++-- .../breakStructurizerNode.cpp | 5 +++ .../structurizerNodes/breakStructurizerNode.h | 1 + .../continuationStructurizerNode.cpp | 5 +++ .../continuationStructurizerNode.h | 1 + .../structurizerNodes/ifStructurizerNode.cpp | 14 +++++-- .../structurizerNodes/ifStructurizerNode.h | 1 + .../loopStructurizerNode.cpp | 5 +++ .../structurizerNodes/loopStructurizerNode.h | 1 + .../sequenceStructurizerNode.cpp | 39 ++++++++++++++----- .../sequenceStructurizerNode.h | 2 + .../simpleStructurizerNode.cpp | 5 +++ .../simpleStructurizerNode.h | 2 + .../src/structurizerNodes/structurizerNode.h | 1 + .../switchStructurizerNode.cpp | 19 ++++++++- .../switchStructurizerNode.h | 2 + .../templates/switch/middle.t | 2 +- 17 files changed, 103 insertions(+), 19 deletions(-) diff --git a/plugins/robots/generators/generatorBase/src/structuralControlFlowGenerator.cpp b/plugins/robots/generators/generatorBase/src/structuralControlFlowGenerator.cpp index 3cec79599e..fce737606d 100644 --- a/plugins/robots/generators/generatorBase/src/structuralControlFlowGenerator.cpp +++ b/plugins/robots/generators/generatorBase/src/structuralControlFlowGenerator.cpp @@ -91,10 +91,14 @@ void StructuralControlFlowGenerator::visitSwitch(const Id &id, const QList(mSemanticTree->produceNodeFor(switchElement->id())); + if (switchElement->hasBreakOnUpperLevel()) { + switchNode->setGenerateIfs(); + } zone->appendChild(switchNode); QMap addedBranches; @@ -333,8 +340,10 @@ QString StructuralControlFlowGenerator::syntheticConditionToString(StructurizerN result = head.id(); } } else { - result = tree->boolOperator() == StructurizerNode::ConditionTree::OR ? "(@@1@@) or (@@2@@)" : "(@@1@@) and (@@2@@)"; - result.replace("@@1@@", syntheticConditionToString(tree->left())).replace("@@2@@", syntheticConditionToString(tree->right())); + result = tree->boolOperator() == StructurizerNode::ConditionTree::OR + ? "(@@1@@) or (@@2@@)" : "(@@1@@) and (@@2@@)"; + result.replace("@@1@@", syntheticConditionToString(tree->left())) + .replace("@@2@@", syntheticConditionToString(tree->right())); } return tree->isInverted() ? QString("not(%1)").arg(result) : result; } diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/breakStructurizerNode.cpp b/plugins/robots/generators/generatorBase/src/structurizerNodes/breakStructurizerNode.cpp index f9ea7b77c9..9eaa535b76 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/breakStructurizerNode.cpp +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/breakStructurizerNode.cpp @@ -21,3 +21,8 @@ StructurizerNode *BreakStructurizerNode::clone() const { return new BreakStructurizerNode(parent()); } + +bool BreakStructurizerNode::hasBreakOnUpperLevel() const +{ + return true; +} diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/breakStructurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/breakStructurizerNode.h index 833e863b38..c8f97c25a0 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/breakStructurizerNode.h +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/breakStructurizerNode.h @@ -11,6 +11,7 @@ class BreakStructurizerNode : public SimpleStructurizerNode Type type() const; bool isEqual(StructurizerNode *other) const; + bool hasBreakOnUpperLevel() const; StructurizerNode *clone() const; }; diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/continuationStructurizerNode.cpp b/plugins/robots/generators/generatorBase/src/structurizerNodes/continuationStructurizerNode.cpp index 045c858f5e..d3f48d538b 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/continuationStructurizerNode.cpp +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/continuationStructurizerNode.cpp @@ -96,3 +96,8 @@ int ContinuationStructurizerNode::numberOfConditionCalculating(const Vertex &id) Q_UNUSED(id) return 0; } + +bool ContinuationStructurizerNode::hasBreakOnUpperLevel() const +{ + return false; +} diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/continuationStructurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/continuationStructurizerNode.h index c0b75e71bb..d92310511e 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/continuationStructurizerNode.h +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/continuationStructurizerNode.h @@ -31,6 +31,7 @@ class ContinuationStructurizerNode : public StructurizerNode bool isEqual(StructurizerNode *other) const; StructurizerNode *clone() const; int numberOfConditionCalculating(const Vertex &id) const; + bool hasBreakOnUpperLevel() const; protected: const Vertex mId; diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/ifStructurizerNode.cpp b/plugins/robots/generators/generatorBase/src/structurizerNodes/ifStructurizerNode.cpp index b5ce0e6b75..b6746893b2 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/ifStructurizerNode.cpp +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/ifStructurizerNode.cpp @@ -26,14 +26,17 @@ int IfStructurizerNode::numberOfContinuation(const Vertex &id) const return mThenBranch->numberOfContinuation(id) + mElseBranch->numberOfContinuation(id); } -IfStructurizerNode::IfStructurizerNode(const Vertex &id, const Vertex &firstId, const Vertex &secondId, QObject *parent) +IfStructurizerNode::IfStructurizerNode(const Vertex &id, const Vertex &firstId + , const Vertex &secondId, QObject *parent) : StructurizerNode(parent) { mThenBranch = new SequenceStructurizerNode(parent); - static_cast(mThenBranch)->addToTheEnd(new ContinuationStructurizerNode(firstId, parent)); + static_cast(mThenBranch) + ->addToTheEnd(new ContinuationStructurizerNode(firstId, parent)); mElseBranch = new SequenceStructurizerNode(parent); - static_cast(mElseBranch)->addToTheEnd(new ContinuationStructurizerNode(secondId, parent)); + static_cast(mElseBranch) + ->addToTheEnd(new ContinuationStructurizerNode(secondId, parent)); mCondition = new ConditionTree({id, firstId}); } @@ -187,3 +190,8 @@ int IfStructurizerNode::numberOfConditionCalculating(const Vertex &id) const count += mElseBranch->numberOfConditionCalculating(id); return count; } + +bool IfStructurizerNode::hasBreakOnUpperLevel() const +{ + return mThenBranch->hasBreakOnUpperLevel() || mElseBranch->hasBreakOnUpperLevel(); +} diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/ifStructurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/ifStructurizerNode.h index 5a64c85dca..6754b6dce6 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/ifStructurizerNode.h +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/ifStructurizerNode.h @@ -30,6 +30,7 @@ class IfStructurizerNode : public StructurizerNode bool isEqual(StructurizerNode *other) const; StructurizerNode *clone() const; int numberOfConditionCalculating(const Vertex &id) const; + bool hasBreakOnUpperLevel() const; void dropEmptyConditionals(); diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/loopStructurizerNode.cpp b/plugins/robots/generators/generatorBase/src/structurizerNodes/loopStructurizerNode.cpp index d28a0c189e..d481a38464 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/loopStructurizerNode.cpp +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/loopStructurizerNode.cpp @@ -132,3 +132,8 @@ bool LoopStructurizerNode::isInverted() const { return mInvertedCondition; } + +bool LoopStructurizerNode::hasBreakOnUpperLevel() const +{ + return false; +} diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/loopStructurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/loopStructurizerNode.h index 19483c7de9..d2fca96970 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/loopStructurizerNode.h +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/loopStructurizerNode.h @@ -30,6 +30,7 @@ class LoopStructurizerNode : public StructurizerNode bool isEqual(StructurizerNode *other) const; StructurizerNode *clone() const; int numberOfConditionCalculating(const Vertex &id) const; + bool hasBreakOnUpperLevel() const; void dropEmptyConditionals(); diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/sequenceStructurizerNode.cpp b/plugins/robots/generators/generatorBase/src/structurizerNodes/sequenceStructurizerNode.cpp index 9419a65764..ee36f9c6cd 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/sequenceStructurizerNode.cpp +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/sequenceStructurizerNode.cpp @@ -175,7 +175,8 @@ void SequenceStructurizerNode::factorize(const Vertex &id, bool force) } else { StructurizerNode *newIf = new IfStructurizerNode(ifCondition, parent()); StructurizerNode *thenBranch = static_cast(newIf)->thenBranch(); - static_cast(thenBranch)->addToTheEnd(new ContinuationStructurizerNode(id, parent())); + static_cast(thenBranch) + ->addToTheEnd(new ContinuationStructurizerNode(id, parent())); mChildren.append(newIf); } dropEmptyConditionals(); @@ -239,7 +240,8 @@ void SequenceStructurizerNode::derecursivate(const Vertex &id) mChildren.append(loop); } -bool SequenceStructurizerNode::mergeConditionalBranches(const QSet &exits, const QSet &loopHeads) +bool SequenceStructurizerNode::mergeConditionalBranches(const QSet &exits + , const QSet &loopHeads) { bool result = false; for (int i = 0; i < mChildren.size(); ++i) { @@ -247,8 +249,10 @@ bool SequenceStructurizerNode::mergeConditionalBranches(const QSet &exit result = true; } if (mChildren[i]->type() == ifThenElse) { - SequenceStructurizerNode *first = static_cast(static_cast(mChildren[i])->thenBranch()); - SequenceStructurizerNode *second = static_cast(static_cast(mChildren[i])->elseBranch()); + SequenceStructurizerNode *first = static_cast( + static_cast(mChildren[i])->thenBranch()); + SequenceStructurizerNode *second = static_cast( + static_cast(mChildren[i])->elseBranch()); if (first->mChildren.size() == 0 || second->mChildren.size() == 0) { continue; } @@ -280,8 +284,11 @@ bool SequenceStructurizerNode::mergeConditionalBranches(const QSet &exit int nonExitCount = 0; for (auto &e : thisSwitch->branches()) { if (static_cast(e)->mChildren.size() > 0 - && static_cast(e)->mChildren.last()->type() == continuation) { - endContinuations.insert(static_cast(e)->mChildren.last()->id()); + && static_cast(e) + ->mChildren.last()->type() == continuation) + { + endContinuations.insert(static_cast(e) + ->mChildren.last()->id()); } if (static_cast(e)->mChildren.size() > 0 && static_cast(e)->mChildren.last()->type() == simple @@ -311,7 +318,9 @@ void SequenceStructurizerNode::dropEmptyConditionals() for (int j = 0; j < mChildren.size(); ++j) { if (mChildren[j]->type() == ifThenElse && static_cast(mChildren[j])->isEmpty()) { mChildren.erase(mChildren.begin() + j--); - } else if (mChildren[j]->type() == switchCase && static_cast(mChildren[j])->isEmpty()) { + } else if (mChildren[j]->type() == switchCase + && static_cast(mChildren[j])->isEmpty()) + { mChildren.erase(mChildren.begin() + j--); } else { mChildren[j]->dropEmptyConditionals(); @@ -356,11 +365,23 @@ void SequenceStructurizerNode::addBreaksToLoopFor(const Vertex &id) } else if (mChildren[i]->type() == loop) { auto thisLoop = static_cast(mChildren[i]); static_cast(thisLoop->body())->addBreaksToLoopFor(id); - ConditionTree *breakCondition = static_cast(thisLoop->body())->findAllContinuations(id); + ConditionTree *breakCondition = static_cast( + thisLoop->body())->findAllContinuations(id); thisLoop->replaceContinuation(id, new BreakStructurizerNode(parent())); auto breakIf = new IfStructurizerNode(breakCondition, parent()); mChildren.insert(++i, breakIf); - static_cast(breakIf->thenBranch())->addToTheEnd(new ContinuationStructurizerNode(id, parent())); + static_cast(breakIf->thenBranch()) + ->addToTheEnd(new ContinuationStructurizerNode(id, parent())); } } } + +bool SequenceStructurizerNode::hasBreakOnUpperLevel() const +{ + for (const auto &e : mChildren) { + if (e->hasBreakOnUpperLevel()) { + return true; + } + } + return false; +} diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/sequenceStructurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/sequenceStructurizerNode.h index 0b1504947c..2ba72aa271 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/sequenceStructurizerNode.h +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/sequenceStructurizerNode.h @@ -29,6 +29,8 @@ class SequenceStructurizerNode : public StructurizerNode bool isEqual(StructurizerNode *other) const; StructurizerNode *clone() const; int numberOfConditionCalculating(const Vertex &id) const; + bool hasBreakOnUpperLevel() const; + void dropEmptyConditionals(); void addToTheEnd(StructurizerNode *); diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/simpleStructurizerNode.cpp b/plugins/robots/generators/generatorBase/src/structurizerNodes/simpleStructurizerNode.cpp index 62c779eab8..86b1358fdc 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/simpleStructurizerNode.cpp +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/simpleStructurizerNode.cpp @@ -92,3 +92,8 @@ int SimpleStructurizerNode::numberOfConditionCalculating(const Vertex &id) const Q_UNUSED(id) return 0; } + +bool SimpleStructurizerNode::hasBreakOnUpperLevel() const +{ + return false; +} diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/simpleStructurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/simpleStructurizerNode.h index 1891a24feb..a150e4f64d 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/simpleStructurizerNode.h +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/simpleStructurizerNode.h @@ -29,6 +29,8 @@ class SimpleStructurizerNode : public StructurizerNode bool isEqual(StructurizerNode *other) const; StructurizerNode *clone() const; int numberOfConditionCalculating(const Vertex &id) const; + bool hasBreakOnUpperLevel() const; + void dropEmptyConditionals(); protected: diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/structurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/structurizerNode.h index 7c21ee44bb..7e51f259fe 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/structurizerNode.h +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/structurizerNode.h @@ -75,6 +75,7 @@ class StructurizerNode : public QObject virtual bool isEqual(StructurizerNode *other) const = 0; virtual StructurizerNode *clone() const = 0; virtual int numberOfConditionCalculating(const Vertex &id) const = 0; + virtual bool hasBreakOnUpperLevel() const = 0; virtual void dropEmptyConditionals() = 0; }; diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.cpp b/plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.cpp index 460eb98391..5ce217091a 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.cpp +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.cpp @@ -116,7 +116,8 @@ bool SwitchStructurizerNode::isEqual(StructurizerNode *other) const } } if (static_cast(other)->mDefaultBranch.first != mDefaultBranch.first - || !static_cast(other)->mBranches[mDefaultBranch.first]->isEqual(mBranches[mDefaultBranch.first])) + || !static_cast(other)->mBranches[mDefaultBranch.first] + ->isEqual(mBranches[mDefaultBranch.first])) { return false; } @@ -148,7 +149,8 @@ StructurizerNode::ConditionTree *SwitchStructurizerNode::findAllContinuations(co if (branchCondition == nullptr) { branchCondition = new ConditionTree(qMakePair(mId, e)); } else { - branchCondition = new ConditionTree(ConditionTree::OR, branchCondition, new ConditionTree(qMakePair(mId, e))); + branchCondition = new ConditionTree(ConditionTree::OR + , branchCondition, new ConditionTree(qMakePair(mId, e))); } } if (branchCondition != nullptr) { @@ -227,3 +229,16 @@ int SwitchStructurizerNode::numberOfConditionCalculating(const Vertex &id) const count += mDefaultBranch.second->numberOfConditionCalculating(id); return count; } + +bool SwitchStructurizerNode::hasBreakOnUpperLevel() const +{ + for (const auto &e : mBranches) { + if (e->hasBreakOnUpperLevel()) { + return true; + } + } + if (mDefaultBranch.second->hasBreakOnUpperLevel()) { + return true; + } + return false; +} diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.h index c5c81abb61..8b553c68c0 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.h +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.h @@ -34,6 +34,8 @@ class SwitchStructurizerNode : public StructurizerNode void dropEmptyConditionals(); + bool hasBreakOnUpperLevel() const; + bool isEmpty() const; protected: diff --git a/plugins/robots/generators/trik/trikPythonGeneratorLibrary/templates/switch/middle.t b/plugins/robots/generators/trik/trikPythonGeneratorLibrary/templates/switch/middle.t index a66bf0bc9e..fb25ea9699 100644 --- a/plugins/robots/generators/trik/trikPythonGeneratorLibrary/templates/switch/middle.t +++ b/plugins/robots/generators/trik/trikPythonGeneratorLibrary/templates/switch/middle.t @@ -1,2 +1,2 @@ -else: if (@@CONDITION@@): +elif (@@CONDITION@@): @@BODY@@ From 55f5c70446b3e73bf9932f973396d8dc8e5b576f Mon Sep 17 00:00:00 2001 From: Anna Zinovyeva Date: Fri, 11 Jun 2021 13:42:45 +0300 Subject: [PATCH 10/12] add pass simple node --- .../ev3/ev3RbfGenerator/templates.qrc | 1 + .../ev3/ev3RbfGenerator/templates/pass.t | 0 .../generatorBase/generatorBase.pri | 2 ++ .../generatorBase/generatorFactoryBase.h | 4 +++ .../generatorBase/semanticTree/simpleNode.h | 2 ++ .../src/generatorFactoryBase.cpp | 8 ++++- .../src/semanticTree/simpleNode.cpp | 10 ++++++ .../src/simpleGenerators/passGenerator.cpp | 26 +++++++++++++++ .../src/simpleGenerators/passGenerator.h | 33 +++++++++++++++++++ .../src/structuralControlFlowGenerator.cpp | 8 ++++- .../nxt/nxtOsekCGenerator/templates.qrc | 1 + .../nxt/nxtOsekCGenerator/templates/pass.t | 0 .../nxt/nxtRussianCGenerator/templates.qrc | 1 + .../nxt/nxtRussianCGenerator/templates/pass.t | 0 .../pioneer/pioneerLuaGenerator/templates.qrc | 1 + .../pioneerLuaGenerator/templates/pass.t | 0 .../trikFSharpGeneratorLibrary/templates.qrc | 1 + .../templates/pass.t | 0 .../templates.qrc | 1 + .../templates/pass.t | 0 .../trikPythonGeneratorLibrary/templates.qrc | 1 + .../templates/pass.t | 1 + .../trikQtsGeneratorLibrary/templates.qrc | 1 + .../trikQtsGeneratorLibrary/templates/pass.t | 0 24 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 plugins/robots/generators/ev3/ev3RbfGenerator/templates/pass.t create mode 100644 plugins/robots/generators/generatorBase/src/simpleGenerators/passGenerator.cpp create mode 100644 plugins/robots/generators/generatorBase/src/simpleGenerators/passGenerator.h create mode 100644 plugins/robots/generators/nxt/nxtOsekCGenerator/templates/pass.t create mode 100644 plugins/robots/generators/nxt/nxtRussianCGenerator/templates/pass.t create mode 100644 plugins/robots/generators/pioneer/pioneerLuaGenerator/templates/pass.t create mode 100644 plugins/robots/generators/trik/trikFSharpGeneratorLibrary/templates/pass.t create mode 100644 plugins/robots/generators/trik/trikPascalABCGeneratorLibrary/templates/pass.t create mode 100644 plugins/robots/generators/trik/trikPythonGeneratorLibrary/templates/pass.t create mode 100644 plugins/robots/generators/trik/trikQtsGeneratorLibrary/templates/pass.t diff --git a/plugins/robots/generators/ev3/ev3RbfGenerator/templates.qrc b/plugins/robots/generators/ev3/ev3RbfGenerator/templates.qrc index 98a5aa36e3..349136fe84 100644 --- a/plugins/robots/generators/ev3/ev3RbfGenerator/templates.qrc +++ b/plugins/robots/generators/ev3/ev3RbfGenerator/templates.qrc @@ -5,6 +5,7 @@ templates/beep.t templates/break.t templates/continue.t + templates/pass.t templates/initialNode.t templates/finalNodeMain.t templates/finalNodeSubprogram.t diff --git a/plugins/robots/generators/ev3/ev3RbfGenerator/templates/pass.t b/plugins/robots/generators/ev3/ev3RbfGenerator/templates/pass.t new file mode 100644 index 0000000000..e69de29bb2 diff --git a/plugins/robots/generators/generatorBase/generatorBase.pri b/plugins/robots/generators/generatorBase/generatorBase.pri index 93d8cf153d..6ccbc16444 100644 --- a/plugins/robots/generators/generatorBase/generatorBase.pri +++ b/plugins/robots/generators/generatorBase/generatorBase.pri @@ -66,6 +66,7 @@ HEADERS += \ $$PWD/include/generatorBase/gotoControlFlowGenerator.h \ $$PWD/src/converters/dynamicPropertiesConverter.h \ $$PWD/src/readableLabelManager.h \ + $$PWD/src/simpleGenerators/passGenerator.h \ $$PWD/src/simpleGenerators/syntheticIfGenerator.h \ $$PWD/src/simpleGenerators/syntheticVariableNameGenerator.h \ $$PWD/src/structuralControlFlowGenerator.h \ @@ -91,6 +92,7 @@ SOURCES += \ $$PWD/src/robotsDiagramVisitor.cpp \ $$PWD/src/primaryControlFlowValidator.cpp \ $$PWD/src/generatorFactoryBase.cpp \ + $$PWD/src/simpleGenerators/passGenerator.cpp \ $$PWD/src/simpleGenerators/syntheticIfGenerator.cpp \ $$PWD/src/simpleGenerators/syntheticVariableNameGenerator.cpp \ $$PWD/src/structurizerNodes/breakStructurizerNode.cpp \ diff --git a/plugins/robots/generators/generatorBase/include/generatorBase/generatorFactoryBase.h b/plugins/robots/generators/generatorBase/include/generatorBase/generatorFactoryBase.h index 529c4ab3e2..d186ce69c7 100644 --- a/plugins/robots/generators/generatorBase/include/generatorBase/generatorFactoryBase.h +++ b/plugins/robots/generators/generatorBase/include/generatorBase/generatorFactoryBase.h @@ -153,6 +153,10 @@ class ROBOTS_GENERATOR_EXPORT GeneratorFactoryBase : public QObject virtual simple::AbstractSimpleGenerator *continueGenerator(const qReal::Id &id , GeneratorCustomizer &customizer); + /// Returns a pointer to a code generator for 'pass' instruction + virtual simple::AbstractSimpleGenerator *passGenerator(const qReal::Id &id + , GeneratorCustomizer &customizer); + /// Returns a pointer to a code generator for goto label declaration virtual simple::AbstractSimpleGenerator *labelGenerator(const qReal::Id &id , GeneratorCustomizer &customizer); diff --git a/plugins/robots/generators/generatorBase/include/generatorBase/semanticTree/simpleNode.h b/plugins/robots/generators/generatorBase/include/generatorBase/semanticTree/simpleNode.h index 436da22c48..4ac698c30b 100644 --- a/plugins/robots/generators/generatorBase/include/generatorBase/semanticTree/simpleNode.h +++ b/plugins/robots/generators/generatorBase/include/generatorBase/semanticTree/simpleNode.h @@ -34,6 +34,7 @@ class ROBOTS_GENERATOR_EXPORT SimpleNode : public NonZoneNode , continueNode , gotoNode , tempVariableNode + , passNode }; explicit SimpleNode(const qReal::Id &idBinded, QObject *parent = nullptr); @@ -42,6 +43,7 @@ class ROBOTS_GENERATOR_EXPORT SimpleNode : public NonZoneNode void bindToSyntheticConstruction(SyntheticBlockType type); static SimpleNode *createBreakNode(QObject *parent); + static SimpleNode *createPassNode(QObject *parent); static SimpleNode *createSyntheticVariableNode(const qReal::Id &id, QObject *parent); protected: diff --git a/plugins/robots/generators/generatorBase/src/generatorFactoryBase.cpp b/plugins/robots/generators/generatorBase/src/generatorFactoryBase.cpp index 94a28e7fc9..5878077190 100644 --- a/plugins/robots/generators/generatorBase/src/generatorFactoryBase.cpp +++ b/plugins/robots/generators/generatorBase/src/generatorFactoryBase.cpp @@ -51,6 +51,7 @@ #include "simpleGenerators/subprogramsSimpleGenerator.h" #include "simpleGenerators/breakGenerator.h" #include "simpleGenerators/continueGenerator.h" +#include "simpleGenerators/passGenerator.h" #include "simpleGenerators/labelGenerator.h" #include "simpleGenerators/gotoSimpleGenerator.h" #include "simpleGenerators/variableInitGenerator.h" @@ -216,7 +217,8 @@ simple::AbstractSimpleGenerator *GeneratorFactoryBase::syntheticIfGenerator(cons , bool elseIsEmpty , QString syntheticCondition , bool needInverting) -RETURN_GENERATOR_PTR(SyntheticIfGenerator, (mRepo, customizer, ids, elseIsEmpty, syntheticCondition, id, needInverting, mReadableLabelManager, this)) +RETURN_GENERATOR_PTR(SyntheticIfGenerator, (mRepo, customizer, ids, elseIsEmpty, syntheticCondition + , id, needInverting, mReadableLabelManager, this)) simple::AbstractSimpleGenerator *GeneratorFactoryBase::infiniteLoopGenerator(const Id &id , GeneratorCustomizer &customizer) @@ -326,6 +328,10 @@ simple::AbstractSimpleGenerator *GeneratorFactoryBase::continueGenerator(const I , GeneratorCustomizer &customizer) RETURN_GENERATOR_PTR(ContinueGenerator, (mRepo, customizer, id, this)) +simple::AbstractSimpleGenerator *GeneratorFactoryBase::passGenerator(const Id &id + , GeneratorCustomizer &customizer) +RETURN_GENERATOR_PTR(PassGenerator, (mRepo, customizer, id, this)) + AbstractSimpleGenerator *GeneratorFactoryBase::labelGenerator(const qReal::Id &id , GeneratorCustomizer &customizer) RETURN_GENERATOR_PTR(LabelGenerator, (mRepo, customizer, id, this)) diff --git a/plugins/robots/generators/generatorBase/src/semanticTree/simpleNode.cpp b/plugins/robots/generators/generatorBase/src/semanticTree/simpleNode.cpp index 101510f3eb..16fa131515 100644 --- a/plugins/robots/generators/generatorBase/src/semanticTree/simpleNode.cpp +++ b/plugins/robots/generators/generatorBase/src/semanticTree/simpleNode.cpp @@ -32,6 +32,9 @@ QString SimpleNode::toStringImpl(GeneratorCustomizer &customizer, int indent, co case breakNode: return utils::StringUtils::addIndent(customizer.factory()->breakGenerator(mId , customizer)->generate(), indent, indentString); + case passNode: + return utils::StringUtils::addIndent(customizer.factory()->passGenerator(mId + , customizer)->generate(), indent, indentString); case continueNode: return utils::StringUtils::addIndent(customizer.factory()->continueGenerator(mId , customizer)->generate(), indent, indentString); @@ -59,6 +62,13 @@ SimpleNode *SimpleNode::createBreakNode(QObject *parent) return breakNode; } +SimpleNode *SimpleNode::createPassNode(QObject *parent) +{ + SimpleNode *passNode = new SimpleNode(qReal::Id(), parent); + passNode->bindToSyntheticConstruction(SyntheticBlockType::passNode); + return passNode; +} + SimpleNode *SimpleNode::createSyntheticVariableNode(const qReal::Id &id, QObject *parent) { SimpleNode *varNode = new SimpleNode(id, parent); diff --git a/plugins/robots/generators/generatorBase/src/simpleGenerators/passGenerator.cpp b/plugins/robots/generators/generatorBase/src/simpleGenerators/passGenerator.cpp new file mode 100644 index 0000000000..fe74f82846 --- /dev/null +++ b/plugins/robots/generators/generatorBase/src/simpleGenerators/passGenerator.cpp @@ -0,0 +1,26 @@ +/* Copyright 2013-2021 CyberTech Labs Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ + +#include "passGenerator.h" + +using namespace generatorBase::simple; +using namespace qReal; + +PassGenerator::PassGenerator(const qrRepo::RepoApi &repo + , GeneratorCustomizer &customizer + , const Id &id + , QObject *parent) + : BindingGenerator(repo, customizer, id, "pass.t", QList(), parent) +{ +} diff --git a/plugins/robots/generators/generatorBase/src/simpleGenerators/passGenerator.h b/plugins/robots/generators/generatorBase/src/simpleGenerators/passGenerator.h new file mode 100644 index 0000000000..a17aec8031 --- /dev/null +++ b/plugins/robots/generators/generatorBase/src/simpleGenerators/passGenerator.h @@ -0,0 +1,33 @@ +/* Copyright 2013-2021 CyberTech Labs Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ + +#pragma once + +#include "generatorBase/simpleGenerators/bindingGenerator.h" + +namespace generatorBase { +namespace simple { + +/// Generator for 'pass' construction +class PassGenerator : public BindingGenerator +{ +public: + PassGenerator(const qrRepo::RepoApi &repo + , GeneratorCustomizer &customizer + , const qReal::Id &id + , QObject *parent = nullptr); +}; + +} +} diff --git a/plugins/robots/generators/generatorBase/src/structuralControlFlowGenerator.cpp b/plugins/robots/generators/generatorBase/src/structuralControlFlowGenerator.cpp index fce737606d..3ac59c5084 100644 --- a/plugins/robots/generators/generatorBase/src/structuralControlFlowGenerator.cpp +++ b/plugins/robots/generators/generatorBase/src/structuralControlFlowGenerator.cpp @@ -1,4 +1,4 @@ -/* Copyright 2018 Konstantin Batoev +/* Copyright 2013-2021 CyberTech Labs Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -237,6 +237,9 @@ void StructuralControlFlowGenerator::addSwitch(StructurizerNode *node, semantics branchElement = switchElement->branches().value(targetId); } makeSemanticTree(branchElement, zoneForBranch, numberOfOccurrences, alreadyCalculated); + if (zoneForBranch->children().size() == 0) { + zoneForBranch->appendChild(SimpleNode::createPassNode(mSemanticTree)); + } } } } @@ -282,6 +285,9 @@ void StructuralControlFlowGenerator::addLoop(StructurizerNode *node, semantics:: } zone->appendChild(loopNode); makeSemanticTree(loopElement->body(), loopNode->bodyZone(), numberOfOccurrences, alreadyCalculated); + if (loopNode->bodyZone()->children().size() == 0) { + loopNode->bodyZone()->appendChild(SimpleNode::createPassNode(mSemanticTree)); + } } diff --git a/plugins/robots/generators/nxt/nxtOsekCGenerator/templates.qrc b/plugins/robots/generators/nxt/nxtOsekCGenerator/templates.qrc index a1b985edbe..0aea3b82c6 100644 --- a/plugins/robots/generators/nxt/nxtOsekCGenerator/templates.qrc +++ b/plugins/robots/generators/nxt/nxtOsekCGenerator/templates.qrc @@ -3,6 +3,7 @@ templates/beep.t templates/break.t templates/continue.t + templates/pass.t templates/finalNodeMain.t templates/finalNodeSubprogram.t templates/function.t diff --git a/plugins/robots/generators/nxt/nxtOsekCGenerator/templates/pass.t b/plugins/robots/generators/nxt/nxtOsekCGenerator/templates/pass.t new file mode 100644 index 0000000000..e69de29bb2 diff --git a/plugins/robots/generators/nxt/nxtRussianCGenerator/templates.qrc b/plugins/robots/generators/nxt/nxtRussianCGenerator/templates.qrc index 9f9008736f..c845335fd9 100644 --- a/plugins/robots/generators/nxt/nxtRussianCGenerator/templates.qrc +++ b/plugins/robots/generators/nxt/nxtRussianCGenerator/templates.qrc @@ -3,6 +3,7 @@ templates/beep.t templates/break.t templates/continue.t + templates/pass.t templates/finalNodeMain.t templates/finalNodeSubprogram.t templates/function.t diff --git a/plugins/robots/generators/nxt/nxtRussianCGenerator/templates/pass.t b/plugins/robots/generators/nxt/nxtRussianCGenerator/templates/pass.t new file mode 100644 index 0000000000..e69de29bb2 diff --git a/plugins/robots/generators/pioneer/pioneerLuaGenerator/templates.qrc b/plugins/robots/generators/pioneer/pioneerLuaGenerator/templates.qrc index 6a865c8698..90ae1082ef 100644 --- a/plugins/robots/generators/pioneer/pioneerLuaGenerator/templates.qrc +++ b/plugins/robots/generators/pioneer/pioneerLuaGenerator/templates.qrc @@ -3,6 +3,7 @@ templates/break.t templates/comment.t templates/continue.t + templates/pass.t templates/endOfHandler.t templates/finalNodeMain.t templates/finalNodeSubprogram.t diff --git a/plugins/robots/generators/pioneer/pioneerLuaGenerator/templates/pass.t b/plugins/robots/generators/pioneer/pioneerLuaGenerator/templates/pass.t new file mode 100644 index 0000000000..e69de29bb2 diff --git a/plugins/robots/generators/trik/trikFSharpGeneratorLibrary/templates.qrc b/plugins/robots/generators/trik/trikFSharpGeneratorLibrary/templates.qrc index f6b9fe3813..5a3efcc71c 100644 --- a/plugins/robots/generators/trik/trikFSharpGeneratorLibrary/templates.qrc +++ b/plugins/robots/generators/trik/trikFSharpGeneratorLibrary/templates.qrc @@ -3,6 +3,7 @@ templates/beep.t templates/break.t templates/continue.t + templates/pass.t templates/finalNodeMain.t templates/finalNodeSubprogram.t templates/function.t diff --git a/plugins/robots/generators/trik/trikFSharpGeneratorLibrary/templates/pass.t b/plugins/robots/generators/trik/trikFSharpGeneratorLibrary/templates/pass.t new file mode 100644 index 0000000000..e69de29bb2 diff --git a/plugins/robots/generators/trik/trikPascalABCGeneratorLibrary/templates.qrc b/plugins/robots/generators/trik/trikPascalABCGeneratorLibrary/templates.qrc index cb0c98061e..b2a88a806d 100644 --- a/plugins/robots/generators/trik/trikPascalABCGeneratorLibrary/templates.qrc +++ b/plugins/robots/generators/trik/trikPascalABCGeneratorLibrary/templates.qrc @@ -4,6 +4,7 @@ templates/break.t templates/comment.t templates/continue.t + templates/pass.t templates/finalNodeMain.t templates/finalNodeSubprogram.t templates/function.t diff --git a/plugins/robots/generators/trik/trikPascalABCGeneratorLibrary/templates/pass.t b/plugins/robots/generators/trik/trikPascalABCGeneratorLibrary/templates/pass.t new file mode 100644 index 0000000000..e69de29bb2 diff --git a/plugins/robots/generators/trik/trikPythonGeneratorLibrary/templates.qrc b/plugins/robots/generators/trik/trikPythonGeneratorLibrary/templates.qrc index b6fa8dc39a..d938ea1201 100644 --- a/plugins/robots/generators/trik/trikPythonGeneratorLibrary/templates.qrc +++ b/plugins/robots/generators/trik/trikPythonGeneratorLibrary/templates.qrc @@ -3,6 +3,7 @@ templates/beep.t templates/break.t templates/continue.t + templates/pass.t templates/finalNodeMain.t templates/finalNodeSubprogram.t templates/function.t diff --git a/plugins/robots/generators/trik/trikPythonGeneratorLibrary/templates/pass.t b/plugins/robots/generators/trik/trikPythonGeneratorLibrary/templates/pass.t new file mode 100644 index 0000000000..2ae28399f5 --- /dev/null +++ b/plugins/robots/generators/trik/trikPythonGeneratorLibrary/templates/pass.t @@ -0,0 +1 @@ +pass diff --git a/plugins/robots/generators/trik/trikQtsGeneratorLibrary/templates.qrc b/plugins/robots/generators/trik/trikQtsGeneratorLibrary/templates.qrc index e4a7d38410..a379cc1f3b 100644 --- a/plugins/robots/generators/trik/trikQtsGeneratorLibrary/templates.qrc +++ b/plugins/robots/generators/trik/trikQtsGeneratorLibrary/templates.qrc @@ -3,6 +3,7 @@ templates/beep.t templates/break.t templates/continue.t + templates/pass.t templates/finalNodeMain.t templates/finalNodeSubprogram.t templates/function.t diff --git a/plugins/robots/generators/trik/trikQtsGeneratorLibrary/templates/pass.t b/plugins/robots/generators/trik/trikQtsGeneratorLibrary/templates/pass.t new file mode 100644 index 0000000000..e69de29bb2 From c9d0466cedb8715c0ae039f5819201821286fab4 Mon Sep 17 00:00:00 2001 From: Anna Zinovyeva Date: Fri, 11 Jun 2021 13:45:50 +0300 Subject: [PATCH 11/12] add headers --- .../generatorBase/src/readableLabelManager.cpp | 2 +- .../generatorBase/src/readableLabelManager.h | 2 +- .../simpleGenerators/syntheticIfGenerator.cpp | 3 ++- .../simpleGenerators/syntheticIfGenerator.h | 3 +-- .../syntheticVariableNameGenerator.cpp | 15 +++++++++++++++ .../syntheticVariableNameGenerator.h | 15 ++++++++++++++- .../src/structuralControlFlowGenerator.h | 3 +-- .../generatorBase/src/structurizer.cpp | 18 ++++++++++++++++-- .../generatorBase/src/structurizer.h | 14 ++++++++++++++ .../breakStructurizerNode.cpp | 14 ++++++++++++++ .../structurizerNodes/breakStructurizerNode.h | 14 ++++++++++++++ .../continuationStructurizerNode.cpp | 14 ++++++++++++++ .../continuationStructurizerNode.h | 14 ++++++++++++++ .../structurizerNodes/ifStructurizerNode.cpp | 16 +++++++++++++++- .../src/structurizerNodes/ifStructurizerNode.h | 14 ++++++++++++++ .../structurizerNodes/loopStructurizerNode.cpp | 16 +++++++++++++++- .../structurizerNodes/loopStructurizerNode.h | 14 ++++++++++++++ .../sequenceStructurizerNode.cpp | 14 ++++++++++++++ .../sequenceStructurizerNode.h | 14 ++++++++++++++ .../simpleStructurizerNode.cpp | 14 ++++++++++++++ .../structurizerNodes/simpleStructurizerNode.h | 14 ++++++++++++++ .../src/structurizerNodes/structurizerNode.cpp | 14 ++++++++++++++ .../src/structurizerNodes/structurizerNode.h | 14 ++++++++++++++ .../switchStructurizerNode.cpp | 16 +++++++++++++++- .../structurizerNodes/switchStructurizerNode.h | 14 ++++++++++++++ 25 files changed, 292 insertions(+), 13 deletions(-) diff --git a/plugins/robots/generators/generatorBase/src/readableLabelManager.cpp b/plugins/robots/generators/generatorBase/src/readableLabelManager.cpp index 658cd0d1b0..5f52a101ce 100644 --- a/plugins/robots/generators/generatorBase/src/readableLabelManager.cpp +++ b/plugins/robots/generators/generatorBase/src/readableLabelManager.cpp @@ -1,4 +1,4 @@ -/* Copyright 2017 QReal Research Group +/* Copyright 2013-2021 CyberTech Labs Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/plugins/robots/generators/generatorBase/src/readableLabelManager.h b/plugins/robots/generators/generatorBase/src/readableLabelManager.h index db84f6ff2f..8e2b322f95 100644 --- a/plugins/robots/generators/generatorBase/src/readableLabelManager.h +++ b/plugins/robots/generators/generatorBase/src/readableLabelManager.h @@ -1,4 +1,4 @@ -/* Copyright 2017 QReal Research Group +/* Copyright 2013-2021 CyberTech Labs Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticIfGenerator.cpp b/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticIfGenerator.cpp index af1b113b07..29e01f1572 100644 --- a/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticIfGenerator.cpp +++ b/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticIfGenerator.cpp @@ -1,4 +1,4 @@ -/* Copyright 2007-2015 QReal Research Group +/* Copyright 2013-2021 CyberTech Labs Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,6 +13,7 @@ * limitations under the License. */ #include "syntheticIfGenerator.h" + #include "generatorBase/generatorCustomizer.h" using namespace generatorBase::simple; diff --git a/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticIfGenerator.h b/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticIfGenerator.h index 73e52a3330..057089061f 100644 --- a/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticIfGenerator.h +++ b/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticIfGenerator.h @@ -1,4 +1,4 @@ -/* Copyright 2007-2015 QReal Research Group +/* Copyright 2013-2021 CyberTech Labs Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,7 +15,6 @@ #pragma once #include "generatorBase/simpleGenerators/abstractSimpleGenerator.h" - #include "src/readableLabelManager.h" namespace generatorBase { diff --git a/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticVariableNameGenerator.cpp b/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticVariableNameGenerator.cpp index 8c63d571d9..4cf04875b8 100644 --- a/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticVariableNameGenerator.cpp +++ b/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticVariableNameGenerator.cpp @@ -1,4 +1,19 @@ +/* Copyright 2013-2021 CyberTech Labs Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ + #include "syntheticVariableNameGenerator.h" + #include "generatorBase/generatorCustomizer.h" using namespace generatorBase; diff --git a/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticVariableNameGenerator.h b/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticVariableNameGenerator.h index 7224393131..d0b710b832 100644 --- a/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticVariableNameGenerator.h +++ b/plugins/robots/generators/generatorBase/src/simpleGenerators/syntheticVariableNameGenerator.h @@ -1,7 +1,20 @@ +/* Copyright 2013-2021 CyberTech Labs Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ + #pragma once #include "generatorBase/simpleGenerators/bindingGenerator.h" - #include "src/readableLabelManager.h" namespace generatorBase { diff --git a/plugins/robots/generators/generatorBase/src/structuralControlFlowGenerator.h b/plugins/robots/generators/generatorBase/src/structuralControlFlowGenerator.h index 69a501d54e..d1e0028dd3 100644 --- a/plugins/robots/generators/generatorBase/src/structuralControlFlowGenerator.h +++ b/plugins/robots/generators/generatorBase/src/structuralControlFlowGenerator.h @@ -1,4 +1,4 @@ -/* Copyright 2018 Konstantin Batoev +/* Copyright 2013-2021 CyberTech Labs Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,6 @@ #include "structurizerNodes/switchStructurizerNode.h" #include "structurizerNodes/sequenceStructurizerNode.h" - #include #include diff --git a/plugins/robots/generators/generatorBase/src/structurizer.cpp b/plugins/robots/generators/generatorBase/src/structurizer.cpp index 92d86c8046..f6ca39f5e6 100644 --- a/plugins/robots/generators/generatorBase/src/structurizer.cpp +++ b/plugins/robots/generators/generatorBase/src/structurizer.cpp @@ -1,6 +1,18 @@ -#include "structurizer.h" +/* Copyright 2013-2021 CyberTech Labs Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ -#include +#include "structurizer.h" #include "structurizerNodes/structurizerNode.h" #include "structurizerNodes/simpleStructurizerNode.h" @@ -10,6 +22,8 @@ #include "structurizerNodes/loopStructurizerNode.h" #include "structurizerNodes/switchStructurizerNode.h" +#include + using namespace generatorBase; Structurizer::Structurizer(QObject *parent) diff --git a/plugins/robots/generators/generatorBase/src/structurizer.h b/plugins/robots/generators/generatorBase/src/structurizer.h index 81d229d664..550a70f57e 100644 --- a/plugins/robots/generators/generatorBase/src/structurizer.h +++ b/plugins/robots/generators/generatorBase/src/structurizer.h @@ -1,3 +1,17 @@ +/* Copyright 2013-2021 CyberTech Labs Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ + #pragma once #include diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/breakStructurizerNode.cpp b/plugins/robots/generators/generatorBase/src/structurizerNodes/breakStructurizerNode.cpp index 9eaa535b76..6bd3c368b7 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/breakStructurizerNode.cpp +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/breakStructurizerNode.cpp @@ -1,3 +1,17 @@ +/* Copyright 2013-2021 CyberTech Labs Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ + #include "breakStructurizerNode.h" using namespace generatorBase; diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/breakStructurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/breakStructurizerNode.h index c8f97c25a0..2864f9710c 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/breakStructurizerNode.h +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/breakStructurizerNode.h @@ -1,3 +1,17 @@ +/* Copyright 2013-2021 CyberTech Labs Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ + #pragma once #include "simpleStructurizerNode.h" diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/continuationStructurizerNode.cpp b/plugins/robots/generators/generatorBase/src/structurizerNodes/continuationStructurizerNode.cpp index d3f48d538b..bee9e138c9 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/continuationStructurizerNode.cpp +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/continuationStructurizerNode.cpp @@ -1,3 +1,17 @@ +/* Copyright 2013-2021 CyberTech Labs Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ + #include "continuationStructurizerNode.h" using namespace generatorBase; diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/continuationStructurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/continuationStructurizerNode.h index d92310511e..1e2814347a 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/continuationStructurizerNode.h +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/continuationStructurizerNode.h @@ -1,3 +1,17 @@ +/* Copyright 2013-2021 CyberTech Labs Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ + #pragma once #include "structurizerNode.h" diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/ifStructurizerNode.cpp b/plugins/robots/generators/generatorBase/src/structurizerNodes/ifStructurizerNode.cpp index b6746893b2..a719c54017 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/ifStructurizerNode.cpp +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/ifStructurizerNode.cpp @@ -1,5 +1,19 @@ +/* Copyright 2013-2021 CyberTech Labs Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ + #include "ifStructurizerNode.h" -#include "simpleStructurizerNode.h" + #include "continuationStructurizerNode.h" #include "sequenceStructurizerNode.h" diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/ifStructurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/ifStructurizerNode.h index 6754b6dce6..2717eec41e 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/ifStructurizerNode.h +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/ifStructurizerNode.h @@ -1,3 +1,17 @@ +/* Copyright 2013-2021 CyberTech Labs Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ + #pragma once #include "structurizerNode.h" diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/loopStructurizerNode.cpp b/plugins/robots/generators/generatorBase/src/structurizerNodes/loopStructurizerNode.cpp index d481a38464..adf786eaea 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/loopStructurizerNode.cpp +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/loopStructurizerNode.cpp @@ -1,6 +1,20 @@ +/* Copyright 2013-2021 CyberTech Labs Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ + #include "loopStructurizerNode.h" + #include "sequenceStructurizerNode.h" -#include "ifStructurizerNode.h" using namespace generatorBase; diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/loopStructurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/loopStructurizerNode.h index d2fca96970..e24a3e1c0b 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/loopStructurizerNode.h +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/loopStructurizerNode.h @@ -1,3 +1,17 @@ +/* Copyright 2013-2021 CyberTech Labs Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ + #pragma once #include "structurizerNode.h" diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/sequenceStructurizerNode.cpp b/plugins/robots/generators/generatorBase/src/structurizerNodes/sequenceStructurizerNode.cpp index ee36f9c6cd..6993039faf 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/sequenceStructurizerNode.cpp +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/sequenceStructurizerNode.cpp @@ -1,3 +1,17 @@ +/* Copyright 2013-2021 CyberTech Labs Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ + #include "sequenceStructurizerNode.h" #include "continuationStructurizerNode.h" diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/sequenceStructurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/sequenceStructurizerNode.h index 2ba72aa271..ee444787e8 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/sequenceStructurizerNode.h +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/sequenceStructurizerNode.h @@ -1,3 +1,17 @@ +/* Copyright 2013-2021 CyberTech Labs Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ + #pragma once #include "structurizerNode.h" diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/simpleStructurizerNode.cpp b/plugins/robots/generators/generatorBase/src/structurizerNodes/simpleStructurizerNode.cpp index 86b1358fdc..bd0ddb5a31 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/simpleStructurizerNode.cpp +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/simpleStructurizerNode.cpp @@ -1,3 +1,17 @@ +/* Copyright 2013-2021 CyberTech Labs Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ + #include "simpleStructurizerNode.h" using namespace generatorBase; diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/simpleStructurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/simpleStructurizerNode.h index a150e4f64d..2f5bad1f84 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/simpleStructurizerNode.h +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/simpleStructurizerNode.h @@ -1,3 +1,17 @@ +/* Copyright 2013-2021 CyberTech Labs Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ + #pragma once #include "structurizerNode.h" diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/structurizerNode.cpp b/plugins/robots/generators/generatorBase/src/structurizerNodes/structurizerNode.cpp index d271f6103a..50afa905ba 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/structurizerNode.cpp +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/structurizerNode.cpp @@ -1,3 +1,17 @@ +/* Copyright 2013-2021 CyberTech Labs Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ + #include "structurizerNode.h" using namespace generatorBase; diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/structurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/structurizerNode.h index 7e51f259fe..567dfe87c8 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/structurizerNode.h +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/structurizerNode.h @@ -1,3 +1,17 @@ +/* Copyright 2013-2021 CyberTech Labs Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ + #pragma once #include diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.cpp b/plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.cpp index 5ce217091a..7072a29c7a 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.cpp +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.cpp @@ -1,5 +1,19 @@ +/* Copyright 2013-2021 CyberTech Labs Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ + #include "switchStructurizerNode.h" -#include "simpleStructurizerNode.h" + #include "continuationStructurizerNode.h" #include "sequenceStructurizerNode.h" diff --git a/plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.h b/plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.h index 8b553c68c0..26190ec79f 100644 --- a/plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.h +++ b/plugins/robots/generators/generatorBase/src/structurizerNodes/switchStructurizerNode.h @@ -1,3 +1,17 @@ +/* Copyright 2013-2021 CyberTech Labs Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ + #pragma once #include "structurizerNode.h" From 5e98be8378c422c7c9a7c168cc901bb9f27901c8 Mon Sep 17 00:00:00 2001 From: Anna Zinovyeva Date: Fri, 11 Jun 2021 13:46:58 +0300 Subject: [PATCH 12/12] a few lupdate things --- qrtranslations/fr/plugins/robots/generatorBase_fr.ts | 4 ++-- qrtranslations/ru/plugins/robots/generatorBase_ru.ts | 4 ++-- qrtranslations/ru/plugins/robots/pioneerLuaGenerator_ru.ts | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/qrtranslations/fr/plugins/robots/generatorBase_fr.ts b/qrtranslations/fr/plugins/robots/generatorBase_fr.ts index bf63c26203..6fe98607b6 100644 --- a/qrtranslations/fr/plugins/robots/generatorBase_fr.ts +++ b/qrtranslations/fr/plugins/robots/generatorBase_fr.ts @@ -14,7 +14,7 @@ /* ERREUR SELECTIONNEZ LE TYPE DU CAPTEUR */ - + There is no opened diagram Il n'y a pas de diagramme d'ouvert @@ -136,7 +136,7 @@ generatorBase::MasterGeneratorBase - + This diagram cannot be generated into the structured code. Generating it into the code with 'goto' statements. Ce diagramme ne peut pas être transformé en code structuré. Le code contenant 'goto' sera généré. diff --git a/qrtranslations/ru/plugins/robots/generatorBase_ru.ts b/qrtranslations/ru/plugins/robots/generatorBase_ru.ts index b366e7348f..f2c94a4192 100644 --- a/qrtranslations/ru/plugins/robots/generatorBase_ru.ts +++ b/qrtranslations/ru/plugins/robots/generatorBase_ru.ts @@ -95,7 +95,7 @@ Неизвестный блок - + There is no opened diagram Сначала откройте диаграмму @@ -137,7 +137,7 @@ generatorBase::MasterGeneratorBase - + This diagram cannot be generated into the structured code. Generating it into the code with 'goto' statements. Данная диаграмма не может быть сгенерирована в структурированный код. Генерирую код с 'goto'. diff --git a/qrtranslations/ru/plugins/robots/pioneerLuaGenerator_ru.ts b/qrtranslations/ru/plugins/robots/pioneerLuaGenerator_ru.ts index 18eb381dfe..6b2e4a8473 100644 --- a/qrtranslations/ru/plugins/robots/pioneerLuaGenerator_ru.ts +++ b/qrtranslations/ru/plugins/robots/pioneerLuaGenerator_ru.ts @@ -88,7 +88,7 @@ QObject - + There is no opened diagram Диаграмма не открыта