Оптимизируем пропуск условий при отсутствии ИД события

This commit is contained in:
2022-02-24 17:18:03 +03:00
parent 24a66b0ca4
commit 798897962e
2 changed files with 43 additions and 43 deletions

View File

@@ -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; // корневые элементы дерава

View File

@@ -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 - наименьший приоритет.