// QuoteParser 实现 Quote 语法的解析 func QuoteParser(st p.ParseState) (interface{}, error) { lisp, err := p.Bind_(p.Rune('\''), p.Choice( p.Try(p.Bind(AtomParser, SuffixParser)), p.Bind(ListParser, SuffixParser), ))(st) if err == nil { return Quote{lisp}, nil } return nil, err }
func stop(st p.ParseState) (interface{}, error) { pos := st.Pos() defer st.SeekTo(pos) r, err := p.Choice( p.Try(p.Space), p.Try(p.NewLine), p.Try(p.OneOf(":.()[]{}?")), p.Try(p.Eof), )(st) if err != nil { return nil, err } return r, nil }
func ValueParser(st p.ParseState) (interface{}, error) { value, err := p.Choice(p.Try(StringParser), p.Try(FloatParser), p.Try(IntParser), p.Try(RuneParser), p.Try(StringParser), p.Try(BoolParser), p.Try(NilParser), p.Try(p.Bind(AtomParser, SuffixParser)), p.Try(p.Bind(ListParser, SuffixParser)), p.Try(DotExprParser), QuoteParser, )(st) return value, err }
func ExtTypeParser(env Env) p.Parser { return func(st p.ParseState) (interface{}, error) { _, err := p.String("::")(st) if err != nil { return nil, err } buildin := p.Choice( p.Try(p.Bind_(typeName("bool"), p.Return(BOOL))), p.Try(p.Bind_(typeName("float"), p.Return(FLOAT))), p.Try(p.Bind_(typeName("int"), p.Return(INT))), p.Try(p.Bind_(typeName("string"), p.Return(STRING))), p.Try(p.Bind_(typeName("time"), p.Return(TIME))), p.Try(p.Bind_(typeName("duration"), p.Return(DURATION))), p.Try(p.Bind_(typeName("any"), p.Return(ANY))), p.Try(p.Bind_(typeName("atom"), p.Return(ATOM))), p.Try(p.Bind_(p.String("list"), p.Return(LIST))), p.Try(p.Bind_(typeName("quote"), p.Return(QUOTE))), p.Try(p.Bind_(p.String("dict"), p.Return(DICT))), p.Try(MapTypeParserExt(env)), ) ext := func(st p.ParseState) (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 } else { return nil, st.Trap("var %v is't a type. It is %v", n, reflect.TypeOf(t)) } } t, err := p.Either(buildin, ext)(st) if err != nil { return nil, err } _, err = p.Try(p.Rune('?'))(st) option := err == nil return Type{t.(reflect.Type), option}, nil } }
func TypeParser(st p.ParseState) (interface{}, error) { t, err := p.Bind_(p.String("::"), p.Choice( p.Try(p.Bind_(p.String("bool"), p.Return(BOOL))), p.Try(p.Bind_(p.String("float"), p.Return(FLOAT))), p.Try(p.Bind_(p.String("int"), p.Return(INT))), p.Try(p.Bind_(p.String("string"), p.Return(STRING))), p.Try(p.Bind_(p.String("time"), p.Return(TIME))), p.Try(p.Bind_(p.String("duration"), p.Return(DURATION))), p.Try(p.Bind_(p.String("any"), p.Return(ANY))), p.Try(p.Bind_(p.String("atom"), p.Return(ATOM))), p.Try(p.Bind_(p.String("list"), p.Return(LIST))), p.Try(p.Bind_(p.String("quote"), p.Return(QUOTE))), p.Try(p.Bind_(p.String("dict"), p.Return(DICT))), MapTypeParser, ))(st) if err != nil { return nil, err } _, err = p.Try(p.Rune('?'))(st) option := err == nil return Type{t.(reflect.Type), option}, 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 { return nil, ParsexSignErrorf("Parsec Parser Return Error: only accept one Parsec Parser as arg but %v", args) } param, err := Eval(env, args[0]) if err != nil { return nil, err } return ParsecBox(p.Return(param)), nil }, "option": func(env Env, args ...interface{}) (Lisp, error) { if len(args) != 2 { return nil, ParsexSignErrorf("Parsec Parser Option Error: only accept two Parsec Parser as arg but %v", args) }
package gisp import ( "fmt" p "github.com/Dwarfartisan/goparsec" ) // Bool 是内置的 bool 类型的封装 type Bool bool // BoolParser 解析 bool var BoolParser = p.Bind(p.Choice(p.String("true"), p.String("false")), func(input interface{}) p.Parser { return func(st p.ParseState) (interface{}, error) { switch input.(string) { case "true": return Bool(true), nil case "false": return Bool(false), nil default: return nil, fmt.Errorf("Unexcept bool token %v", input) } } }) // NilParser 解析 nil var NilParser = p.Bind_(p.String("nil"), p.Return(nil)) // Nil 类型定义空值行为 type Nil struct { }