Архитектура Мысли, Часть 1: Танушы — как мы научили Python читать руны

Это первая статья из нового технического цикла, где мы заглянем «под капот» языка Tengri-Lang. Теперь, когда проект открыт на GitHub, мы можем в деталях показать, с чего начиналось его практическое воплощение. В этой части мы разберем самого первого «мастера» нашего компилятора — Лексер, реализованный на Python.

В предыдущих статьях мы много говорили о философии. Теперь давайте поговорим о коде.

Прежде чем браться за создание «боевого» компилятора на Go, нам нужно было быстро проверить саму идею. Сможет ли машина в принципе распознать наш рунический синтаксис? Будет ли логика грамматики работать? Для таких задач нет инструмента лучше, чем Python. Он позволил нам, не увязая в деталях, создать первого «мастера» — «Танушы» (Распознающего).

Его работа — как у чтеца, который скользит по строке и распознает отдельные слова, не вникая в смысл предложения целиком.

Прежде всего, мы определили, как будет выглядеть «распознанное слово» (токен) в нашей системе. Мы создали простой класс Token, который является контейнером для информации о каждом элементе кода.

  • token.py:

Python

# token.py
class Token:
    """Описывает один 'распознанный' элемент кода."""
    def __init__(self, type, value, line=1, column=1):
        self.type = type      # Тип токена (например, 'Runa_Const', 'Identifier')
        self.value = value    # Значение токена (например, 'Λ', 'san')
        self.line = line      # Номер строки
        self.column = column  # Номер колонки

    def __repr__(self):
        """Метод для красивого вывода токена при печати."""
        return f"Token({self.type}, '{self.value}')"

Каждый токен имеет тип (type) и значение (value). Просто и эффективно.

Теперь — сам «Танушы». В Python его очень удобно реализовать в виде класса Lexer. Сердце этого класса — словарь token_map. Он позволяет мгновенно, без сложных проверок, сопоставить символ из кода с его типом.

  • lexer.py (ключевые фрагменты):

Python

# lexer.py
from token import Token

class Lexer:
    """«Танушы» — распознающий. Финальная версия прототипа."""
    def __init__(self, source_code):
        self.code = source_code
        self.position = 0
        # Полный словарь для мгновенного распознавания одиночных символов
        self.token_map = {
            'Π': 'Runa_Func_Def', '—': 'Runa_Var',
            'Λ': 'Runa_Const',    'Y': 'Runa_If',
            'Q': 'Runa_True',     'I': 'Runa_False',
            '↻': 'Runa_Loop',     '→': 'Runa_Return',
            # ... и так далее для всех рун и операторов
        }

Главный метод get_next_token смотрит на текущий символ и первым делом проверяет, есть ли он в нашем словаре. Если да — токен мгновенно создан.

Python

# фрагмент метода get_next_token в lexer.py
def get_next_token(self):
    # ... (пропуск пробелов и комментариев)

    current_char = self.code[self.position]

    # Проверка по словарю одиночных символов
    if current_char in self.token_map:
        token_type = self.token_map[current_char]
        token = Token(token_type, current_char)
        self.position += 1
        return token

    # Если символ не в словаре, проверяем, не число ли это
    if current_char.isdigit():
        return self._read_number()

    # Или, может быть, это имя (идентификатор)
    if current_char.isalpha():
        identifier = self._read_identifier()
        return Token('Identifier', identifier)
    
    # ...

Метод _read_identifier() просто читает символы подряд, пока они являются буквами или цифрами, и возвращает получившееся слово. Так tengri распознается как один токен, а не 5 отдельных букв.

Этот простой Лексер на Python выполнил свою главную задачу: он доказал, что наша система рун и синтаксиса жизнеспособна. Он смог правильно прочитать и разбить на осмысленные части код, который мы для него написали.

Получив это подтверждение, мы поняли, что пора переходить на следующий уровень. Для создания настоящего, быстрого и надежного компилятора нужен был более подходящий инструмент. Именно поэтому следующим шагом в нашей истории стал перенос этой выверенной логики на «боевой» язык — Go.

В следующей статье мы познакомимся с сердцем нашего компилятора — «Құрастырушы» (Парсером), который знает все законы языка. Именно он берет поток токенов и строит из них величественное «Ой Бәйтерегі» — Древо Мысли.

Оставайтесь с нами и заглядывайте в наш репозиторий на GitHub!

Комментарии 1

Авторизуйтесь чтобы оставить комментарий