// SliceTypeParserExt 定义了带环境的序列类型解析逻辑 func SliceTypeParserExt(env Env) p.P { return func(st p.State) (interface{}, error) { t, err := p.Str("[]").Then(ExtTypeParser(env))(st) if err != nil { return nil, err } return reflect.SliceOf(t.(Type).Type), nil } }
// ExtTypeParser 定义了带环境的类型解释器 func ExtTypeParser(env Env) p.P { return func(st p.State) (interface{}, error) { _, err := p.Str("::")(st) if err != nil { return nil, err } builtin := p.Choice( p.Try(typeName("bool").Then(p.Return(BOOL))), p.Try(typeName("float").Then(p.Return(FLOAT))), p.Try(typeName("int").Then(p.Return(INT))), p.Try(typeName("string").Then(p.Return(STRING))), p.Try(typeName("time").Then(p.Return(TIME))), p.Try(typeName("duration").Then(p.Return(DURATION))), p.Try(typeName("any").Then(p.Return(ANY))), p.Try(typeName("atom").Then(p.Return(ATOM))), p.Try(p.Str("list").Then(p.Return(LIST))), p.Try(typeName("quote").Then(p.Return(QUOTE))), p.Try(p.Str("dict").Then(p.Return(DICT))), p.Try(MapTypeParserExt(env)), ) ext := func(st p.State) (interface{}, error) { n, err := anyType(st) if err != nil { return nil, err } t, ok := env.Lookup(n.(string)) if !ok { return nil, st.Trap("type %v not found", n) } if typ, ok := t.(reflect.Type); ok { return typ, nil } return nil, st.Trap("var %v is't a type. It is %v", n, reflect.TypeOf(t)) } t, err := p.Choice(builtin, ext)(st) if err != nil { return nil, err } _, err = p.Try(p.Chr('?'))(st) option := err == nil return Type{t.(reflect.Type), option}, nil } }
// MapTypeParser 定义了序列类型解析逻辑 func MapTypeParser(st p.State) (interface{}, error) { key, err := p.Between(p.Str("map["), p.Chr(']'), TypeParser)(st) if err != nil { return nil, err } value, err := TypeParser(st) if err != nil { return nil, err } return reflect.MapOf(key.(Type).Type, value.(Type).Type), nil }
// MapTypeParserExt 定义了带环境的映射类型解析逻辑 func MapTypeParserExt(env Env) p.P { return func(st p.State) (interface{}, error) { key, err := p.Between(p.Str("map["), p.Chr(']'), ExtTypeParser(env))(st) if err != nil { return nil, err } value, err := ExtTypeParser(env)(st) if err != nil { return nil, err } return reflect.MapOf(key.(Type).Type, value.(Type).Type), nil } }
func typeName(word string) p.P { return p.Str(word).Bind(stopWord) }
// TypeParser 定义了一个基本的类型解释器 func TypeParser(st p.State) (interface{}, error) { t, err := p.Str("::").Then( p.Choice( p.Try(p.Str("bool").Then(p.Return(BOOL))), p.Try(p.Str("float").Then(p.Return(FLOAT))), p.Try(p.Str("int").Then(p.Return(INT))), p.Try(p.Str("string").Then(p.Return(STRING))), p.Try(p.Str("time").Then(p.Return(TIME))), p.Try(p.Str("duration").Then(p.Return(DURATION))), p.Try(p.Str("any").Then(p.Return(ANY))), p.Try(p.Str("atom").Then(p.Return(ATOM))), p.Try(p.Str("list").Then(p.Return(LIST))), p.Try(p.Str("quote").Then(p.Return(QUOTE))), p.Try(p.Str("dict").Then(p.Return(DICT))), MapTypeParser, ))(st) if err != nil { return nil, err } _, err = p.Try(p.Chr('?'))(st) option := err == nil return Type{t.(reflect.Type), option}, nil }
} param, err := Eval(env, args[0]) if err != nil { return nil, err } return ParsecBox(p.Eq(param)), nil }, "str": func(env Env, args ...interface{}) (Lisp, error) { if len(args) != 1 { return nil, fmt.Errorf("One Arg Error:expect args has 1 arg") } param, err := Eval(env, args[0]) if err != nil { return nil, err } return ParsecBox(p.Str(param.(string))), nil }, "rune": func(env Env, args ...interface{}) (Lisp, error) { if len(args) != 1 { return nil, fmt.Errorf("Rune Arg Error:expect args has 1 arg") } param, err := Eval(env, args[0]) if err != nil { return nil, err } return ParsecBox(p.Chr(rune(param.(Rune)))), nil }, "asint": ParsecBox(p.AsInt), "asfloat": ParsecBox(p.AsFloat64), "asstr": ParsecBox(p.AsString), "string": func(env Env, args ...interface{}) (Lisp, error) {
package pjson import ( "fmt" p "github.com/Dwarfartisan/goparsec2" ) // Bool 是内置的 bool 类型 type Bool bool // BoolParser 解析 bool // BoolParser 解析 bool var BoolParser = p.Choice(p.Str("true"), p.Str("false")).Bind(func(input interface{}) p.P { return func(st p.State) (interface{}, error) { switch input.(string) { case "true": return Bool(true), nil case "false": return Bool(false), nil default: return nil, fmt.Errorf("Unexpect bool token %v", input) } } }) // var BoolParser = p.Do(func(st p.State) interface{} { // f := p.Try(p.Bool).Exec(st) // switch f.(string) { // case "true": // return Bool(true), nil
package pjson import ( "fmt" "reflect" p "github.com/Dwarfartisan/goparsec2" ) // Skip 忽略匹配指定算子的内容 var Skip = p.Skip(p.Space) // Comma 逗号分隔符 var Comma = p.Str(",") // Colon 冒号分隔符 var Colon = p.Str(":") func listBodyParser(st p.State) (interface{}, error) { value, err := p.SepBy(ValueParser(), Skip.Then(Comma).Then(Skip))(st) return value, err } // 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.UnionAll(listBodyParser))(st)
package pjson import ( "fmt" "reflect" p "github.com/Dwarfartisan/goparsec2" ) // Skip 忽略匹配指定算子的内容 var Skip = p.Skip(p.Space) // Comma 逗号分隔符 var Comma = p.Skip(p.Str(",")) // Colon 冒号分隔符 var Colon = p.Skip(p.Str(":")) func listBodyParser(st p.State) (interface{}, error) { value, err := p.SepBy1(ValueParser(), Comma)(st) fmt.Printf("type :%v, value :%v, err :%v\n", reflect.TypeOf(value), value, err) return value, err } // 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)