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 } } } }
func TestParsecRune2(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 := p.MemoryParseState(data) pre, err := p.Between(p.Rune('\''), p.Rune('\''), p.AnyRune)(state) if err != nil { t.Fatalf("except found rune expr from \"%v\" but error:%v", data, err) } src := ` (let ((st (p.state "` + data + `"))) ((p.rune '\'') st) (var data (p.anyone st)) ((p.rune '\'') st) data) ` //fmt.Println(src) gre, err := g.Parse(src) if err != nil { t.Fatalf("except \"%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("except got \"%v\" from gisp equal \"%v\" from parsec", gre, pre) } }
func MapTypeParser(st p.ParseState) (interface{}, error) { key, err := p.Between(p.String("map["), p.Rune(']'), 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 }
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 } }) 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 }
var ( data string ok bool ) if data, ok = param.(string); !ok { return nil, ParsexSignErrorf("NoneOf Arg Error:except args has 1 string arg.") } return ParsecBox(p.NoneOf(data)), nil }, "between": func(env Env, args ...interface{}) (Lisp, error) { ptype := reflect.TypeOf((*Parsecer)(nil)).Elem() params, err := GetArgs(env, px.UnionAll(TypeAs(ptype), TypeAs(ptype), TypeAs(ptype), px.Eof), args) if err != nil { return nil, err } return ParsecBox(p.Between(params[0].(Parsecer).Parser, params[1].(Parsecer).Parser, params[2].(Parsecer).Parser)), nil }, "bind": func(env Env, args ...interface{}) (Lisp, error) { if len(args) != 2 { return nil, ParsexSignErrorf("Bind Args Error:except 2 args.") } prs, err := Eval(env, args[0]) if err != nil { return nil, err } var parser Parsecer var ok bool if parser, ok = prs.(Parsecer); !ok { return nil, ParsexSignErrorf("Bind Args Error:except first arg is a parsecer.") } f, err := Eval(env, args[1])
// BracketParserExt 在带有 Ext 的环境下对中括号表达式求值 func BracketParserExt(env Env) p.Parser { return p.Between(p.Rune('['), p.Rune(']'), p.SepBy1(ValueParserExt(env), p.Rune(':')), ) }
// BracketParser 尝试将 state 中下一个值解析为中括号表达式 func BracketParser(st p.ParseState) (interface{}, error) { return p.Between(p.Rune('['), p.Rune(']'), p.SepBy1(ValueParser, p.Rune(':')), )(st) }