//RandomWalk does a random walk of the parser, given two probabilities. // next is passed to r.Intn and when a zero value is returned the Next method on the parser is called. // down is passed to r.Intn and when a non zero value is returned the Down method on the parser is called. //RandomWalk is great for testing that the implemented parser can handle random skipping of parts of the tree. func RandomWalk(p parser.Interface, r Rand, next, down int) Nodes { a := make(Nodes, 0) for { if r.Intn(next) == 0 { break } if err := p.Next(); err != nil { if err == io.EOF { break } else { panic(err) } } value := getValue(p) if p.IsLeaf() { a = append(a, Node{fmt.Sprintf("%#v", value), nil}) } else { name := fmt.Sprintf("%#v", value) var v Nodes if r.Intn(down) != 0 { p.Down() v = RandomWalk(p, r, next, down) p.Up() } a = append(a, Node{name, v}) } } return a }
func (this *msg) encode(buf []byte, offset int, p parser.Interface) ([]byte, int, error) { for { if err := p.Next(); err != nil { if err == io.EOF { return buf, offset, nil } else { return nil, 0, err } } name, err := p.String() if err != nil { return nil, 0, err } fieldEnc, ok := this.fieldEncoders[name] if !ok { continue //skip field } p.Down() buf, offset, err = fieldEnc.encode(buf, offset, p) if err != nil { return nil, 0, err } p.Up() } }
func deriv(refs ast.RefLookup, patterns []*ast.Pattern, tree parser.Interface) ([]*ast.Pattern, error) { var resPatterns []*ast.Pattern = patterns for { if !escapable(resPatterns) { return resPatterns, nil } if err := tree.Next(); err != nil { if err == io.EOF { break } else { return nil, err } } childPatterns, err := derivCalls(refs, resPatterns, tree) if err != nil { return nil, err } if tree.IsLeaf() { //do nothing } else { tree.Down() zchild, zi := zip(childPatterns) zchild, err = deriv(refs, zchild, tree) if err != nil { return nil, err } childPatterns = unzip(zchild, zi) tree.Up() } resPatterns = derivReturns(refs, resPatterns, childPatterns) resPatterns = simps(refs, resPatterns) } return resPatterns, nil }
func deriv(mem *Mem, patterns int, tree parser.Interface) (int, error) { for { if !mem.escapable(patterns) { return patterns, nil } if err := tree.Next(); err != nil { if err == io.EOF { break } else { return 0, err } } callTree, err := mem.getCallTree(patterns) if err != nil { return 0, err } childPatterns, stackElm, err := callTree.Eval(tree) if err != nil { return 0, err } if !tree.IsLeaf() { tree.Down() childPatterns, err = deriv(mem, childPatterns, tree) if err != nil { return 0, err } tree.Up() } nullIndex := mem.getNullable(childPatterns) patterns = mem.getReturn(stackElm, nullIndex) } return patterns, nil }
func deriv(auto *Auto, current int, tree parser.Interface) (int, error) { for { if !auto.escapables[current] { return current, nil } if err := tree.Next(); err != nil { if err == io.EOF { break } else { return 0, err } } callTree := auto.calls[current] childState, stackElm, err := callTree.Eval(tree) if err != nil { return 0, err } if !tree.IsLeaf() { tree.Down() childState, err = deriv(auto, childState, tree) if err != nil { return 0, err } tree.Up() } nullIndex := auto.stateToNullable[childState] current = auto.returns[stackElm].lookup(nullIndex) } return current, nil }
func encode(e *xml.Encoder, p parser.Interface) error { for { if err := p.Next(); err != nil { if err == io.EOF { break } else { return err } } if p.IsLeaf() { if err := e.EncodeToken(getCharData(p)); err != nil { return err } } else { name := getName(p) if err := e.EncodeToken(xml.StartElement{Name: name}); err != nil { return err } p.Down() if err := encode(e, p); err != nil { return err } p.Up() if err := e.EncodeToken(xml.EndElement{Name: name}); err != nil { return err } } } return nil }
func next(t *testing.T, parser parser.Interface) { if err := parser.Next(); err != nil { if err != io.EOF { t.Fatal(err) } } }
func (this *repeatedField) encode(buf []byte, offset int, p parser.Interface) ([]byte, int, error) { for { if err := p.Next(); err != nil { if err == io.EOF { return buf, offset, nil } else { return nil, 0, err } } _, err := p.Int() if err != nil { return nil, 0, err } p.Down() buf, offset, err = this.fieldEnc.encode(buf, offset, p) if err != nil { return nil, 0, err } p.Up() } }
func (this *fixed32IntField) encode(buf []byte, offset int, p parser.Interface) ([]byte, int, error) { if err := p.Next(); err != nil { return buf, offset, nil } if !p.IsLeaf() { return buf, offset, nil } buf, offset = safeCopy(buf, offset, this.key) v, err := p.Int() if err != nil { return nil, 0, err } buf, offset = safeFixed32(buf, offset, uint32(v)) return buf, offset, nil }
func (this *doubleField) encode(buf []byte, offset int, p parser.Interface) ([]byte, int, error) { if err := p.Next(); err != nil { return buf, offset, nil } if !p.IsLeaf() { return buf, offset, nil } buf, offset = safeCopy(buf, offset, this.key) v, err := p.Double() if err != nil { return nil, 0, err } buf, offset = safeFixed64(buf, offset, math.Float64bits(v)) return buf, offset, nil }
func (this *sint64Field) encode(buf []byte, offset int, p parser.Interface) ([]byte, int, error) { if err := p.Next(); err != nil { return buf, offset, nil } if !p.IsLeaf() { return buf, offset, nil } buf, offset = safeCopy(buf, offset, this.key) v, err := p.Int() if err != nil { return nil, 0, err } buf, offset = safeVarint(buf, offset, uint64((uint64(v)<<1)^uint64((v>>63)))) return buf, offset, nil }
func (this *bytesField) encode(buf []byte, offset int, p parser.Interface) ([]byte, int, error) { if err := p.Next(); err != nil { return buf, offset, nil } if !p.IsLeaf() { return buf, offset, nil } buf, offset = safeCopy(buf, offset, this.key) v, err := p.Bytes() if err != nil { return nil, 0, err } buf, offset = safeVarint(buf, offset, uint64(len(v))) buf, offset = safeCopy(buf, offset, v) return buf, offset, nil }
//Walk walks through the whole parser in a top down manner and records the values into a Nodes structute. func Walk(p parser.Interface) Nodes { a := make(Nodes, 0) for { if err := p.Next(); err != nil { if err == io.EOF { break } else { panic(err) } } value := getValue(p) if p.IsLeaf() { a = append(a, Node{fmt.Sprintf("%v", value), nil}) } else { name := fmt.Sprintf("%v", value) p.Down() v := Walk(p) p.Up() a = append(a, Node{name, v}) } } return a }
func (this *boolField) encode(buf []byte, offset int, p parser.Interface) ([]byte, int, error) { if err := p.Next(); err != nil { return buf, offset, nil } if !p.IsLeaf() { return buf, offset, nil } buf, offset = safeCopy(buf, offset, this.key) b, err := p.Bool() if err != nil { return nil, 0, err } v := uint64(0) if b { v = 1 } buf, offset = safeVarint(buf, offset, v) return buf, offset, nil }
func getCharData(p parser.Interface) xml.CharData { i, err := p.Int() if err == nil { return xml.CharData([]byte(strconv.FormatInt(i, 10))) } u, err := p.Uint() if err == nil { return xml.CharData([]byte(strconv.FormatUint(u, 10))) } d, err := p.Double() if err == nil { return xml.CharData([]byte(strconv.FormatFloat(d, 'e', -1, 64))) } b, err := p.Bool() if err == nil { return xml.CharData([]byte(strconv.FormatBool(b))) } s, err := p.String() if err == nil { return xml.CharData([]byte(s)) } v, err := p.Bytes() if err == nil { return xml.CharData([]byte(base64.StdEncoding.EncodeToString(v))) } return nil }
func encodeStruct(p parser.Interface, v reflect.Value) error { kind := v.Type().Kind() isPtr := false if kind == reflect.Ptr { kind = v.Type().Elem().Kind() isPtr = true } if kind != reflect.Struct { return fmt.Errorf("expected struct") } for { if err := p.Next(); err != nil { if err == io.EOF { return nil } else { panic(err) } } if p.IsLeaf() { return fmt.Errorf("struct: did not expect leaf") } name, err := p.String() if err != nil { return err } strct := v if isPtr { strct = v.Elem() } field := strct.FieldByName(name) if !field.IsValid() { continue //skip field } fieldKind := field.Kind() fieldIsPtr := false fieldType := field.Type() if fieldKind == reflect.Ptr { fieldIsPtr = true fieldKind = field.Type().Elem().Kind() fieldType = field.Type().Elem() } p.Down() switch fieldKind { case reflect.Struct: if !p.IsLeaf() { if fieldIsPtr { field.Set(reflect.New(field.Type().Elem())) } if err := encodeStruct(p, field); err != nil { return err } } case reflect.Slice: list, err := newList(p, fieldType) if err != nil { return err } field.Set(list) default: value, err := newValue(p, fieldType) if err != nil { return err } field.Set(value) } p.Up() } }
func newValue(p parser.Interface, typ reflect.Type) (reflect.Value, error) { if err := p.Next(); err != nil { if err == io.EOF { return reflect.ValueOf(nil), nil } else { panic(err) } } if !p.IsLeaf() { return reflect.ValueOf(nil), fmt.Errorf("expected leaf") } if value, err := p.Int(); err == nil { return reflect.ValueOf(value), nil } if value, err := p.Uint(); err == nil { return reflect.ValueOf(value), nil } if value, err := p.Double(); err == nil { return reflect.ValueOf(value), nil } if value, err := p.Bool(); err == nil { return reflect.ValueOf(value), nil } if value, err := p.String(); err == nil { return reflect.ValueOf(value), nil } if value, err := p.Bytes(); err == nil { return reflect.ValueOf(value), nil } return reflect.ValueOf(nil), nil }
func newList(p parser.Interface, typ reflect.Type) (reflect.Value, error) { list := reflect.MakeSlice(typ, 0, 0) for { if err := p.Next(); err != nil { if err == io.EOF { return list, nil } else { panic(err) } } if p.IsLeaf() { return reflect.ValueOf(nil), fmt.Errorf("list: did not expect leaf") } _, err := p.Int() if err != nil { return reflect.ValueOf(nil), err } elemType := typ.Elem() elemKind := elemType.Kind() elemIsPtr := false if elemKind == reflect.Ptr { elemIsPtr = true elemType = typ.Elem().Elem() elemKind = elemType.Kind() } p.Down() switch elemKind { case reflect.Struct: if !p.IsLeaf() { elem := reflect.New(elemType).Elem() if err := encodeStruct(p, elem); err != nil { return reflect.ValueOf(nil), err } if elemIsPtr { elem = elem.Addr() } list = reflect.Append(list, elem) } else { list = reflect.Append(list, reflect.Zero(typ.Elem())) } case reflect.Slice: newList, err := newList(p, elemType) if err != nil { return reflect.ValueOf(nil), err } list = reflect.Append(list, newList) default: elem, err := newValue(p, typ.Elem()) if err != nil { return reflect.ValueOf(nil), err } list = reflect.Append(list, elem) } p.Up() } }
func getName(p parser.Interface) xml.Name { i, err := p.Int() if err == nil { return xml.Name{Local: strconv.FormatInt(i, 10)} } u, err := p.Uint() if err == nil { return xml.Name{Local: strconv.FormatUint(u, 10)} } d, err := p.Double() if err == nil { return xml.Name{Local: strconv.FormatFloat(d, 'e', -1, 64)} } b, err := p.Bool() if err == nil { return xml.Name{Local: strconv.FormatBool(b)} } s, err := p.String() if err == nil { return xml.Name{Local: s} } v, err := p.Bytes() if err == nil { return xml.Name{Local: base64.StdEncoding.EncodeToString(v)} } return xml.Name{} }
func encode(p parser.Interface) (interface{}, error) { var fields = make(map[string]interface{}) var list []interface{} for { if err := p.Next(); err != nil { if err == io.EOF { if len(fields) > 0 { return fields, nil } if list != nil { return list, nil } return nil, nil } return nil, err } if p.IsLeaf() { if v, err := p.Int(); err == nil { return v, nil } if v, err := p.Uint(); err == nil { return v, nil } if v, err := p.Double(); err == nil { return v, nil } if v, err := p.Bool(); err == nil { return v, nil } if v, err := p.String(); err == nil { return v, nil } if v, err := p.Bytes(); err == nil { return base64.StdEncoding.EncodeToString(v), nil } return nil, nil } if _, err := p.Int(); err == nil { p.Down() item, err := encode(p) if err != nil { return nil, err } p.Up() list = append(list, item) continue } name, err := p.String() if err != nil { return nil, err } p.Down() value, err := encode(p) if err != nil { return nil, err } p.Up() fields[name] = value } }
func getValue(p parser.Interface) interface{} { var v interface{} var err error v, err = p.Int() if err == nil { return v } v, err = p.Uint() if err == nil { return v } v, err = p.Double() if err == nil { return v } v, err = p.Bool() if err == nil { return v } v, err = p.String() if err == nil { return v } v, err = p.Bytes() if err == nil { return v } return nil }