File size: 3,016 Bytes
e4806d5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
from ast_parser.token import TokenKind


def is_digit(code: int) -> bool:
    """Check if code is a digit.

    Args:
        code (int): Unicode code point.

    Returns:
        bool: True if code is a digit, False otherwise.
    """
    return 0x0030 <= code <= 0x0039  # <digit>


def is_coefficient_start(code: int) -> bool:
    """Check if code is a coefficient start.

    The Coefficient can start with a digit or a dot.

    Args:
        code (int): Unicode code point.

    Returns:
        bool: True if code is a Coefficient start, False otherwise.
    """
    return is_digit(code) or code == 0x002E  # <digit> | `.`


def is_lower_alpha(code: int) -> bool:
    """Check if code is a lowercased alpha.

    Args:
        code (int): Unicode code point.

    Returns:
        bool: True if code is a lowercased alpha, False otherwise.
    """
    return 0x0061 <= code <= 0x007A  # <lower_alpha>


def is_upper_alpha(code: int) -> bool:
    """Check if code is an uppercased alpha.

    Args:
        code (int): Unicode code point.

    Returns:
        bool: True if code is an uppercased alpha, False otherwise.
    """
    return 0x0041 <= code <= 0x005A  # <upper_alpha>


def is_alpha(code: int) -> bool:
    """Check if code is an alpha.

    Args:
        code (int): Unicode code point.

    Returns:
        bool: True if code is an alpha, False otherwise.
    """
    return is_lower_alpha(code) or is_upper_alpha(code)  # <alpha>


def is_variable_start(code: int) -> bool:
    """Check if code is a variable start.

    The Variable can start with an alpha or an underscore.

    Args:
        code (int): Unicode code point.

    Returns:
        bool: True if code is a Variable start, False otherwise.
    """
    return is_alpha(code) or code == 0x005F  # <alpha> | `_`


def is_variable_continue(code: int) -> bool:
    """Check if code is a variable continue.

    The Variable can continue with an alpha, an underscore or a digit.

    Args:
        code (int): Unicode code point.

    Returns:
        bool: True if code is a Variable continue, False otherwise.
    """
    return is_variable_start(code) or is_digit(code)  # <alpha> | `_` | <digit>


def is_ascii(code: int) -> bool:
    """Check if code is an ASCII.

    Args:
        code (int): Unicode code point.

    Returns:
        bool: True if code is an ASCII, False otherwise.
    """
    return 0x0020 <= code <= 0x007E  # <ASCII>


def print_char_code(code: int | None) -> str:
    """Describe code as a character or Unicode code point.

    Args:
        code (int | None): Unicode code point. None for EOF.

    Returns:
        str: Character or Unicode code point.
    """
    if code is None:  # <EOF>
        return TokenKind.EOF.value

    return chr(code) if is_ascii(code) else f"U+{code:04X}"


__all__ = (
    "is_digit",
    "is_coefficient_start",
    "is_lower_alpha",
    "is_upper_alpha",
    "is_alpha",
    "is_variable_start",
    "is_variable_continue",
    "is_ascii",
    "print_char_code",
)