func TestParsecRune(t *testing.T) { g := NewGispWith( map[string]Toolbox{ "axiom": Axiom, "props": Propositions, "time": Time}, map[string]Toolbox{"time": Time, "p": Parsec}) //data := "Here is a Rune : 'a' and a is't a rune. It is a word in sentence." data := "'a' and a is't a rune. It is a word in sentence." state := NewStringState(data) pre, err := p.Between(p.Chr('\''), p.Chr('\''), p.AsRune)(state) if err != nil { t.Fatalf("expect found rune expr from \"%v\" but error:%v", data, err) } src := ` (let ((st (p.state "` + data + `"))) ((p.between (p.rune '\'') (p.rune '\'') p.one) st)) ` gre, err := g.Parse(src) if err != nil { t.Fatalf("expect \"%v\" pass gisp '<rune>' but error:%v", src, err) } t.Logf("from gisp: %v", gre) t.Logf("from parsec: %v", pre) if !reflect.DeepEqual(pre, gre) { t.Fatalf("expect got \"%v\" from gisp equal \"%v\" from parsec", gre, pre) } }
// 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) list, err := p.Between(left, right, listBodyParser)(st) 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)) } } }
// 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, objectBodyParser)(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)) } } }
// DotParser 定义了从文本中解析出 Dot 表达式的 Parser func DotParser(st p.State) (interface{}, error) { name, err := p.Chr('.').Then(atomNameParser()).Parse(st) if err != nil { return nil, err } return AA(name.(string)), nil }
// DotExprParser 实现 Dot 表达式的解析构造 func DotExprParser(st p.State) (interface{}, error) { name, err := p.Chr('.').Then(atomNameParser())(st) if err != nil { return nil, err } return DotExpr{name.(string)}, 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 }
// QuoteParser 实现 Quote 语法的解析 func QuoteParser(st p.State) (interface{}, error) { lisp, err := p.Chr('\'').Then( p.Choice( p.Try(p.P(AtomParser).Bind(SuffixParser)), ListParser().Bind(SuffixParser), ))(st) if err == nil { return Quote{lisp}, nil } return nil, err }
// 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 } }
// ListParserExt 实现带扩展的列表解析器 func ListParserExt(env Env) p.P { left := p.Chr('(').Then(Skip) right := Skip.Then(p.Chr(')')) empty := left.Then(right) return func(st p.State) (interface{}, error) { list, err := p.Try(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 unexpected: %v", list, reflect.TypeOf(list)) } } else { _, e := empty(st) if e == nil { return List{}, nil } return nil, err } } }
// 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 } }
// 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 }
func IntParser(st p.State) (interface{}, error) { i, err := p.Int(st) if err == nil { val, err := strconv.Atoi(i.(string)) if err == nil { return Int(val), nil } return nil, err } return nil, err } // 用于string var EscapeChars = p.Do(func(st p.State) interface{} { p.Chr('\\').Exec(st) r := p.RuneOf("nrt\"\\").Exec(st) ru := r.(rune) switch ru { case 'r': return '\r' case 'n': return '\n' case '"': return '"' case '\\': return '\\' case 't': return '\t' default: panic(st.Trap("Unknown escape sequence \\%c", r))
} 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) { if len(args) != 1 { return nil, fmt.Errorf("string Arg Error:expect args has 1 arg") } param, err := Eval(env, args[0]) if err != nil { return nil, err } var str string var ok bool if str, ok = param.(string); !ok {
// BracketParserExt 在带有 Ext 的环境下解析中括号表达式 func BracketParserExt(env Env) p.P { return p.Between(p.Chr('['), p.Chr(']'), p.SepBy1(ValueParserExt(env), p.Chr(':')), ) }