From 61681f9a71b39e2bc3c4e100858afb982512fefa Mon Sep 17 00:00:00 2001 From: Sourr_cream Date: Tue, 13 Feb 2024 21:48:09 +0300 Subject: [PATCH] second version of parser --- backend/handlers/handler_expression.go | 10 ++- backend/pkg/orchestrator/parser.go | 106 ++++++++++++++++++++++--- 2 files changed, 104 insertions(+), 12 deletions(-) diff --git a/backend/handlers/handler_expression.go b/backend/handlers/handler_expression.go index 2d35297..7bbd76a 100644 --- a/backend/handlers/handler_expression.go +++ b/backend/handlers/handler_expression.go @@ -3,6 +3,7 @@ package handlers import ( "Prrromanssss/DAEE/config" "Prrromanssss/DAEE/internal/database" + "Prrromanssss/DAEE/pkg/orchestrator" "encoding/json" "fmt" "net/http" @@ -24,13 +25,20 @@ func HandlerCreateExpression(w http.ResponseWriter, r *http.Request, apiCfg *con respondWithError(w, 400, fmt.Sprintf("Error parsing JSON: %v", err)) } + parseData, err := orchestrator.ParseExpression(params.Data) + + if err != nil { + respondWithError(w, 400, fmt.Sprintf("Error parsing expression: %v", err)) + return + } + expression, err := apiCfg.DB.CreateExpression(r.Context(), database.CreateExpressionParams{ ID: uuid.New(), CreatedAt: time.Now().UTC(), UpdatedAt: time.Now().UTC(), Data: params.Data, - ParseData: "", + ParseData: parseData, Status: "ready for computation", }) diff --git a/backend/pkg/orchestrator/parser.go b/backend/pkg/orchestrator/parser.go index 07c814e..b038d45 100644 --- a/backend/pkg/orchestrator/parser.go +++ b/backend/pkg/orchestrator/parser.go @@ -2,19 +2,29 @@ package orchestrator import ( "errors" + "fmt" + "strconv" "strings" "unicode" ) -func InfixToPostfix(expression string) (string, error) { - var output strings.Builder - var stack []rune +func ParseExpression(expression string) (string, error) { rawExpression := strings.ReplaceAll(expression, " ", "") if !isValidExpression(rawExpression) { return "", errors.New("invalid expression") } + rawExpression = addBrackets(rawExpression) + result, err := infixToPostfix(rawExpression) + if err != nil { + return "", err + } + return result, nil +} - for _, char := range rawExpression { +func infixToPostfix(expression string) (string, error) { + var output strings.Builder + var stack []rune + for _, char := range expression { switch char { case '(': stack = append(stack, char) @@ -39,7 +49,7 @@ func InfixToPostfix(expression string) (string, error) { return strings.ReplaceAll(strings.TrimSpace(output.String()), " ", " "), nil } -func Contains(arr []rune, element rune) bool { +func contains(arr []rune, element rune) bool { for _, elem := range arr { if elem == element { return true @@ -64,15 +74,15 @@ func isValidExpression(expression string) bool { if i == 0 { return false } - if Contains([]rune{'+', '-', '*', '/', '(', ' '}, rune(expression[i-1])) { + if contains([]rune{'+', '-', '*', '/', '(', ' '}, rune(expression[i-1])) { return false } case '-', '+': if i == 0 || i == 1 || expression[i-1] == '(' { continue } - if Contains([]rune{'+', '-', '*', '/', ' '}, rune(expression[i-1])) && - Contains([]rune{'+', '-', '*', '/', '(', ' '}, rune(expression[i-2])) { + if contains([]rune{'+', '-', '*', '/', ' '}, rune(expression[i-1])) && + contains([]rune{'+', '-', '*', '/', '(', ' '}, rune(expression[i-2])) { return false } @@ -86,9 +96,83 @@ func isValidExpression(expression string) bool { return len(stack) == 0 } -// func addBrackets(expression string) string { -// return expression -// } +func replaceUnaryPlusAndMinus(expression string) string { + var result strings.Builder + + length := len(expression) + ind := 0 + for ind < length { + if ind+1 < length && contains([]rune{'+', '-', '*', '/'}, rune(expression[ind])) && expression[ind+1] == '+' { + result.WriteRune(rune(expression[ind])) + result.WriteRune('&') + ind++ + } else if ind == 0 && expression[ind] == '+' { + result.WriteRune('&') + } else if ind+1 < length && contains([]rune{'+', '-', '*', '/'}, rune(expression[ind])) && expression[ind+1] == '-' { + result.WriteRune(rune(expression[ind])) + result.WriteRune('$') + ind++ + } else if ind == 0 && expression[ind] == '-' { + result.WriteRune('$') + } else { + result.WriteRune(rune(expression[ind])) + } + ind++ + } + return result.String() +} + +func orderPlusMinus(expression string) []rune { + res := make([]rune, 0) + for _, char := range expression { + if char == '-' || char == '+' { + res = append(res, char) + } + } + return res +} + +func isNumber(s string) bool { + _, err := strconv.ParseFloat(s, 64) + return err == nil || s[0] == '$' || s[0] == '&' +} + +func addBrackets(expression string) string { + var result string + + parts := strings.FieldsFunc(replaceUnaryPlusAndMinus(expression), func(r rune) bool { + return r == '+' || r == '-' + }) + fmt.Println(parts) + length := len(parts) + sliceOfOrdersPlusMinus := orderPlusMinus(replaceUnaryPlusAndMinus(expression)) + var ind, indForOrdersPlusMinus int + if len(parts) < 2 { + return expression + } + for ind < length { + if ind == 0 && isNumber(parts[ind]) && isNumber(parts[ind+1]) { + result += "(" + parts[ind] + string(sliceOfOrdersPlusMinus[indForOrdersPlusMinus]) + parts[ind+1] + ")" + indForOrdersPlusMinus++ + ind++ + } else if ind == 0 && ((isNumber(parts[ind]) && !isNumber(parts[ind+1])) || !isNumber(parts[ind])) { + result += parts[ind] + } else if ind+1 < length && isNumber(parts[ind]) && isNumber(parts[ind+1]) { + result += string(sliceOfOrdersPlusMinus[indForOrdersPlusMinus]) + "(" + parts[ind] + indForOrdersPlusMinus++ + result += string(sliceOfOrdersPlusMinus[indForOrdersPlusMinus]) + parts[ind+1] + ")" + indForOrdersPlusMinus++ + ind++ + } else { + result += string(sliceOfOrdersPlusMinus[indForOrdersPlusMinus]) + parts[ind] + indForOrdersPlusMinus++ + } + ind++ + } + result = strings.ReplaceAll(result, "&", "+") + result = strings.ReplaceAll(result, "$", "-") + return result +} func popUntilOpeningParenthesis(stack *[]rune, output *strings.Builder) error { for len(*stack) > 0 && (*stack)[len(*stack)-1] != '(' {