При попытке парсинга кода регулярными выражениями выводится ошибка
Я делаю скриптовый язык, и у меня проблема разбиения кода на токены. У меня есть файл Lexer.py:
from game.sl.TokenType import token_types_list
from game.sl.Token import *
class Lexer:
def __init__(self, code):
self.code = code
self.pos = 0
self.token_list = []
def lex_analysis(self):
while self.next_token():
self.next_token()
self.token_list = self.filter_list()
return self.token_list
def filter_list(self):
"""
Фильтруем список токенов от пробелов
"""
token_list = []
for token in self.token_list:
if token.type != token_types_list['SPACE']:
token_list.append(token)
return token_list
def next_token(self):
"""
Функция для разбиения кода на токены
Мы берем из типа токена его регулярное выражение, смотрим, совпадает ли
он с текущим токеном, и если да, то делаем новый токен, если нет,
то берем новую регулярку из словаря и
повторяем до тех пор, пока не закончится код
"""
if self.pos >= len(self.code):
return False
for token_type in token_types_list.values():
result = re.match(r'^' + token_type.regex, self.code[int(self.pos):])
if result and result.group(0):
token = Token(token_type, result.group(0), self.pos)
self.pos += len(result.group(0))
self.token_list.append(token)
return True
Также имеется файл TokenType.py, в котором задаются все типы токенов, которые будут использоваться в языке:
class TokenType:
def __init__(self, name, regex):
self.name = name
self.regex = regex
token_types_list = {
'PLUS': TokenType('PLUS', r'+'),
'MINUS': TokenType('MINUS', r'-'),
'ASSIGN': TokenType('ASSIGN', r'='),
'CONDITIONAL': TokenType('CONDITIONAL', r'if'),
'EQUAL': TokenType('EQUAL', r'=='),
'COLON': TokenType('COLON', r':'),
'COMMA': TokenType('COMMA', r','),
'SEMICOLON': TokenType('SEMICOLON', r';'),
'SET_IMAGE': TokenType('SET_IMAGE', r'set_image'),
'SET_SPRITES': TokenType('SET_SPRITES', r'set_sprites'),
'SET_SPRITE': TokenType('SET_SPRITE', r'set_sprite'),
'SET_AUDIO': TokenType('SET_AUDIO', r'set_audio'),
'MIX_AUDIO': TokenType('MIX_AUDIO', r'mix_audio'),
'SET_TEXT': TokenType('SET_TEXT', r'set_text'),
'ADD_DIALOG': TokenType('ADD_DIALOG', r'add_dialog'),
'SPACE': TokenType('SPACE', r'[ \n\t\r]'),
'LPAR': TokenType('LPAR', r'\('),
'RPAR': TokenType('RPAR', r'\)'),
'STRING': TokenType('STRING', r'".*"'),
'NUMBER': TokenType('NUMBER', r'[0-9]*'),
'VARIABLE': TokenType('VARIABLE', r'\w*'),
}
И, собственно, конструктор токена в файле Token.py:
from game.sl.TokenType import *
class Token:
def __init__(self, type: TokenType, text, pos):
self.type = type
self.text = text
self.pos = pos
На вход лексер получает такой исходный код:
set_image "resources/arts/street.img";
set_audio "resources/audio/street.mp3";
set_text "Text";
choice = add_dialog "first" "second" "third";
Но при запуске лексера выводится ошибка:
re.error: nothing to repeat at position 1
Если посмотреть, что прилетает в re.match, то получится такой текст:
print('^' + token_type.regex, ' ', self.code[self.pos:], ' ', self.pos)
# ^+ set_image "resources/arts/street.img";
# set_audio "resources/audio/street.mp3";
# set_text "Text";
# choice = add_dialog "first" "second" "third"; 0
Почему она появляется?
Ответы (1 шт):
Автор решения: Kewsen
→ Ссылка
Я понял в чем причина. Ошибка прилетала, когда цикл доходил до +, -, =, и т.д.
Я просто поставил перед ними \ и все заработало.