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