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 jsonParser_init() hammer.Parser { // string jsonString := hammer.Sequence( hammer.Ch('"'), hammer.Many1( hammer.Choice( hammer.ChRange('\x20', '\x21'), // skip " hammer.ChRange('\x23', '\x2E'), // skip / hammer.ChRange('\x30', '\x5B'), // skip \ hammer.ChRange('\x5D', '\x7E'), // skip DEL hammer.Sequence(hammer.Ch('\\'), hammer.Ch('"')), hammer.Sequence(hammer.Ch('\\'), hammer.Ch('\\')), hammer.Sequence(hammer.Ch('\\'), hammer.Ch('/')), hammer.Sequence(hammer.Ch('\\'), hammer.Ch('b')), hammer.Sequence(hammer.Ch('\\'), hammer.Ch('f')), hammer.Sequence(hammer.Ch('\\'), hammer.Ch('n')), hammer.Sequence(hammer.Ch('\\'), hammer.Ch('r')), hammer.Sequence(hammer.Ch('\\'), hammer.Ch('t')), hammer.Sequence(hammer.Ch('\\'), hammer.Ch('u')), ), ), hammer.Ch('"'), ) // number jsonNumber := hammer.Sequence( hammer.Optional(hammer.Ch('-')), hammer.Choice( hammer.Ch('0'), hammer.Sequence( hammer.ChRange('1', '9'), hammer.Many1(hammer.ChRange('0', '9')), ), ), hammer.Optional(hammer.Sequence( hammer.Ch('.'), hammer.Many1(hammer.ChRange(0, 9)), )), hammer.Optional(hammer.Sequence( hammer.Choice(hammer.Ch('e'), hammer.Ch('E')), hammer.Optional(hammer.Choice(hammer.Ch('+'), hammer.Ch('-'))), hammer.Many1(hammer.ChRange(0, 9)), )), ) // indirects for use in value jsonArray := hammer.Indirect() jsonObject := hammer.Indirect() // value jsonValue := hammer.Choice( jsonString, jsonNumber, jsonObject, jsonArray, hammer.Token([]byte("true")), hammer.Token([]byte("false")), hammer.Token([]byte("null")), ) // array hammer.BindIndirect(jsonArray, hammer.Sequence( hammer.Ch('['), hammer.SepBy1(jsonValue, hammer.Ch(',')), hammer.Ch(']'), ), ) // object hammer.BindIndirect(jsonObject, hammer.Sequence( hammer.Ch('{'), jsonString, hammer.Ch(':'), jsonValue, hammer.Ch('}'), ), ) return jsonObject }