Как определить экспоненциальные числа в модуле python SLY? - PullRequest
0 голосов
/ 09 июля 2020

Я пишу лексер для игрушечного языка программирования, используя модуль python SLY . Но я не могу обнаружить экспоненциальные числа, такие как -123e456 или 123.456e-789, и так далее с моим кодом. Он определяет "e" или "E" как переменную. Как я могу изменить свой код, чтобы он мог обнаруживать положительные или отрицательные целые числа, числа с плавающей запятой и экспоненциальные члены, такие как 123, -123.456, -123e456, -123.456e-789 и так далее? Так может ли кто-нибудь помочь мне с этой проблемой. Какой должна быть схема номера ?? вот мой код.

from sly import Lexer

class CalcLexer(Lexer):
    tokens = {ID, NUMBER, PLUS, MINUS, TIMES, DIVIDE, POWER, MODULUS, ASSIGN, EQUAL, NOT_EQUAL, GREATER,  GREATER_EQUAL, LESS, LESS_EQUAL, LPAREN, RPAREN}
    ignore = ' \t'
    # Other ignored patterns
    ignore_comment = r'\#.*'
    ignore_newline = r'\n+'
    NUMBER = r"(?<![a-df-zA-DF-Z:])[-+]?\d*\.?\d+"
    ID = r'[a-zA-Z_][a-zA-Z0-9_]*'
    PLUS = r'\+'
    MINUS = r'-'
    TIMES = r'\*'
    DIVIDE = r'/'
    POWER = r'\^'
    MODULAS = r'%'
    NOT_EQUAL = r'!='
    EQUAL = r'=='
    ASSIGN = r'='
    GREATER = r'>'
    GREATER_EQUAL = r'>='
    LESS_EQUAL = r'<='
    LESS = r'<'
    LPAREN= r'\('
    RPAREN = r'\)'

    #@_(r"(?<![a-df-zA-DF-Z:])[-+]?\d*\.?\d+")
    def NUMBER(self, t):
        if t.value.count('.') == 0: t.value = int(t.value)
        elif t.value.count('.') < 2: t.value = eval(t.value)
        else: print("ERROR"); break
        return t

if __name__ == '__main__':
    data = "abc_123_X = a + 123e45 -c * d / e ^(f%g)"
    lexer = CalcLexer()
    for tok in lexer.tokenize(data):
        print("type = %r, value = %r" %(tok.type, tok.value))

1 Ответ

0 голосов
/ 09 июля 2020

Это довольно стандартное регулярное выражение для чисел с плавающей запятой:

([0-9]*\.[0-9]+|[0-9]+\.?)([Ee][+-]?[0-9]+)?

Первая часть соответствует любой последовательности цифр с возможной десятичной запятой, при условии, что есть хотя бы один di git. (Это позволяет избежать распознавания .e3 как числа с плавающей запятой.) Вторая часть (необязательная) соответствует экспоненте.

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

...