func init() { end := hammer.Ch('e') colon := hammer.Ch(':') neg := hammer.Ch('-') digits := hammer.Many1(hammer.ChRange('0', '9')) uint_10 := hammer.Action(digits, func(token ast.Token) (ast.Token, bool) { numstr := charSequenceString(token.Value.([]ast.Token)) num, err := strconv.ParseUint(numstr, 10, 64) if err != nil { return token, false } token.Value = num return token, true }) int_10 := hammer.Action(hammer.Sequence(hammer.Optional(neg), digits), func(token ast.Token) (ast.Token, bool) { tokens := token.Value.([]ast.Token) neg, digits := tokens[0], tokens[1] numstr := charSequenceString(digits.Value.([]ast.Token)) num, err := strconv.ParseInt(numstr, 10, 64) if err != nil { return token, false } if neg.Value != ast.None { num *= -1 } token.Value = num return token, true }) b_string := hammer.LengthValue(hammer.Left(uint_10, colon), hammer.Uint8()) b_int := hammer.Sequence(hammer.Ch('i'), int_10, end) b_list := hammer.Indirect() b_dict := hammer.Indirect() anyType := hammer.Choice(b_int, b_string, b_list, b_dict) hammer.BindIndirect(b_list, hammer.Sequence( hammer.Ch('l'), hammer.Many(anyType), end, )) hammer.BindIndirect(b_dict, hammer.Sequence( hammer.Ch('d'), hammer.Many(hammer.Sequence(b_string, anyType)), end, )) bencode = anyType }
func base64_parser() hammer.Parser { digit := hammer.ChRange('0', '9') alpha := hammer.Choice( hammer.ChRange('A', 'Z'), hammer.ChRange('a', 'z'), ) plus := hammer.Ch('+') slash := hammer.Ch('/') equals := hammer.Ch('=') bsfdig := hammer.Choice(alpha, digit, plus, slash) bsfdig_4bit := hammer.In([]byte("AEIMQUYcgkosw048")) bsfdig_2bit := hammer.In([]byte("AQgw")) base64_3 := hammer.RepeatN(bsfdig, 4) base64_2 := hammer.Sequence(bsfdig, bsfdig, bsfdig_4bit, equals) base64_1 := hammer.Sequence(bsfdig, bsfdig_2bit, equals, equals) base64 := hammer.Sequence( hammer.Many(base64_3), hammer.Optional( hammer.Choice(base64_2, base64_1), ), ) return base64 }