3 回答
TA贡献1818条经验 获得超11个赞
您可以使用regexp.Split()(就像您所做的那样)获取表达式的操作数,并且可以使用regexp.FindAllString().
通过这样做,您将拥有 2 个单独的[]string切片,如果您希望将结果合并为一个切片,则可以合并这 2 个[]string切片。
input := "house-width + 3 - y ^ (5 * house length)"
r := regexp.MustCompile(`\s([+\-/*^])\s`)
s1 := r.Split(input, -1)
s2 := r.FindAllString(input, -1)
fmt.Printf("%q\n", s1)
fmt.Printf("%q\n", s2)
all := make([]string, len(s1)+len(s2))
for i := range s1 {
all[i*2] = s1[i]
if i < len(s2) {
all[i*2+1] = s2[i]
}
}
fmt.Printf("%q\n", all)
输出(在Go Playground上试试):
["house-width" "3" "y" "(5" "house length)"]
[" + " " - " " ^ " " * "]
["house-width" " + " "3" " - " "y" " ^ " "(5" " * " "house length)"]
笔记:
如果要修剪运算符中的空格,可以使用该strings.TrimSpace()函数:
for i, v := range s2 {
all[i*2+1] = strings.TrimSpace(v)
}
fmt.Printf("%q\n", all)
输出:
["house-width" "+" "3" "-" "y" "^" "(5" "*" "house length)"]
TA贡献1876条经验 获得超5个赞
如果您打算在之后解析表达式,则必须进行一些更改:
包括括号作为词素
你不能让空格和破折号都是有效的标识符字符,因为例如在两者- y之间3并且^将是一个有效的标识符。
完成后,您可以使用简单的线性迭代来对字符串进行词法分析:
package main
import (
"bytes"
"fmt"
)
func main() {
input := `house width + 3 - y ^ (5 * house length)`
buffr := bytes.NewBuffer(nil)
outpt := make([]string, 0)
for _, r := range input {
if r == '+' || r == '-' || r == '*' || r == '/' || r == '^' || r == '(' || r == ')' || (r >= '0' && r <= '9') {
bs := bytes.TrimSpace(buffr.Bytes())
if len(bs) > 0 {
outpt = append(outpt, (string)(bs))
}
outpt = append(outpt, (string)(r))
buffr.Reset()
} else {
buffr.WriteRune(r)
}
}
fmt.Printf("%#v\n", outpt)
}
词法分析后,使用 Dijkstra 的分流码算法构建 AST 或直接评估表达式。
- 3 回答
- 0 关注
- 197 浏览
添加回答
举报