代码拉取完成,页面将自动刷新
parserc-go是用golang实现的解析器组合子(Parser Combinator)库,可以方便地以自底向上的方式构建复杂的解析器。
package main
import (
"fmt"
. "parserc-go/parserc"
"strconv"
)
func toString(v any) any {
switch v.(type) {
case rune:
return fmt.Sprintf("%c", v)
default:
return fmt.Sprintf("%s", v)
}
}
func join(list any) any {
s := ""
for _, e := range list.([]any) {
s += toString(e).(string)
}
return s
}
func toFloat(a any) any {
v, _ := strconv.ParseFloat(a.(string), 64)
return v
}
func calc(p any) any {
v := p.(Pair).First.(float64)
for _, e := range p.(Pair).Second.([]any) {
switch e.(Pair).First.(string) {
case "+":
v += e.(Pair).Second.(float64)
case "-":
v -= e.(Pair).Second.(float64)
case "*":
v *= e.(Pair).Second.(float64)
case "/":
v /= e.(Pair).Second.(float64)
}
}
return v
}
var (
w = Chs(' ', '\t', '\n', '\r')
ws = w.Many()
digit = Range('0', '9').Map(toString)
digits = digit.Many1().Map(join)
integer = digits.Map(toFloat).Surround(ws)
decimal = Seq(digits, Ch('.'), digits).Map(join).Map(toFloat).Surround(ws)
add = Str("+").Surround(ws)
sub = Str("-").Surround(ws)
mul = Str("*").Surround(ws)
div = Str("/").Surround(ws)
lp = Str("(").Surround(ws)
rp = Str(")").Surround(ws)
expr = NewParser()
bracketExpr = Skip(lp).And(expr).Skip(rp)
fact = OneOf(decimal, integer, bracketExpr)
term = fact.And(mul.Or(div).And(fact).Many()).Map(calc)
)
func init() {
expr.Set(term.And(add.Or(sub).And(term).Many()).Map(calc))
}
func eval(s string) float64 {
r, err := expr.ParseToEnd(s)
if err != nil {
panic(err)
}
return r.(float64)
}
func main() {
fmt.Println(eval("77.58* ( 6 / 3.14+55.2234 ) -2 * 6.1/ ( 1.0+2/ (4.0-3.8*5))"))
}
package main
import (
"fmt"
. "parserc-go/parserc"
"strconv"
)
func toString(v any) any {
switch v.(type) {
case rune:
return fmt.Sprintf("%c", v)
default:
return fmt.Sprintf("%s", v)
}
}
func join(list any) any {
s := ""
for _, e := range list.([]any) {
s += toString(e).(string)
}
return s
}
func toInt(s any) any {
v, _ := strconv.Atoi(s.(string))
return v
}
func toFloat(a any) any {
v, _ := strconv.ParseFloat(a.(string), 64)
return v
}
func toBool(a any) any {
r, _ := strconv.ParseBool(a.(string))
return r
}
func buildObj(ps any) any {
m := map[string]any{}
for _, p := range ps.([]any) {
m[p.(Pair).First.(string)] = p.(Pair).Second
}
return m
}
var (
w = Chs(' ', '\t', '\n', '\r')
ws = w.Many()
digit = Range('0', '9').Map(toString)
digits = digit.Many1().Map(join)
integer = digits.Map(toInt).Surround(ws)
decimal = Seq(digits, Ch('.'), digits).Surround(ws).Map(join).Map(toFloat)
str = Skip(Ch('"')).And(Not('"').Many()).Skip(Ch('"')).Map(join).Surround(ws)
boolean = Str("true").Or(Str("false")).Map(toBool).Surround(ws)
objStart = Ch('{').Surround(ws)
objEnd = Ch('}').Surround(ws)
arrStart = Ch('[').Surround(ws)
arrEnd = Ch(']').Surround(ws)
colon = Ch(':').Surround(ws)
comma = Ch(',').Surround(ws)
jsonObj = NewParser()
arr = Skip(arrStart).And(Separate(comma, jsonObj).Opt([]any{})).Skip(arrEnd)
pair = str.Skip(colon).And(jsonObj)
obj = Skip(objStart).And(Separate(comma, pair).Opt([]any{})).Skip(objEnd).Map(buildObj)
)
func init() {
jsonObj.Set(OneOf(decimal, integer, str, boolean, arr, obj))
}
func parse(s string) any {
r, err := jsonObj.ParseToEnd(s)
if err != nil {
panic(err)
}
return r
}
func main() {
fmt.Println(parse(`
{
"a": 123,
"b": 3.14,
"c": "hello",
"d": {
"x": 100,
"y": "world!"
},
"e": [
12,
34.56,
{
"name": "Xiao Ming",
"age": 18,
"score": [99.8, 87.5, 60.0]
},
"abc"
],
"f": [],
"g": {},
"h": [true, {"m": false}]
}`))
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。