@UuuuuuuuuuuuuuuuNiX

Traceback (most recent call last), как исправить?

Поучаю ошибку:
Traceback (most recent call last):
  File "D:\PythonScript\index.py", line 166, in <module>
    interpreter.interpret(source_code)
  File "D:\PythonScript\index.py", line 145, in interpret
    parsed_data = self.parser.parse()
  File "D:\PythonScript\index.py", line 70, in parse
    parsed_data.append(self.parse_statement())
  File "D:\PythonScript\index.py", line 76, in parse_statement
    raise Exception('Ожидается идентификатор')
Exception: Ожидается идентификатор


При запуске кода:
class Lexer:
    def __init__(self, source_code):
        self.source_code = source_code
        self.position = 0
        self.tokens = []

    def tokenize(self):
        while self.position < len(self.source_code):
            current_char = self.source_code[self.position]
    
            if current_char.isdigit():
                self.tokens.append(self.parse_number())
            elif current_char == '"':
                self.tokens.append(self.parse_string())
            elif current_char.isalpha() or current_char == '_':
                self.tokens.append(self.parse_identifier())
            elif current_char.isspace():
                self.position += 1
                continue
            elif current_char == '(' or current_char == ')':
                self.tokens.append({'type': 'paren', 'value': current_char})
            elif current_char == '=':
                self.tokens.append({'type': 'operator', 'value': current_char})
            elif current_char == '+':
                self.tokens.append({'type': 'operator', 'value': current_char})
            else:
                raise Exception(f'Недопустимый символ: {current_char}')
    
            self.position += 1
    
        return self.tokens

        return self.tokens

    def parse_number(self):
        start_position = self.position
        while self.position < len(self.source_code) and self.source_code[self.position].isdigit():
            self.position += 1
        number = int(self.source_code[start_position:self.position])
        return {'type': 'number', 'value': number}

    def parse_string(self):
        start_position = self.position
        self.position += 1
        while self.position < len(self.source_code) and self.source_code[self.position] != '"':
            self.position += 1
        if self.position >= len(self.source_code):
            raise Exception('Неожиданный конец строки')
        self.position += 1
        string = self.source_code[start_position:self.position]
        return {'type': 'string', 'value': string}

    def parse_identifier(self):
        start_position = self.position
        while self.position < len(self.source_code) and (
                self.source_code[self.position].isalpha() or self.source_code[self.position] == '_'):
            self.position += 1
        identifier = self.source_code[start_position:self.position]
        return {'type': 'identifier', 'value': identifier}


class Parser:
    def __init__(self, tokens):
        self.tokens = tokens
        self.position = 0

    def parse(self):
        parsed_data = []
        while self.position < len(self.tokens):
            parsed_data.append(self.parse_statement())
        return parsed_data

    def parse_statement(self):
        variable = self.tokens[self.position]
        if variable['type'] != 'identifier':
            raise Exception('Ожидается идентификатор')
        self.position += 1
    
        if self.position >= len(self.tokens) or self.tokens[self.position]['value'] != '=':
            raise Exception('Ожидается оператор присваивания')
        self.position += 1
    
        value_token = self.tokens[self.position]
        if value_token['type'] == 'string' or value_token['type'] == 'number' or value_token['type'] == 'identifier':
            assignment = {'type': 'assignment', 'variable': variable['value'], 'value': value_token['value']}
            self.position += 1
            return assignment
        else:
            raise Exception('Ожидается строка, число или идентификатор')
    



class SemanticAnalyzer:
    def __init__(self, parsed_data):
        self.parsed_data = parsed_data

    def analyze(self):
        semantic_data = []
        for statement in self.parsed_data:
            if statement['type'] == 'assignment':
                variable = statement['variable']
                value = self.evaluate_expression(statement['value'])
                semantic_data.append({variable: value})
        return semantic_data

    def evaluate_expression(self, expression):
        try:
            return int(expression)
        except ValueError:
            try:
                return float(expression)
            except ValueError:
                return expression.strip('\"')

    def data_acquisition(self, prompt):
        return input(prompt)


class CodeGenerator:
    def __init__(self, semantic_data):
        self.semantic_data = semantic_data

    def generate(self):
        generated_code = ''
        for statement in self.semantic_data:
            variable = list(statement.keys())[0]
            value = statement[variable]
            generated_code += f"{variable} = {repr(value)}\n"
        return generated_code


class Interpreter:
    def __init__(self):
        self.lexer = None
        self.parser = None
        self.semantic_analyzer = None
        self.code_generator = None

    def interpret(self, source_code):
        self.lexer = Lexer(source_code)
        tokens = self.lexer.tokenize()

        self.parser = Parser(tokens)
        parsed_data = self.parser.parse()

        self.semantic_analyzer = SemanticAnalyzer(parsed_data)
        semantic_data = self.semantic_analyzer.analyze()

        self.code_generator = CodeGenerator(semantic_data)
        generated_code = self.code_generator.generate()

        self.execute_code(generated_code)

    def execute_code(self, code):
        exec(code, {'data_acquisition': self.semantic_analyzer.data_acquisition})


if __name__ == "__main__":
    interpreter = Interpreter()
    source_code = '''
    name = data_acquisition("Enter your name: ")
    age = data_acquisition("Enter your age: ")
    write(name)
    '''
    interpreter.interpret(source_code)


Можете помочь? Очень сильно прошу!
  • Вопрос задан
  • 90 просмотров
Решения вопроса 1
Vindicar
@Vindicar
RTFM!
У тебя парсер строку
name = data_acquisition("Enter your name: ")
разбирает как
name = data_acquisition  <-- присваивание
("Enter your name: ") <-- какой-то левый код

или поработай над приоритетом правил, или тщательнее определяй конец оператора.
Сейчас ты игнорируешь концы строк, а зря. Если у тебя синтаксис питоно-подобный, то они значимы.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы