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 }
// BracketSuffix 表示带 [] 后缀的表达式 func BracketSuffix(x interface{}) p.Parser { return func(st p.ParseState) (interface{}, error) { b, err := p.Try(BracketParser)(st) if err != nil { return nil, err } return bracketSuffix(Bracket{x, b.([]interface{})})(st) } }
func dotSuffix(x interface{}) p.Parser { return func(st p.ParseState) (interface{}, error) { d, err := p.Try(DotParser)(st) if err != nil { return x, nil } return dotSuffix(Dot{x, d.(Atom)})(st) } }
// SuffixParser 定义了后缀表达式的通用判定 func SuffixParser(prefix interface{}) p.Parser { suffix := p.Either(p.Try(DotSuffix(prefix)), BracketSuffix(prefix)) return func(st p.ParseState) (interface{}, error) { s, err := suffix(st) if err != nil { return prefix, nil } return SuffixParser(s)(st) } }
// AtomParser 生成 Atom 对象,但是它不带扩展环境 func AtomParser(st p.ParseState) (interface{}, error) { a, err := atomNameParser(st) if err != nil { return nil, err } t, err := p.Try(TypeParser)(st) if err == nil { return Atom{a.(string), t.(Type)}, nil } return Atom{a.(string), ANYMUST}, 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 }
// FloatParser 解析浮点数 func FloatParser(st p.ParseState) (interface{}, error) { f, err := p.Try(p.Float)(st) if err == nil { val, err := strconv.ParseFloat(f.(string), 64) if err == nil { return Float(val), nil } return nil, err } return nil, err }
func AtomParserExt(env Env) p.Parser { return func(st p.ParseState) (interface{}, error) { a, err := atomNameParser(st) if err != nil { return nil, err } t, err := p.Try(ExtTypeParser(env))(st) if err == nil { return Atom{a.(string), t.(Type)}, nil } else { return Atom{a.(string), ANYMUST}, 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 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 }
)(st) if err != nil { return nil, err } return r, nil } func stopWord(x interface{}) p.Parser { return p.Bind_(stop, p.Return(x)) } func typeName(word string) p.Parser { return p.Bind(p.String(word), stopWord) } var anyType = p.Bind(p.Bind(p.Many1(p.Either(p.Try(p.Digit), p.Letter)), stopWord), p.ReturnString) 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 } } func MapTypeParserExt(env Env) p.Parser { return func(st p.ParseState) (interface{}, error) { key, err := p.Between(p.String("map["), p.Rune(']'), ExtTypeParser(env))(st) if err != nil {
return '\'', nil case '\\': return '\\', nil case 't': return '\t', nil default: return nil, st.Trap("Unknown escape sequence \\%c", r) } } else { return nil, err } }) var RuneParser = p.Bind( p.Between(p.Rune('\''), p.Rune('\''), p.Either(p.Try(EscapeCharr), p.NoneOf("'"))), func(x interface{}) p.Parser { return p.Return(Rune(x.(rune))) }, ) var StringParser = p.Bind( p.Between(p.Rune('"'), p.Rune('"'), p.Many(p.Either(p.Try(EscapeChars), p.NoneOf("\"")))), p.ReturnString) func bodyParser(st p.ParseState) (interface{}, error) { value, err := p.SepBy(ValueParser, p.Many1(Space))(st) return value, err }
"anyone": ParsecBox(p.AnyRune), "int": ParsecBox(p.Int), "float": ParsecBox(p.Float), "digit": ParsecBox(p.Digit), "eof": ParsecBox(p.Eof), "try": func(env Env, args ...interface{}) (Lisp, error) { if len(args) != 1 { return nil, ParsexSignErrorf("Parsec Parser Try Error: only accept one Parsec Parser as arg but %v", args) } param, err := Eval(env, args[0]) if err != nil { return nil, err } switch parser := param.(type) { case Parsecer: return ParsecBox(p.Try(parser.Parser)), nil default: return nil, ParsexSignErrorf( "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 },
// BracketSuffixParser 定义 bracket 表达式判定 func BracketSuffixParser(x interface{}) p.Parser { return p.Either(p.Try(BracketSuffix(x)), p.Return(x)) }