Skip to content

Commit

Permalink
second version of parser
Browse files Browse the repository at this point in the history
  • Loading branch information
Prrromanssss committed Feb 13, 2024
1 parent 92823b9 commit 61681f9
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 12 deletions.
10 changes: 9 additions & 1 deletion backend/handlers/handler_expression.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package handlers
import (
"Prrromanssss/DAEE/config"
"Prrromanssss/DAEE/internal/database"
"Prrromanssss/DAEE/pkg/orchestrator"
"encoding/json"
"fmt"
"net/http"
Expand All @@ -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",
})

Expand Down
106 changes: 95 additions & 11 deletions backend/pkg/orchestrator/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand All @@ -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
}

Expand All @@ -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] != '(' {
Expand Down

0 comments on commit 61681f9

Please sign in to comment.