// divx 实现一个左折叠的 parsex 连除解析器,精度向上适配。 func divx(st px.ParsexState) (interface{}, error) { data, err := px.Try(px.ManyTil(IntValue, px.Eof))(st) if err == nil { ints := data.([]interface{}) root := ints[0].(Int) for _, x := range ints[1:] { root /= x.(Int) } return root, nil } data, err = px.ManyTil(NumberValue, px.Eof)(st) if err == nil { numbers := data.([]interface{}) root := numbers[0].(Float) for _, x := range numbers[1:] { root /= x.(Float) } return root, nil } if nerr, ok := err.(NotNumberError); ok { return nil, TypeSignError{Type: Type{FLOAT, false}, Value: nerr.Value} } return nil, err }
// addx 实现一个parsex累加解析器,精度向上适配。我一直觉得应该有一个简单的高效版本,不需要回溯的 // 但是目前还没有找到。 func addx(st px.ParsexState) (interface{}, error) { ints, err := px.Try(px.ManyTil(IntValue, px.Eof))(st) if err == nil { root := Int(0) for _, x := range ints.([]interface{}) { root += x.(Int) } return root, nil } numbers, err := px.ManyTil(NumberValue, px.Eof)(st) if err == nil { root := Float(0) for _, x := range numbers.([]interface{}) { root += x.(Float) } return root, nil } if nerr, ok := err.(NotNumberError); ok { return nil, TypeSignError{Type: FLOATMUST, Value: nerr.Value} } return nil, err }
"Try Arg Error:except 1 parser arg but %v.", reflect.TypeOf(param)) } }, "either": func(env Env, args ...interface{}) (Lisp, error) { ptype := reflect.TypeOf((px.Parser)(nil)) params, err := GetArgs(env, px.UnionAll(TypeAs(ptype), TypeAs(ptype), px.Eof), args) if err != nil { return nil, err } return ParsecBox(p.Either(params[0].(Parsecer).Parser, params[1].(Parsecer).Parser)), nil }, "choice": func(env Env, args ...interface{}) (Lisp, error) { ptype := reflect.TypeOf((px.Parser)(nil)) params, err := GetArgs(env, px.ManyTil(TypeAs(ptype), px.Eof), args) if err != nil { return nil, err } parsers := make([]p.Parser, len(params)) for idx, prs := range params { if parser, ok := prs.(Parsecer); ok { parsers[idx] = parser.Parser } return nil, ParsexSignErrorf("Choice Args Error:except parsec parsers but %v is %v", prs, reflect.TypeOf(prs)) } return ParsecBox(p.Choice(parsers...)), nil }, "return": func(env Env, args ...interface{}) (Lisp, error) { if len(args) != 1 {
"Try Arg Error:except 1 parser arg but %v.", reflect.TypeOf(param)) } }, "either": func(env Env, args ...interface{}) (Lisp, error) { ptype := reflect.TypeOf((px.Parser)(nil)) params, err := GetArgs(env, px.UnionAll(TypeAs(ptype), TypeAs(ptype), px.Eof), args) if err != nil { return nil, err } return ParsexBox(px.Either(params[0].(Parsexer).Parser, params[1].(Parsexer).Parser)), nil }, "choice": func(env Env, args ...interface{}) (Lisp, error) { ptype := reflect.TypeOf((px.Parser)(nil)) params, err := GetArgs(env, px.ManyTil(TypeAs(ptype), px.Eof), args) if err != nil { return nil, err } parsers := make([]px.Parser, len(params)) for idx, prs := range params { if parser, ok := prs.(Parsexer); ok { parsers[idx] = parser.Parser } return nil, ParsexSignErrorf("Choice Args Error:except parsec parsers but %v is %v", prs, reflect.TypeOf(prs)) } return ParsexBox(px.Choice(parsers...)), nil }, "return": func(env Env, args ...interface{}) (Lisp, error) { if len(args) != 1 {