From 073728e7500d235860b1b547b73b96493d51c49e Mon Sep 17 00:00:00 2001 From: NunoSempere Date: Sat, 11 May 2024 11:08:03 +0100 Subject: [PATCH] rationalize parser --- f.go | 138 ++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 85 insertions(+), 53 deletions(-) diff --git a/f.go b/f.go index 645208d..a0943c3 100644 --- a/f.go +++ b/f.go @@ -41,8 +41,6 @@ func combineBounds(old_low, old_high, new_low, new_high float64) (float64, float } func main() { - var old_low, old_high float64 - reader := bufio.NewReader(os.Stdin) input, _ := reader.ReadString('\n') input = strings.TrimSpace(input) @@ -58,80 +56,114 @@ func main() { fmt.Println(error_msg_start) return } - fmt.Printf("=> %.1f %.1f\n", old_low, old_high) - error_msg_cont := "Please enter two floats separated by a space, like: 1 10, or two floats preceded by a division, like: / 2 20. Or enter i to get the logmean and logstd" + error_msg_cont := "Valid inputs: 2 || * 2 || / 2 || 2 20 || * 2 20 || / 2 20 || i || e" EventForLoop: for { - var new_low, new_high float64 - var err1, err2 error input, _ = reader.ReadString('\n') if strings.TrimSpace(input) == "" { continue EventForLoop } tokens := strings.Split(strings.TrimSpace(input), " ") - switch len(tokens) { - case 0: - continue EventForLoop - case 1: - single_float, err1 := strconv.ParseFloat(tokens[0], 64) - switch { - case tokens[0] == "i": - fmt.Printf("=> %.1f %.1f\n", old_low, old_high) - logmean_old, logstd_old := boundsToLogParams(old_low, old_high) - fmt.Printf("=> Lognormal, with logmean: %.1f, logstd: %.1f\n", logmean_old, logstd_old) - continue EventForLoop - case err1 != nil: - new_low = single_float - new_high = single_float - default: + var new_low, new_high float64 + var err1, err2 error + err1, err2 = nil, nil + + switch tokens[0] { + case "*": + switch len(tokens) { + case 1: + fmt.Println("Can't multiply by nothing") fmt.Println(error_msg_cont) continue EventForLoop - } - case 2: - new_low, err1 = strconv.ParseFloat(tokens[0], 64) - new_high, err2 = strconv.ParseFloat(tokens[1], 64) - if err2 != nil { - fmt.Println(error_msg_cont) - continue EventForLoop - } - switch tokens[0] { - case "*": - new_low = new_high - case "/": - new_low = 1.0 / new_high - new_high = new_low - default: + case 2: + single_float, err1 := strconv.ParseFloat(tokens[1], 64) if err1 != nil { + fmt.Println("Trying to multiply by a scalar, but scalar is not a float") fmt.Println(error_msg_cont) continue EventForLoop } - } - case 3: - new_low, err1 = strconv.ParseFloat(tokens[1], 64) - new_high, err2 = strconv.ParseFloat(tokens[2], 64) - if err1 != nil || err2 != nil { - fmt.Println(error_msg_cont) - continue EventForLoop - } - switch tokens[0] { - case "*": - case "/": - tmp_low := new_low - new_low = 1.0 / new_high - new_high = 1.0 / tmp_low + new_low = single_float + new_high = single_float + case 3: + new_low, err1 = strconv.ParseFloat(tokens[1], 64) + new_high, err2 = strconv.ParseFloat(tokens[2], 64) + if err1 != nil || err2 != nil { + fmt.Println(error_msg_cont) + fmt.Println("Trying to multiply by a distribution, but distribution is not specified as two floats") + continue EventForLoop + } default: + fmt.Println("Trying to multiply by something, but this something is neither a scalar nor a distribution") fmt.Println(error_msg_cont) continue EventForLoop } + case "/": + switch len(tokens) { + case 1: + fmt.Println("Can't divide by nothing") + fmt.Println(error_msg_cont) + continue EventForLoop + case 2: + single_float, err1 := strconv.ParseFloat(tokens[0], 64) + if err1 != nil { + fmt.Println("Trying to divide by a scalar, but scalar is not a float") + fmt.Println(error_msg_cont) + continue EventForLoop + } + new_low = 1.0 / single_float + new_high = 1.0 / single_float + case 3: + new_low, err1 = strconv.ParseFloat(tokens[1], 64) + new_high, err2 = strconv.ParseFloat(tokens[2], 64) + if err1 != nil || err2 != nil { + fmt.Println("Trying to divide by a distribution, but distribution is not specified as two floats") + fmt.Println(error_msg_cont) + continue EventForLoop + } + default: + fmt.Println("Trying to divide by something, but this something is neither a scalar nor a distribution") + } default: - fmt.Println(error_msg_cont) - continue EventForLoop + switch len(tokens) { + case 0: + continue EventForLoop + case 1: + switch tokens[0] { + case "i": + fmt.Printf("=> %.1f %.1f\n", old_low, old_high) + logmean_old, logstd_old := boundsToLogParams(old_low, old_high) + fmt.Printf("=> Lognormal, with logmean: %.1f, logstd: %.1f\n", logmean_old, logstd_old) + continue EventForLoop + case "e": + break EventForLoop + default: + single_float, err1 := strconv.ParseFloat(tokens[0], 64) + if err1 != nil { + fmt.Println("Trying to multiply by a scalar, but scalar is not a float") + fmt.Println(error_msg_cont) + continue EventForLoop + } + new_low = single_float + new_high = single_float + } + case 2: + new_low, err1 = strconv.ParseFloat(tokens[0], 64) + new_high, err2 = strconv.ParseFloat(tokens[1], 64) + if err1 != nil || err2 != nil { + fmt.Println("Trying to multiply by a distribution, but distribution is not specified as two floats") + fmt.Println(error_msg_cont) + continue EventForLoop + } + default: + fmt.Println("No operation takes more than 3 words") + fmt.Println(error_msg_cont) + continue EventForLoop + } } - // Use the abstracted function for combining floats old_low, old_high = combineBounds(old_low, old_high, new_low, new_high) fmt.Printf("=> %.1f %.1f\n", old_low, old_high) }