// 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 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 }
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) } }
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 } }
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) }
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 }
func typeName(word string) p.Parser { return p.Bind(p.String(word), stopWord) }
)(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 {
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 {
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) {
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) {