Как написать интерфейс PLY для написанного от руки лексера? - PullRequest
2 голосов
/ 31 марта 2012

Я пишу компилятор на Python, и я написал рукописный лексер, потому что я не могу понять, как разобрать отступ в PLY.Кроме того, мой лексер использует некоторые операторы yield, например, так:

def scan():
...
    for i in tokens:
        if i[0]: yield Token(self.line, i[0] if i[0] in keywords else "ident", i[0])
            elif i[1]:
                 if "e" in i[1]:
                     base, exp = i[1].split("e")
                     val = float(base) * 10 ** int(exp)
                 else: val = float(i[1])
                 yield Token(self.line, "float", val)
        ... other cases ...

Однако я понял, что для синтаксического анализатора PLY требуется метод token, поэтому я создал такой, который выглядит следующим образом:

def token(self):
    return next(self.scan())

Фактическое сканирование с использованием scan() занимает в среднем 124 мс, согласно моим тестам, но когда я использую анализатор PLY, анализ не начинается через несколько минут.Похоже, у моего метода token() есть проблема.

Также я попытался переименовать метод scan(), чтобы it мог стать интерфейсом.Python возвращает что-то вроде

AttributeError: 'generator' object has no attribute 'type'

Так что, похоже, PLY нужен метод, который будет возвращать один токен за раз.

Есть ли способ переписать метод token(), чтобыон вернет следующую итерацию scan() и не будет такой медленной?

1 Ответ

0 голосов
/ 31 марта 2012

Вам нужно сохранить генератор где-нибудь, например:

def start(...):
   self.lexer = self.scan()

def token(...):
    return next(self.lexer)

Отказ от ответственности: я ничего не знаю о PLY.

...