Реализация настраиваемого класса Lexer в Python - PullRequest
1 голос
/ 01 февраля 2012

Я хочу реализовать настраиваемый и расширяемый класс лексеров.

Моя идея

2 различных типа обработчиков :

  1. Обработчики набора символов
  2. Обработчики функций

Когда символ читается, он проталкивается через все обработчики, зарегистрированные в лексере.Как только обработчик сопоставляет и возвращает действительный токен , он возвращается.Когда ни один обработчик не соответствует символу, вызывается функция в худшем случае , и если она не возвращает действительный токен , следующий символ читается и он рекурсивно продолжается.

Обработчик набора символов состоит из строки и функции, принимающей три аргумента.Строка представляет собой набор символов, которые будут вызывать функцию, если в этой строке содержится текущий проанализированный символ.Функция может возвращать Нет , если она не может создать токен следующих символов.Функция должна отодвинуть все символы обратно для чтения, чтобы создать Token , если они не могут быть обработаны.Символы, которые были перенесены обратно в сканер, будут возвращены при следующем вызове scanner.read_next_char(), это позволяет читать входной поток байтов, как будто функция никогда не касалась сканера.

A обработчик функции - это функция, принимающая три аргумента, которая возвращает действительный токен или нет , если не удалось создать действительный токен со следующими символамисимвол, который вызывал обработчик, точно так же, как функции, связанные с набором символов выше.

Функция в худшем случае вызывается, когда никакой обработчик не может создатьдействительный токен от текущего и последующих символов, соответствующий описанному выше шаблону.

Каждый обработчик принимает три аргумента: лексер , сканер используется лексером (для чтения следующих символов) и текущим символом, который фактически вызвал обработчик.

Сам лексер и дескрипторrs разделены.

class LexingRules(object):

    def __init__(self):
        self.charset_handlers  = []
        self.function_handlers = []
        self.worst_case        = None

    # convenient methods for adding handlers

class Lexer(object):

    def __init__(self, scanner, rules):
        self.scanner = scanner
        self.rules   = rules
        self.current_token = None
        self.read_next_token()

    def read_next_token(self):
        current_char = self.scanner.current_char

        for charset, handler in self.rules.charset_handlers:
            if current_char in charset:
                token = handler(self, self.scanner, current_char)
                if isinstance(token, Token):
                    self.current_token = token
                    return token
        for function in self.rules.function_handlers:
            token = function(self, self.scanner, current_char)
            if isinstance(token, Token):
                self.current_token = token
                return token
        if self.rules.worst_case:
            token = self.rules.worst_case(self, self.scanner, current_char)
            if isinstance(token, Token):
                self.current_token = token
                return token

        self.scanner.read()
        return self.read_next_token()

Возможный подкласс LexingRules

import string
class MyLexingRules(LexingRules):

    def __init__(self):
        super(MyLexingRules, self).__init__()
        self.charset_handlers.append(string.ascii_letters, self.handle_letters)

    def handle_letters(self, lexer, scanner, char):
        tkn = ''
        while scanner.current_char in string.ascii_letters:
            tkn += scanner.current_char
            scanner.read()
        return Token(tkn, TOKEN_ID_IDENTIFIER)

Цель

Разделениебазовых реализаций Lexer и жестко запрограммированных операций Lexing.

В настоящее время я нахожусь в начале собственного проекта.Я хочу создать расширяемый скомпилированный / переведенный язык.Синтаксис, оператор-расширение и т. Д. Должны быть возможны для создания.

Вопрос

Что вы думаете о дизайне лексера, есть ли у вас на что жаловаться?о, или идея, как его улучшить, добавив больше функциональности?

...