// divx 实现一个左折叠的 parsec 连除解析器,精度向上适配。 func divx(st p.State) (interface{}, error) { data, err := p.Try(p.Many(IntValue).Over(p.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 = p.Many(NumberValue).Over(p.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 }
func (lambda *Lambda) prepareArgs(args List) { l := len(args) formals := make(List, len(args)) if l == 0 { lambda.Meta["parameters parsex"] = []Var{} return } lidx := l - 1 last := args[lidx].(Atom) // variadic function args formal as (last[::Type] ... ) isVariadic := false if last.Name == "..." && len(args) > 1 { isVariadic = true } lambda.Meta["is variadic"] = isVariadic ps := make([]p.P, l+1) for idx, arg := range args[:lidx] { ps[idx] = argParser(arg.(Atom)) formals[idx] = arg } if isVariadic { varArg := args[l-2].(Atom) ps[lidx] = p.Many(argParser(last)) larg := Atom{varArg.Name, varArg.Type} formals[lidx] = larg } else { ps[lidx] = argParser(last) formals[lidx] = last } ps[l] = p.EOF lambda.Meta["formal parameters"] = formals lambda.Meta["parameter parsexs"] = ps }
// ObjectParser 实现数组解析器 func ObjectParser() p.P { return func(st p.State) (interface{}, error) { left := p.Chr('{').Then(Skip) right := Skip.Then(p.Chr('}')) empty := p.Between(left, right, Skip) object, err := p.Between(left, right, p.Many(p.Choice(objectBodyParser, p.NChr('}'))))(st) if err != nil { _, e := empty(st) if e != nil { return nil, err } return Object{}, nil } switch o := object.(type) { case Object: return O(o), nil case map[string]interface{}: return object.(map[string]interface{}), nil default: return nil, fmt.Errorf("Object Parser Error: %v type is unexpected: %v", object, reflect.TypeOf(object)) } } }
// ListParser 实现数组解析器 func ListParser() p.P { return func(st p.State) (interface{}, error) { left := p.Chr('[').Then(Skip) right := Skip.Then(p.Chr(']')) empty := p.Between(left, right, Skip) list, err := p.Between(left, right, p.Many(p.Choice(p.NChr(']'), listBodyParser)))(st) fmt.Printf("list type :%v, value :%v, err: %v\n", reflect.TypeOf(list), list, err) if err != nil { _, e := empty(st) if e != nil { return nil, err } return List{}, nil } switch l := list.(type) { case List: return L(l), nil case []interface{}: return list.([]interface{}), nil default: return nil, fmt.Errorf("List Parser Error: %v type is unexpected: %v", list, reflect.TypeOf(list)) } } }
// addx 实现一个parsex累加解析器,精度向上适配。我一直觉得应该有一个简单的高效版本,不需要回溯的 // 但是目前还没有找到。 func addx(st p.State) (interface{}, error) { ints, err := p.Try(p.Many(IntValue).Over(p.EOF))(st) if err == nil { root := Int(0) for _, x := range ints.([]interface{}) { root += x.(Int) } return root, nil } numbers, err := p.Many(NumberValue).Over(p.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 }
// argParser 构造一个 parsec 解析器,判断输入数据是否与给定类型一致,如果判断成功,构造对应的 // Var。 func argParser(atom Atom) p.P { one := func(st p.State) (interface{}, error) { var err error if data, err := st.Next(); err == nil { if _, err := typeis(atom)(st.Pos(), data); err == nil { slot := VarSlot(atom.Type) slot.Set(data) return slot, nil } } return nil, err } if atom.Name == "..." { return p.Many(one) } return one }
func bodyParserExt(env Env) p.P { return p.Many(ValueParserExt(env).Over(Skip)) }
default: panic(st.Trap("Unknown escape sequence \\%c", r)) } }) // RuneParser 实现 rune 的解析 var RuneParser = p.Do(func(state p.State) interface{} { p.Chr('\'').Exec(state) c := p.Choice(p.Try(EscapeCharr), p.NChr('\'')).Exec(state) p.Chr('\'').Exec(state) return Rune(c.(rune)) }) // StringParser 实现字符串解析 var StringParser = p.Between(p.Chr('"'), p.Chr('"'), p.Many(p.Choice(p.Try(EscapeChars), p.NChr('"')))).Bind(p.ReturnString) func bodyParser(st p.State) (interface{}, error) { value, err := p.SepBy(ValueParser(), Skip)(st) return value, err } func bodyParserExt(env Env) p.P { return p.Many(ValueParserExt(env).Over(Skip)) } // ListParser 实现列表解析器 func ListParser() p.P { return func(st p.State) (interface{}, error) { left := p.Chr('(').Then(Skip) right := Skip.Then(p.Chr(')'))
"Try Arg Error:expect 1 parser arg but %v.", reflect.TypeOf(param)) } }, "either": func(env Env, args ...interface{}) (Lisp, error) { ptype := reflect.TypeOf((p.P)(nil)) params, err := GetArgs(env, p.UnionAll(TypeAs(ptype), TypeAs(ptype), p.EOF), args) if err != nil { return nil, err } return ParsecBox(p.Choice(params[0].(Parsecer).Parser, params[1].(Parsecer).Parser)), nil }, "choice": func(env Env, args ...interface{}) (Lisp, error) { ptype := reflect.TypeOf((p.P)(nil)) params, err := GetArgs(env, p.Many(TypeAs(ptype)).Over(p.EOF), args) if err != nil { return nil, err } parsers := make([]p.P, len(params)) for idx, prs := range params { if parser, ok := prs.(Parsecer); ok { parsers[idx] = parser.Parser } return nil, fmt.Errorf("Choice Args Error:expect 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 {