diff --git a/include/classes/IoTScenario.h b/include/classes/IoTScenario.h index 6313ea40..de1328f1 100644 --- a/include/classes/IoTScenario.h +++ b/include/classes/IoTScenario.h @@ -8,7 +8,7 @@ public: virtual ~ExprAST(); virtual IoTValue* exec(); virtual int setValue(IoTValue *val); // ret 0 - установка значения не поддерживается наследником - virtual bool hasEventIdName(); + virtual bool hasEventIdName(String eventIdName); }; class IoTScenario { @@ -45,7 +45,7 @@ class IoTScenario { /// identifierexpr /// ::= identifier /// ::= identifier '(' expression* ')' - ExprAST *ParseIdentifierExpr(); + ExprAST *ParseIdentifierExpr(String *IDNames); /// numberexpr ::= number ExprAST *ParseNumberExpr(); @@ -60,7 +60,7 @@ class IoTScenario { ExprAST *ParseQuotesExpr(); /// ifexpr ::= 'if' expression 'then' expression 'else' expression - ExprAST *ParseIfExpr(); + ExprAST *ParseIfExpr(String* IDNames); /// primary /// ::= identifierexpr @@ -75,7 +75,7 @@ class IoTScenario { /// expression /// ::= primary binoprhs /// - ExprAST *ParseExpression(); + ExprAST *ParseExpression(String *IDNames); std::vector ScenarioElements; // корневые элементы дерава diff --git a/src/classes/IoTScenario.cpp b/src/classes/IoTScenario.cpp index 770508ca..4551d091 100644 --- a/src/classes/IoTScenario.cpp +++ b/src/classes/IoTScenario.cpp @@ -6,7 +6,6 @@ #include "classes/IoTScenario.h" #include "utils/FileUtils.h" -String _eventIdName = ""; // ID элемента, для которого выполняем сценарий // Лексический анализатор возвращает токены [0-255], если это неизвестны, // иначе одну из известных единиц кода @@ -31,7 +30,7 @@ enum Token { ExprAST::~ExprAST() {} IoTValue* ExprAST::exec() {return nullptr;} int ExprAST::setValue(IoTValue *val) {return 0;} // 0 - установка значения не поддерживается наследником -bool ExprAST::hasEventIdName() {return false;} // по умолчанию все узлы не связаны с ИД события, для которого выполняется сценарий +bool ExprAST::hasEventIdName(String eventIdName) {return false;} // по умолчанию все узлы не связаны с ИД события, для которого выполняется сценарий struct IoTValue zeroIotVal; /// NumberExprAST - Класс узла выражения для числовых литералов (Например, "1.0"). @@ -88,16 +87,10 @@ class BinaryExprAST : public ExprAST { signed char Op; ExprAST *LHS, *RHS; IoTValue val; - String _IDNames; public: - BinaryExprAST(signed char op, ExprAST *lhs, ExprAST *rhs, String IDNames) - : Op(op), LHS(lhs), RHS(rhs), _IDNames(IDNames) {} - - bool hasEventIdName() { - Serial.printf("Call from BinaryExprAST _IDNames:%s\n", _IDNames.c_str()); - return _IDNames.indexOf(_eventIdName) >= 0; // определяем встречался ли ИД, для которого исполняем сценарий в выражении IF - } + BinaryExprAST(signed char op, ExprAST *lhs, ExprAST *rhs) + : Op(op), LHS(lhs), RHS(rhs) {} ~BinaryExprAST() { if (LHS) delete LHS; @@ -222,19 +215,20 @@ public: /// IfExprAST - Класс узла выражения для if/then/else. class IfExprAST : public ExprAST { ExprAST *Cond, *Then, *Else; + String _IDNames; public: - IfExprAST(ExprAST *cond, ExprAST *then, ExprAST *_else) - : Cond(cond), Then(then), Else(_else) {} + IfExprAST(ExprAST *cond, ExprAST *then, ExprAST *_else, String IDNames) + : Cond(cond), Then(then), Else(_else), _IDNames(IDNames) {} + + bool hasEventIdName(String eventIdName) { + Serial.printf("Call from BinaryExprAST _IDNames:%s\n", _IDNames.c_str()); + return _IDNames.indexOf(eventIdName) >= 0; // определяем встречался ли ИД, для которого исполняем сценарий в выражении IF + } IoTValue* exec() { IoTValue *res_ret = nullptr; IoTValue *cond_ret = nullptr; - - if (Cond && !Cond->hasEventIdName()) { - Serial.printf("Call from IfExprAST: Skip because %s not found\n", _eventIdName.c_str()); - return &zeroIotVal; - } if (Cond) cond_ret = Cond->exec(); @@ -427,7 +421,7 @@ public: /// identifierexpr /// ::= identifier /// ::= identifier '(' expression* ')' - ExprAST* IoTScenario::ParseIdentifierExpr() { + ExprAST* IoTScenario::ParseIdentifierExpr(String *IDNames) { String IdName = IdentifierStr; String Cmd = ""; IoTItem* tmpItem = findIoTItem(IdName); @@ -450,7 +444,7 @@ public: std::vector Args; if (CurTok != ')') { while (1) { - ExprAST *Arg = ParseExpression(); + ExprAST *Arg = ParseExpression(IDNames); if (!Arg) return 0; Args.push_back(Arg); @@ -479,7 +473,7 @@ public: /// parenexpr ::= '(' expression ')' ExprAST* IoTScenario::ParseParenExpr() { getNextToken(); // получаем (. - ExprAST *V = ParseExpression(); + ExprAST *V = ParseExpression(nullptr); if (!V) return 0; if (CurTok != ')') @@ -494,7 +488,7 @@ public: std::vector bracketsList; if (CurTok != '}') { while (1) { - ExprAST *Expr = ParseExpression(); + ExprAST *Expr = ParseExpression(nullptr); if (!Expr) return 0; bracketsList.push_back(Expr); @@ -519,18 +513,18 @@ public: } /// ifexpr ::= 'if' expression 'then' expression 'else' expression - ExprAST* IoTScenario::ParseIfExpr() { + ExprAST* IoTScenario::ParseIfExpr(String *IDNames) { getNextToken(); // Получаем if. // условие. - ExprAST *Cond = ParseExpression(); + ExprAST *Cond = ParseExpression(IDNames); if (!Cond) return 0; if (CurTok != tok_then) return Error("expected then"); getNextToken(); // Получаем then - ExprAST *Then = ParseExpression(); + ExprAST *Then = ParseExpression(nullptr); if (Then == 0) return 0; //if (CurTok != tok_else) @@ -538,10 +532,10 @@ public: ExprAST *Else = nullptr; if (CurTok == tok_else) { getNextToken(); - Else = ParseExpression(); + Else = ParseExpression(nullptr); } - return new IfExprAST(Cond, Then, Else); + return new IfExprAST(Cond, Then, Else, *IDNames); } /// primary @@ -552,15 +546,17 @@ public: switch (CurTok) { default: return Error("unknown token when expecting an expression"); case tok_identifier: { - String tmpstr = *IDNames; - *IDNames = tmpstr + " " + IdentifierStr; - return ParseIdentifierExpr(); + if (IDNames) { + String tmpstr = *IDNames; + *IDNames = tmpstr + " " + IdentifierStr; + } + return ParseIdentifierExpr(IDNames); } case tok_number: return ParseNumberExpr(); case '(': return ParseParenExpr(); case '{': return ParseBracketsExpr(); case tok_string: return ParseQuotesExpr(); - case tok_if: return ParseIfExpr(); + case tok_if: return ParseIfExpr(IDNames); } } @@ -593,7 +589,7 @@ public: } // Собираем LHS/RHS. - LHS = new BinaryExprAST(BinOp, LHS, RHS, *IDNames); + LHS = new BinaryExprAST(BinOp, LHS, RHS); } } @@ -601,11 +597,10 @@ public: /// expression /// ::= primary binoprhs /// - ExprAST* IoTScenario::ParseExpression() { - String IDNames = ""; - ExprAST *LHS = ParsePrimary(&IDNames); + ExprAST* IoTScenario::ParseExpression(String *IDNames) { + ExprAST *LHS = ParsePrimary(IDNames); if (!LHS) return 0; - return ParseBinOpRHS(0, LHS, &IDNames); + return ParseBinOpRHS(0, LHS, IDNames); } void IoTScenario::clearScenarioElements() { // удаляем все корневые элементы дерева AST @@ -631,7 +626,11 @@ public: switch (CurTok) { //case tok_eof: return; //case ';': getNextToken(); break; // игнорируем верхнеуровневые точки с запятой. - case tok_if: ScenarioElements.push_back(ParseExpression()); break; + case tok_if: { + String IDNames = ""; // накопитель встречающихся идентификаторов в условии + ScenarioElements.push_back(ParseExpression(&IDNames)); + break; + } default: getNextToken(); break; } } @@ -641,14 +640,15 @@ public: } void IoTScenario::ExecScenario(String eventIdName) { // запускаем поочереди все корневые элементы выражений в сценарии, ожидаемо - это IFы - _eventIdName = eventIdName; // ID элемента для которого выполняем сценарий, т.е. игнорируем любые проверки, если нет такого ID в условиях - + // eventIdName - ID элемента для которого выполняем сценарий, т.е. игнорируем любые проверки, если нет такого ID в условиях Serial.printf("Count root elements in scenario: %d\n", ScenarioElements.size()); for (unsigned int i = 0; i < ScenarioElements.size(); i++) { - if (ScenarioElements[i]) ScenarioElements[i]->exec(); + if (ScenarioElements[i] && ScenarioElements[i]->hasEventIdName(eventIdName)) ScenarioElements[i]->exec(); + else Serial.printf("Call from ExecScenario: Skip ifexec because %s not found\n", eventIdName.c_str()); } } + IoTScenario::IoTScenario() { // Задаём стандартные бинарные операторы. // 1 - наименьший приоритет.