예제 #1
0
파일: parses.go 프로젝트: gale320/gisp
// 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
}
예제 #2
0
파일: parses.go 프로젝트: zy02636/gisp
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
}
예제 #3
0
파일: parsec_test.go 프로젝트: zy02636/gisp
func TestParsecBasic(t *testing.T) {
	g := NewGispWith(
		map[string]Toolbox{
			"axiom": Axiom, "props": Propositions, "time": Time},
		map[string]Toolbox{"time": Time, "p": Parsec})

	digit := p.Bind(p.Many1(p.Digit), p.ReturnString)
	data := "344932454094325"
	state := p.MemoryParseState(data)
	pre, err := digit(state)
	if err != nil {
		t.Fatalf("except \"%v\" pass test many1 digit but error:%v", data, err)
	}

	src := "(let ((st (p.state \"" + data + `")))
    (var data ((p.many1 p.digit) st))
    (p.s2str data))
    `
	gre, err := g.Parse(src)
	if err != nil {
		t.Fatalf("except \"%v\" pass gisp many1 digit 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)
	}
}
예제 #4
0
파일: parses.go 프로젝트: zy02636/gisp
func bodyParserExt(env Env) p.Parser {
	return func(st p.ParseState) (interface{}, error) {
		value, err := p.Many(p.Bind(ValueParserExt(env), func(x interface{}) p.Parser {
			return p.Bind_(Skip, p.Return(x))
		}))(st)
		return value, err
	}
}
예제 #5
0
파일: dot_test.go 프로젝트: zy02636/gisp
func TestDotParser(t *testing.T) {
	data := "now.Year"
	st := p.MemoryParseState(data)
	re, err := p.Bind(AtomParser, DotSuffixParser)(st)
	if err != nil {
		t.Fatalf("except a Dot but error %v", err)
	}
	t.Log(re)
}
예제 #6
0
파일: atom.go 프로젝트: gale320/gisp
func atomNameParser(st p.ParseState) (interface{}, error) {
	ret, err := p.Bind(p.Many1(p.NoneOf("'[]() \t\r\n\".:")),
		p.ReturnString)(st)
	if err != nil {
		return nil, err
	}
	test := p.MemoryParseState(ret.(string))
	_, err = p.Bind_(p.Many1(p.Digit), p.Eof)(test)
	if err == nil {
		return nil, fmt.Errorf("atom name can't be a int like %s", ret.(string))
	}
	return ret, nil
}
예제 #7
0
파일: type.go 프로젝트: zy02636/gisp
func typeName(word string) p.Parser {
	return p.Bind(p.String(word), stopWord)
}
예제 #8
0
파일: type.go 프로젝트: zy02636/gisp
	)(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 {
예제 #9
0
파일: parses.go 프로젝트: zy02636/gisp
		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
}

func bodyParserExt(env Env) p.Parser {
예제 #10
0
파일: parsec.go 프로젝트: gale320/gisp
			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])
			if err != nil {
				return nil, err
			}
			switch fun := f.(type) {
			case func(interface{}) p.Parser:
				return ParsecBox(p.Bind(parser.Parser, fun)), nil
			case Functor:
				return ParsecBox(p.Bind(parser.Parser, func(x interface{}) p.Parser {
					tasker, err := fun.Task(env, x)
					if err != nil {
						return func(st p.ParseState) (interface{}, error) {
							return nil, err
						}
					}
					pr, err := tasker.Eval(env)
					if err != nil {
						return func(st p.ParseState) (interface{}, error) {
							return nil, err
						}
					}
					switch parser := pr.(type) {
예제 #11
0
파일: bool.go 프로젝트: gale320/gisp
import (
	"fmt"

	p "github.com/Dwarfartisan/goparsec"
)

// Bool 是内置的 bool 类型的封装
type Bool bool

// BoolParser 解析 bool
var BoolParser = p.Bind(p.Choice(p.String("true"), p.String("false")), func(input interface{}) p.Parser {
	return func(st p.ParseState) (interface{}, error) {
		switch input.(string) {
		case "true":
			return Bool(true), nil
		case "false":
			return Bool(false), nil
		default:
			return nil, fmt.Errorf("Unexcept bool token %v", input)
		}
	}
})

// NilParser 解析 nil
var NilParser = p.Bind_(p.String("nil"), p.Return(nil))

// Nil 类型定义空值行为
type Nil struct {
}

// Eval 方法实现 Lisp 值的 Eval 。 Nil 的 Eval 总是返回空值
func (n Nil) Eval(env Env) (interface{}, error) {