Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

"""JSON token scanner 

""" 

import re 

try: 

    from _json import make_scanner as c_make_scanner 

except ImportError: 

    c_make_scanner = None 

 

__all__ = ['make_scanner'] 

 

NUMBER_RE = re.compile( 

    r'(-?(?:0|[1-9]\d*))(\.\d+)?([eE][-+]?\d+)?', 

    (re.VERBOSE | re.MULTILINE | re.DOTALL)) 

 

def py_make_scanner(context): 

    parse_object = context.parse_object 

    parse_array = context.parse_array 

    parse_string = context.parse_string 

    match_number = NUMBER_RE.match 

    encoding = context.encoding 

    strict = context.strict 

    parse_float = context.parse_float 

    parse_int = context.parse_int 

    parse_constant = context.parse_constant 

    object_hook = context.object_hook 

    object_pairs_hook = context.object_pairs_hook 

 

    def _scan_once(string, idx): 

        try: 

            nextchar = string[idx] 

        except IndexError: 

            raise StopIteration 

 

        if nextchar == '"': 

            return parse_string(string, idx + 1, encoding, strict) 

        elif nextchar == '{': 

            return parse_object((string, idx + 1), encoding, strict, 

                _scan_once, object_hook, object_pairs_hook) 

        elif nextchar == '[': 

            return parse_array((string, idx + 1), _scan_once) 

        elif nextchar == 'n' and string[idx:idx + 4] == 'null': 

            return None, idx + 4 

        elif nextchar == 't' and string[idx:idx + 4] == 'true': 

            return True, idx + 4 

        elif nextchar == 'f' and string[idx:idx + 5] == 'false': 

            return False, idx + 5 

 

        m = match_number(string, idx) 

        if m is not None: 

            integer, frac, exp = m.groups() 

            if frac or exp: 

                res = parse_float(integer + (frac or '') + (exp or '')) 

            else: 

                res = parse_int(integer) 

            return res, m.end() 

        elif nextchar == 'N' and string[idx:idx + 3] == 'NaN': 

            return parse_constant('NaN'), idx + 3 

        elif nextchar == 'I' and string[idx:idx + 8] == 'Infinity': 

            return parse_constant('Infinity'), idx + 8 

        elif nextchar == '-' and string[idx:idx + 9] == '-Infinity': 

            return parse_constant('-Infinity'), idx + 9 

        else: 

            raise StopIteration 

 

    return _scan_once 

 

make_scanner = c_make_scanner or py_make_scanner