# All files / utils index.ts

79.45% Statements 58/73
78.57% Branches 22/28
80% Functions 4/5
79.17% Lines 57/72

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    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
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    1601x

    4x
    4x

    4x

    4x

    4x
    2x
    26x

    26x

    2x

    4x
    150x

    150x
    10x
    10x
    10x

    140x

    140x

    140x

    2x
    2x

    138x
    2x
    2x

    2x
    30x
    30x

    2x

    2x

    136x
    2x
    2x
    2x
    2x
    2x
    2x
    32x

    32x
    32x

    2x
    2x
    2x

    2x

    134x

    134x

    4x

    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x

    2x
    2x

    1x
     import { TokenType, Token, TokenReg } from './token';

    /**
     * 获取 注释 以及 分隔符 等词法信息
     * @param {String} python
     */
    function lexer(input: string): Token[] {
        // 记录当前字符的位置
        let current = 0;
        let line = 1;
        // 最终的 TokenTypes 结果
        const tokens: Token[] = [];

        /**
         * 提取 TokenType
         */
        // eslint-disable-next-line
        const extract = (currentChar: string, validator: RegExp, TokenType: TokenType): Token => {
            let value = '';
            const start = current;
            while (validator.test(currentChar)) {
                value += currentChar;
                currentChar = input[++current];
            }
            return {
                type: TokenType,
                start: start,
                end: current,
                lineNumber: line,
                value: value,
            };
        };

        /**
         * 过滤（提取） 引号中的内容
         */
        // eslint-disable-next-line
        const matchQuotation = (currentChar: string, validator: RegExp, TokenType: TokenType) => {
            do {
                Iif (currentChar === '\n') {
                    line++;
                }
                currentChar = input[++current];
            } while (!validator.test(currentChar));

            ++current;
        };

        while (current < input.length) {
            let char = input[current];

            // 按顺序处理 换行符 反引号 单引号 双引号 注释 分号
            // 引号内 可能包含注释包含的符号以及分号 所以优先处理引号里面的内容 去除干扰信息

            if (char === '\n') {
                line++;
                current++;
                continue;
            }

            Iif (TokenReg.BackQuotation.test(char)) {
                // eslint-disable-next-line
                matchQuotation(char, TokenReg.BackQuotation, TokenType.BackQuotation);
                continue;
            }

            Iif (TokenReg.SingleQuotation.test(char)) {
                // eslint-disable-next-line

                matchQuotation(char, TokenReg.SingleQuotation, TokenType.SingleQuotation);
                continue;
            }

            if (TokenReg.DoubleQuotation.test(char) && input[current + 1] !== `"`) {
                // eslint-disable-next-line
                matchQuotation(char, TokenReg.DoubleQuotation, TokenType.DoubleQuotation);
                continue;
            }

            // 处理单行注释，以 # 开始，\n 结束
            if (char === '#') {
                let value = '';
                const start = current;

                while (char !== '\n') {
                    value += char;
                    char = input[++current];
                }
                tokens.push({
                    type: TokenType.Comment,
                    value,
                    start: start,
                    lineNumber: line,
                    end: current,
                });
                continue;
            }

            // 处理多行注释，以 """ 开始， """结束
            if (char === `"` && input[current + 1] === `"` && input[current + 2] === `"`) {
                let value = '"""';
                const start = current;
                const startLine = line;
                current += 3;
                char = input[current];
                while (!(char === `"` && input[current - 1] === `"` && input[current - 2] === `"`)) {
                    Iif (char === '\n') {
                        line++;
                    }
                    value += char;
                    char = input[++current];
                }
                value += char;
                ++current;
                tokens.push({
                    type: TokenType.Comment,
                    value,
                    start: start,
                    lineNumber: startLine,
                    end: current,
                });
                continue;
            }

            // 处理结束符 ;
            Iif (TokenReg.StatementTerminator.test(char)) {
                const newToken = extract(
                    char,
                    TokenReg.StatementTerminator,
                    TokenType.StatementTerminator,
                );
                tokens.push(newToken);
                continue;
            }

            current++;
        }
        return tokens;
    }

    /**
     * 清除注释和前后空格
     * @param {String} python
     */
    function cleanPython(python: string) {
        python.trim(); // 删除前后空格
        const tokens = lexer(python);
        let resultPython = '';
        let startIndex = 0;
        tokens.forEach((ele: Token) => {
            Eif (ele.type === TokenType.Comment) {
                resultPython += python.slice(startIndex, ele.start);
                startIndex = ele.end + 1;
            }
        });
        resultPython += python.slice(startIndex);
        return resultPython;
    }
    export { cleanPython, lexer };