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) } }
// 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 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 }
// 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 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 }
// IntParser 解析整数 func IntParser(st p.ParseState) (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.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:
"rune": func(env Env, args ...interface{}) (Lisp, error) { if len(args) != 1 { return nil, ParsexSignErrorf("Rune Arg Error:except args has 1 arg.") } param, err := Eval(env, args[0]) if err != nil { return nil, err } var ( data Rune ok bool ) if data, ok = param.(Rune); !ok { return nil, ParsexSignErrorf("One Arg Error:except args has 1 rune arg but %v.", reflect.TypeOf(param)) } return ParsecBox(p.Rune(rune(data))), nil }, "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) {
// 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) }