Python. Что использовать для более качественного разделения?

Вот часть лексера:

import re


class Lexer(object):
    def __init__(self, source_code):
        self.source_code = source_code

    def tokenize(self):
        tokens = []

        source_code = self.source_code.split()

        source_index = 0

        while source_index < len(source_code):
            word = source_code[source_index]

            if word == "var": tokens.append(["VAR_DECLERATION", word])

            elif re.match('[a-z]', word) or re.match('[A-Z]', word): tokens.append(['IDENTIFIER', word])

            elif re.match('[0-9]', word): tokens.append(['INTEGER', word])

            elif word in "=/*-+": tokens.append(['OPERATOR', word])

            source_index += 1

        print(tokens)

        return tokens

И при его вызове в программе

lex = lexer.Lexer(content)
tokens = lex.tokenize()

Где content содержит var age = 17; print age;

Выводит такой результат: [['VAR_DECLERATION', 'var'], ['IDENTIFIER', 'age'], ['OPERATOR', '='], ['INTEGER', '17;'], ['IDENTIFIER', 'print'], ['IDENTIFIER', 'age;']]

Всё вроде бы хорошо, но есть одно но. Лексер использует функцию .split(), которая разделяет текст по пробелам. И при content = var age=17; print age;

Вывод будет такой: [['VAR_DECLERATION', 'var'], ['IDENTIFIER', 'age=17;'], ['IDENTIFIER', 'print'], ['IDENTIFIER', 'age;']] То есть age=17 слилось.

Вопрос: как мне сделать чтобы они разделялись?


Ответы (1 шт):

Автор решения: Amgarak

Можно добавить регулярное выражение, как пример:

import re

class Lexer(object):
    def __init__(self, source_code):
        self.source_code = source_code

    def tokenize(self):
        tokens = []

        # Добавляем регулярное выражение
        source_code = re.findall(r'\w+|[=/*+-]', self.source_code)

        for word in source_code:
            if word == "var":
                tokens.append(["VAR_DECLARATION", word])
            elif re.match('[a-zA-Z]', word):
                tokens.append(['IDENTIFIER', word])
            elif re.match('[0-9]', word):
                tokens.append(['INTEGER', word])
            elif word in "=/*-+":
                tokens.append(['OPERATOR', word])

        print(tokens)

        return tokens

# Пример
content = "var age=17; print age;"
lex = Lexer(content)
tokens = lex.tokenize()

[['VAR_DECLARATION', 'var'], ['IDENTIFIER', 'age'], ['OPERATOR', '='], ['INTEGER', '17'], ['IDENTIFIER', 'print'], ['IDENTIFIER', 'age']] [Program finished]

→ Ссылка