Beispiel #1
0
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)
	}
}
Beispiel #2
0
// 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))
		}
	}
}
Beispiel #3
0
// 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))
		}

	}
}
Beispiel #4
0
// 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
}
Beispiel #5
0
// 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
}
Beispiel #6
0
// 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
}
Beispiel #7
0
// 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
}
Beispiel #8
0
// 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
	}
}
Beispiel #9
0
// 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
		}
	}
}
Beispiel #10
0
// 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
	}
}
Beispiel #11
0
// 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
}
Beispiel #12
0
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))
Beispiel #13
0
			}
			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 {
Beispiel #14
0
// BracketParserExt 在带有 Ext 的环境下解析中括号表达式
func BracketParserExt(env Env) p.P {
	return p.Between(p.Chr('['), p.Chr(']'),
		p.SepBy1(ValueParserExt(env), p.Chr(':')),
	)
}