Прерываем работу сценария пока не будут исправлены все

грубые синтаксические ошибки. Это позволяет избежать бесконтрольного
создания узлов бинарного дерева и утечки памяти.
This commit is contained in:
2022-09-05 23:24:57 +03:00
parent 9355953bae
commit a535a66ca7

View File

@@ -6,7 +6,7 @@
#include "NTP.h" #include "NTP.h"
bool isIotScenException; // признак исключения и попытки прекратить выполнение сценария заранее bool isIotScenException = false; // признак исключения и попытки прекратить выполнение сценария заранее
// Лексический анализатор возвращает токены [0-255], если это неизвестны, // Лексический анализатор возвращает токены [0-255], если это неизвестны,
// иначе одну из известных единиц кода // иначе одну из известных единиц кода
@@ -734,7 +734,8 @@ int IoTScenario::GetTokPrecedence() {
/// Error* - Это небольшие вспомогательные функции для обработки ошибок. /// Error* - Это небольшие вспомогательные функции для обработки ошибок.
ExprAST *IoTScenario::Error(const char *Str) { ExprAST *IoTScenario::Error(const char *Str) {
Serial.printf("Scenario error in line %d: %s\n", curLine-1, Str); Serial.printf("Scenario error in line %d: %s\n", curLine, Str);
isIotScenException = true;
return nullptr; return nullptr;
} }
@@ -742,6 +743,8 @@ ExprAST *IoTScenario::Error(const char *Str) {
/// ::= identifier /// ::= identifier
/// ::= identifier '(' expression* ')' /// ::= identifier '(' expression* ')'
ExprAST *IoTScenario::ParseIdentifierExpr(String *IDNames, bool callFromCondition) { ExprAST *IoTScenario::ParseIdentifierExpr(String *IDNames, bool callFromCondition) {
if (isIotScenException) return nullptr;
String IdName = IdentifierStr; String IdName = IdentifierStr;
String Cmd = ""; String Cmd = "";
IoTItem *tmpItem = findIoTItem(IdName); IoTItem *tmpItem = findIoTItem(IdName);
@@ -773,8 +776,10 @@ ExprAST *IoTScenario::ParseIdentifierExpr(String *IDNames, bool callFromConditio
if (CurTok == ')') break; if (CurTok == ')') break;
if (CurTok != ',') if (CurTok != ','){
return Error("Expected ')' or ',' in argument list"); return Error("Expected ')' or ',' in argument list");
}
getNextToken(); getNextToken();
} }
} }
@@ -790,6 +795,8 @@ ExprAST *IoTScenario::ParseIdentifierExpr(String *IDNames, bool callFromConditio
/// numberexpr ::= number /// numberexpr ::= number
ExprAST *IoTScenario::ParseNumberExpr() { ExprAST *IoTScenario::ParseNumberExpr() {
if (isIotScenException) return nullptr;
ExprAST *Result = new NumberExprAST(NumStr); ExprAST *Result = new NumberExprAST(NumStr);
getNextToken(); // получаем число getNextToken(); // получаем число
return Result; return Result;
@@ -809,6 +816,8 @@ ExprAST *IoTScenario::ParseParenExpr(String *IDNames, bool callFromCondition) {
/// bracketsexpr ::= '{' expression '}' /// bracketsexpr ::= '{' expression '}'
ExprAST *IoTScenario::ParseBracketsExpr(String *IDNames, bool callFromCondition) { ExprAST *IoTScenario::ParseBracketsExpr(String *IDNames, bool callFromCondition) {
if (isIotScenException) return nullptr;
getNextToken(); // получаем {. getNextToken(); // получаем {.
std::vector<ExprAST *> bracketsList; std::vector<ExprAST *> bracketsList;
@@ -838,6 +847,8 @@ ExprAST *IoTScenario::ParseBracketsExpr(String *IDNames, bool callFromCondition)
/// quotesexpr ::= '"' expression '"' /// quotesexpr ::= '"' expression '"'
ExprAST *IoTScenario::ParseQuotesExpr() { ExprAST *IoTScenario::ParseQuotesExpr() {
if (isIotScenException) return nullptr;
String StringCont = IdentifierStr; String StringCont = IdentifierStr;
ExprAST *Result = new StringExprAST(StringCont); ExprAST *Result = new StringExprAST(StringCont);
getNextToken(); // получаем число getNextToken(); // получаем число
@@ -846,6 +857,8 @@ ExprAST *IoTScenario::ParseQuotesExpr() {
/// ifexpr ::= 'if' expression 'then' expression 'else' expression /// ifexpr ::= 'if' expression 'then' expression 'else' expression
ExprAST *IoTScenario::ParseIfExpr(String *IDNames) { ExprAST *IoTScenario::ParseIfExpr(String *IDNames) {
if (isIotScenException) return nullptr;
getNextToken(); // Получаем if. getNextToken(); // Получаем if.
// условие. // условие.
@@ -903,6 +916,8 @@ ExprAST *IoTScenario::ParsePrimary(String *IDNames, bool callFromCondition) {
/// binoprhs /// binoprhs
/// ::= ('+' primary)* /// ::= ('+' primary)*
ExprAST *IoTScenario::ParseBinOpRHS(int ExprPrec, ExprAST *LHS, String *IDNames, bool callFromCondition) { ExprAST *IoTScenario::ParseBinOpRHS(int ExprPrec, ExprAST *LHS, String *IDNames, bool callFromCondition) {
if (isIotScenException) return nullptr;
// Если это бинарный оператор, получаем его приоритет // Если это бинарный оператор, получаем его приоритет
while (1) { while (1) {
int TokPrec = GetTokPrecedence(); int TokPrec = GetTokPrecedence();
@@ -944,6 +959,8 @@ ExprAST *IoTScenario::ParseExpression(String *IDNames, bool callFromCondition) {
void IoTScenario::loadScenario(String fileName) { // подготавливаем контекст для чтения и интерпретации файла void IoTScenario::loadScenario(String fileName) { // подготавливаем контекст для чтения и интерпретации файла
isIotScenException = false;
if (mode == 0) { if (mode == 0) {
if (file) file.close(); if (file) file.close();
file = FileFS.open(fileName.c_str(), "r"); file = FileFS.open(fileName.c_str(), "r");
@@ -979,15 +996,12 @@ void IoTScenario::exec(String eventIdName) { // посимвольно счит
case tok_if: { case tok_if: {
IDNames = ""; // сбрасываем накопитель встречающихся идентификаторов в условии IDNames = ""; // сбрасываем накопитель встречающихся идентификаторов в условии
ExprAST *tmpAST = ParseIfExpr(&IDNames); ExprAST *tmpAST = ParseIfExpr(&IDNames);
if (!tmpAST) { if (tmpAST) {
Error("IF Expr wrong."); if (tmpAST->hasEventIdName(eventIdName)) {
break; tmpAST->exec();
} }
delete tmpAST;
if (tmpAST->hasEventIdName(eventIdName)) { } else getNextToken();
tmpAST->exec();
}
delete tmpAST;
break;} break;}
default: getNextToken(); break; default: getNextToken(); break;
} }