From 18d5d5536f360cf0274bb25eb59ef94aa4d82841 Mon Sep 17 00:00:00 2001 From: Moammad97 Date: Thu, 3 Dec 2020 18:02:49 +0330 Subject: [PATCH] implement error handler --- hyperdbg/script-engine/ScriptEngine.c | 148 +++++++++++++++++++------- hyperdbg/script-engine/ScriptEngine.h | 7 ++ hyperdbg/script-engine/scanner.c | 16 ++- hyperdbg/script-engine/scanner.h | 16 +++ 4 files changed, 146 insertions(+), 41 deletions(-) diff --git a/hyperdbg/script-engine/ScriptEngine.c b/hyperdbg/script-engine/ScriptEngine.c index 41a45052..47b498b9 100644 --- a/hyperdbg/script-engine/ScriptEngine.c +++ b/hyperdbg/script-engine/ScriptEngine.c @@ -43,6 +43,14 @@ PSYMBOL_BUFFER ScriptEngineParse(char* str) int RuleId; char c; + + // + // Initialize Scanner + // + InputIdx = 0; + CurrentLine = 0; + CurrentLineIdx = 0; + // // End of File Token // @@ -60,22 +68,17 @@ PSYMBOL_BUFFER ScriptEngineParse(char* str) Push(Stack, EndToken); Push(Stack, StartToken); - InputIdx = 0; - c = sgetc(str); CurrentIn = Scan(str, &c); if (CurrentIn->Type == UNKNOWN) { - char* Message = "Invalid Token!"; - CodeBuffer->Message = (char*)malloc(strlen(Message) + 1); - strcpy(CodeBuffer->Message, Message); + char* Message = HandleError(UNKOWN_TOKEN, str); + CodeBuffer->Message = Message; RemoveTokenList(Stack); RemoveTokenList(MatchedStack); - RemoveToken(StartToken); - RemoveToken(EndToken); RemoveToken(CurrentIn); return CodeBuffer; } @@ -99,9 +102,8 @@ PSYMBOL_BUFFER ScriptEngineParse(char* str) NonTerminalId = GetNonTerminalId(TopToken); if (NonTerminalId == -1) { - char* Message = "Invalid Syntax!"; - CodeBuffer->Message = (char*)malloc(strlen(Message) + 1); - strcpy(CodeBuffer->Message, Message); + char* Message = HandleError(SYNTAX_ERROR, str); + CodeBuffer->Message = Message; RemoveToken(StartToken); RemoveToken(EndToken); @@ -112,9 +114,8 @@ PSYMBOL_BUFFER ScriptEngineParse(char* str) TerminalId = GetTerminalId(CurrentIn); if (TerminalId == -1) { - char* Message = "Invalid Syntax!"; - CodeBuffer->Message = (char*)malloc(strlen(Message) + 1); - strcpy(CodeBuffer->Message, Message); + char* Message = HandleError(SYNTAX_ERROR, str); + CodeBuffer->Message = Message; RemoveToken(StartToken); RemoveToken(EndToken); @@ -125,9 +126,8 @@ PSYMBOL_BUFFER ScriptEngineParse(char* str) RuleId = ParseTable[NonTerminalId][TerminalId]; if (RuleId == -1) { - char* Message = "Invalid Syntax!"; - CodeBuffer->Message = (char*)malloc(strlen(Message) + 1); - strcpy(CodeBuffer->Message, Message); + char* Message = HandleError(SYNTAX_ERROR, str); + CodeBuffer->Message = Message; RemoveToken(StartToken); RemoveToken(EndToken); @@ -159,9 +159,8 @@ PSYMBOL_BUFFER ScriptEngineParse(char* str) if (CurrentIn->Type == UNKNOWN) { - char* Message = "Invalid Token!"; - CodeBuffer->Message = (char*)malloc(strlen(Message) + 1); - strcpy(CodeBuffer->Message, Message); + char* Message = HandleError(UNKOWN_TOKEN, str); + CodeBuffer->Message = Message; RemoveToken(StartToken); RemoveToken(EndToken); @@ -182,9 +181,8 @@ PSYMBOL_BUFFER ScriptEngineParse(char* str) { if (!IsEqual(TopToken, CurrentIn)) { - char* Message = "Invalid Syntax!"; - CodeBuffer->Message = (char*)malloc(strlen(Message) + 1); - strcpy(CodeBuffer->Message, Message); + char* Message = HandleError(SYNTAX_ERROR, str); + CodeBuffer->Message = Message; RemoveToken(StartToken); RemoveToken(EndToken); @@ -199,9 +197,21 @@ PSYMBOL_BUFFER ScriptEngineParse(char* str) RemoveToken(CurrentIn); CurrentIn = Scan(str, &c); - printf("\nCurrent Input :\n"); + if (CurrentIn->Type == UNKNOWN) + { + char* Message = HandleError(SYNTAX_ERROR, str); + CodeBuffer->Message = Message; + + RemoveToken(StartToken); + RemoveToken(EndToken); + RemoveTokenList(MatchedStack); + RemoveToken(CurrentIn); + return CodeBuffer; + } + + /* printf("\nCurrent Input :\n"); PrintToken(CurrentIn); - printf("\n"); + printf("\n");*/ #ifdef _SCRIPT_ENGINE_DBG_EN printf("matched...\n"); @@ -252,8 +262,8 @@ void CodeGen(TOKEN_LIST MatchedStack, PSYMBOL_BUFFER CodeBuffer, TOKEN Operator) PushSymbol(CodeBuffer, Op1Symbol); - printf("%s\t%s,\t%s\n", Operator->Value, Op1->Value, Op0->Value); - printf("_____________\n"); + /* printf("%s\t%s,\t%s\n", Operator->Value, Op1->Value, Op0->Value); + printf("_____________\n");*/ // // Free the operand if it is a temp value @@ -263,8 +273,8 @@ void CodeGen(TOKEN_LIST MatchedStack, PSYMBOL_BUFFER CodeBuffer, TOKEN Operator) } else if (IsType2Func(Operator)) { - printf("%s\t%s\n", Operator->Value, Op0->Value); - printf("_____________\n"); + /* printf("%s\t%s\n", Operator->Value, Op0->Value); + printf("_____________\n");*/ } else if (IsType1Func(Operator)) @@ -273,8 +283,8 @@ void CodeGen(TOKEN_LIST MatchedStack, PSYMBOL_BUFFER CodeBuffer, TOKEN Operator) Push(MatchedStack, Temp); TempSymbol = ToSymbol(Temp); PushSymbol(CodeBuffer, TempSymbol); - printf("%s\t%s,\t%s\n", Operator->Value, Temp->Value, Op0->Value); - printf("_____________\n"); + /* printf("%s\t%s,\t%s\n", Operator->Value, Temp->Value, Op0->Value); + printf("_____________\n");*/ // Free the operand if it is a temp value FreeTemp(Op0); } @@ -292,8 +302,8 @@ void CodeGen(TOKEN_LIST MatchedStack, PSYMBOL_BUFFER CodeBuffer, TOKEN Operator) PushSymbol(CodeBuffer, TempSymbol); - printf("%s\t%s,\t%s,\t%s\n", Operator->Value, Temp->Value, Op0->Value, Op1->Value); - printf("_____________\n"); + /* printf("%s\t%s,\t%s,\t%s\n", Operator->Value, Temp->Value, Op0->Value, Op1->Value); + printf("_____________\n");*/ // Free the operand if it is a temp value FreeTemp(Op0); @@ -303,12 +313,6 @@ void CodeGen(TOKEN_LIST MatchedStack, PSYMBOL_BUFFER CodeBuffer, TOKEN Operator) { // TODO : Handle Error } - - - - - - return; } @@ -555,3 +559,71 @@ unsigned long long int SemanticRuleToInt(char* str) } return INVALID; } +char* HandleError(unsigned int ErrorType, char* str) +{ + + // + // allocate rquired memory for message + // + int MessageSize = (InputIdx - CurrentLineIdx) * 2 + 30 + 100; + char* Message = (char*)malloc(MessageSize); + + // + // add line number + // + strcpy(Message, "Line "); + char* Line = (char*)malloc(16); + sprintf(Line, "%d:\n", CurrentLine); + strcat(Message, Line); + free(Line); + + // + // add the line which error happened at + // + unsigned int LineEnd; + for (int i = InputIdx; ; i++) + { + if (str[i] == '\n' || str[i] == '\0') + { + LineEnd = i; + break; + } + } + + strncat(Message, (str + CurrentLineIdx), LineEnd - CurrentLineIdx); + strcat(Message, "\n"); + + + + printf("CurrenTokenIdx = %d\n", CurrentTokenIdx); + // + // add pointer + // + char Space = ' '; + for (int i = 0; i < (CurrentTokenIdx - CurrentLineIdx); i++) + { + strncat(Message,&Space , 1); + } + strcat(Message, "^\n"); + + // + // add error cause and details + // + switch(ErrorType) + { + case SYNTAX_ERROR: + strcat(Message, "SyntaxError: "); + strcat(Message, "Invalid Syntax"); + return Message; + + case UNKOWN_TOKEN: + strcat(Message, "SyntaxError: "); + strcat(Message, "Unkown Token"); + return Message; + + + default: + strcat(Message, "Unkown Error: "); + return Message; + } +} \ No newline at end of file diff --git a/hyperdbg/script-engine/ScriptEngine.h b/hyperdbg/script-engine/ScriptEngine.h index 42de45d4..a6094558 100644 --- a/hyperdbg/script-engine/ScriptEngine.h +++ b/hyperdbg/script-engine/ScriptEngine.h @@ -11,6 +11,8 @@ */ #pragma once +#ifndef SCRIPT_ENGINE_H +#define SCRIPT_ENGINE_H @@ -19,6 +21,9 @@ #include "scanner.h" #include "common.h" +#define SYNTAX_ERROR 0 +#define UNKOWN_TOKEN 1 + PSYMBOL NewSymbol(void); void RemoveSymbol(PSYMBOL Symbol); @@ -47,4 +52,6 @@ unsigned long long int PseudoRegToInt(char* str); unsigned long long int SemanticRuleToInt(char* str); +char* HandleError(unsigned int ErrorType, char* str); +#endif diff --git a/hyperdbg/script-engine/scanner.c b/hyperdbg/script-engine/scanner.c index dbe6b1e6..25b85024 100644 --- a/hyperdbg/script-engine/scanner.c +++ b/hyperdbg/script-engine/scanner.c @@ -416,7 +416,8 @@ TOKEN Scan(char* str, char* c) while (1) { - + CurrentTokenIdx = InputIdx-1; + Token = GetToken(c, str); // @@ -428,8 +429,17 @@ TOKEN Scan(char* str, char* c) strcpy(Token->Value, "$"); return Token; } - - else if (Token->Type == WHITE_SPACE || Token->Type == COMMENT) + else if (Token->Type == WHITE_SPACE) + { + if (!strcpy(Token->Value, "\n")) + { + CurrentLine++; + CurrentLineIdx = InputIdx; + } + RemoveToken(Token); + continue; + } + else if (Token->Type == COMMENT) { RemoveToken(Token); continue; diff --git a/hyperdbg/script-engine/scanner.h b/hyperdbg/script-engine/scanner.h index 9cd947c3..a8a4995d 100644 --- a/hyperdbg/script-engine/scanner.h +++ b/hyperdbg/script-engine/scanner.h @@ -8,6 +8,22 @@ */ unsigned int InputIdx; +/** +* @brief number of current reading line +*/ +unsigned int CurrentLine; + +/* +* @brief current line start postion +*/ +unsigned int CurrentLineIdx; + +/* +* @brief curren token start postion +*/ +unsigned int CurrentTokenIdx; + + //////////////////////////////////////////////////// // Interfacing functions // ////////////////////////////////////////////////////