func ListParserExt(env Env) p.Parser { left := p.Bind_(p.Rune('('), Skip) right := p.Bind_(Skip, p.Rune(')')) empty := p.Between(left, right, Skip) return func(st p.ParseState) (interface{}, error) { list, err := p.Between(left, right, bodyParserExt(env))(st) if err == nil { switch l := list.(type) { case List: return L(l), nil case []interface{}: return List(l), nil default: return nil, fmt.Errorf("List Parser(ext) Error: %v type is unexcepted: %v", list, reflect.TypeOf(list)) } } else { _, e := empty(st) if e == nil { return List{}, nil } else { return nil, err } } } }
// DotParser 定义了从文本中解析出 Dot 表达式的 Parser func DotParser(st p.ParseState) (interface{}, error) { name, err := p.Bind_(p.Rune('.'), atomNameParser)(st) if err != nil { return nil, err } return AA(name.(string)), nil }
func bodyParserExt(env Env) p.Parser { return func(st p.ParseState) (interface{}, error) { value, err := p.Many(p.Bind(ValueParserExt(env), func(x interface{}) p.Parser { return p.Bind_(Skip, p.Return(x)) }))(st) return value, err } }
func TestIntParser3(t *testing.T) { data := "3.14" st := p.MemoryParseState(data) o, err := p.Bind_(IntParser, p.Eof)(st) if err == nil { t.Fatalf("except a Float parse error but got %v", o) } }
func SliceTypeParserExt(env Env) p.Parser { return func(st p.ParseState) (interface{}, error) { t, err := p.Bind_(p.String("[]"), ExtTypeParser(env))(st) if err != nil { return nil, err } return reflect.SliceOf(t.(Type).Type), nil } }
// 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 atomNameParser(st p.ParseState) (interface{}, error) { ret, err := p.Bind(p.Many1(p.NoneOf("'[]() \t\r\n\".:")), p.ReturnString)(st) if err != nil { return nil, err } test := p.MemoryParseState(ret.(string)) _, err = p.Bind_(p.Many1(p.Digit), p.Eof)(test) if err == nil { return nil, fmt.Errorf("atom name can't be a int like %s", ret.(string)) } return ret, nil }
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 stopWord(x interface{}) p.Parser { return p.Bind_(stop, p.Return(x)) }
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 }
return nil, err } // 用于string var EscapeChars = p.Bind_(p.Rune('\\'), func(st p.ParseState) (interface{}, error) { r, err := p.OneOf("nrt\"\\")(st) if err == nil { ru := r.(rune) switch ru { case 'r': return '\r', nil case 'n': return '\n', nil case '"': return '"', nil case '\\': return '\\', nil case 't': return '\t', nil default: return nil, st.Trap("Unknown escape sequence \\%c", r) } } else { return nil, err } }) //用于rune var EscapeCharr = p.Bind_(p.Rune('\\'), func(st p.ParseState) (interface{}, error) { r, err := p.OneOf("nrt'\\")(st) if err == nil {
return func(st p.ParseState) (interface{}, error) { return nil, ParsexSignErrorf("excpet got a parser but %v", pr) } } })), nil default: return nil, ParsexSignErrorf("excpet got a parser but %v", prs) } }, "bind_": func(env Env, args ...interface{}) (Lisp, error) { ptype := reflect.TypeOf((*Parsecer)(nil)).Elem() params, err := GetArgs(env, px.UnionAll(TypeAs(ptype), TypeAs(ptype), px.Eof), args) if err != nil { return nil, err } return ParsecBox(p.Bind_(params[0].(Parsecer).Parser, params[1].(Parsecer).Parser)), nil }, "sepby1": func(env Env, args ...interface{}) (Lisp, error) { ptype := reflect.TypeOf((*Parsecer)(nil)).Elem() params, err := GetArgs(env, px.UnionAll(TypeAs(ptype), TypeAs(ptype), px.Eof), args) if err != nil { return nil, err } return ParsecBox(p.SepBy1(params[0].(Parsecer).Parser, params[1].(Parsecer).Parser)), nil }, "sepby": func(env Env, args ...interface{}) (Lisp, error) { ptype := reflect.TypeOf((*Parsecer)(nil)).Elem() params, err := GetArgs(env, px.UnionAll(TypeAs(ptype), TypeAs(ptype), px.Eof), args) if err != nil { return nil, err }
) // 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 { } // Eval 方法实现 Lisp 值的 Eval 。 Nil 的 Eval 总是返回空值 func (n Nil) Eval(env Env) (interface{}, error) { return nil, nil }