Python. Язык программирования

import ply.yacc as yacc

# Лексический анализатор
tokens = (
    'NAME', 'NUMBER',
    'PLUS', 'MINUS', 'TIMES', 'DIVIDE', 'EQUALS',
    'LPAREN', 'RPAREN', 'PRINT',
    'PLUS_EQUALS', 'MINUS_EQUALS', 'TIMES_EQUALS', 'DIVIDE_EQUALS',
    'IF', 'ELIF', 'ELSE', 'COLON',
    'GT', 'LT', 'EQ'
)

# Регулярные выражения для токенов
t_PLUS    = r'\+'
t_MINUS   = r'-'
t_TIMES   = r'\*'
t_DIVIDE  = r'/'
t_EQUALS  = r'='
t_LPAREN  = r'\('
t_RPAREN  = r'\)'
t_NAME    = r'[a-zA-Z_][a-zA-Z0-9_]*'
t_PLUS_EQUALS = r'\+='
t_MINUS_EQUALS = r'-='
t_TIMES_EQUALS = r'\*='
t_DIVIDE_EQUALS = r'/='
t_PRINT   = r'p'
t_IF      = r'if'
t_ELIF    = r'elif'
t_ELSE    = r'else'
t_COLON   = r':'
t_GT      = r'>'
t_LT      = r'<'
t_EQ      = r'=='

def t_NUMBER(t):
    r'\d+'
    t.value = int(t.value)
    return t

# Пропуск пробелов, табуляций и символов новой строки
t_ignore = ' \t\n'

# Обработка ошибок
def t_error(t):
    print(f"Недопустимый символ '{t.value[0]}'")
    t.lexer.skip(1)

# Создание лексера
lexer = lex.lex()

# Синтаксический анализатор
precedence = (
    ('left', 'PLUS', 'MINUS'),
    ('left', 'TIMES', 'DIVIDE'),
    ('left', 'GT', 'LT', 'EQ'),
)

# Словарь для хранения переменных
variables = {}

def p_statements(p):
    '''statements : statement
                  | statements statement'''
    if len(p) == 2:
        p[0] = [p[1]]
    else:
        p[0] = p[1] + [p[2]]

def p_statement_assign(p):
    'statement : NAME EQUALS expression'
    variables[p[1]] = p[3]

def p_plus_equals(p):
    'statement : NAME PLUS_EQUALS expression'
    if p[1] in variables:
        variables[p[1]] += p[3]
    else:
        print(f"Переменная '{p[1]}' не определена")

def p_minus_equals(p):
    'statement : NAME MINUS_EQUALS expression'
    if p[1] in variables:
        variables[p[1]] -= p[3]
    else:
        print(f"Переменная '{p[1]}' не определена")

def p_times_equals(p):
    'statement : NAME TIMES_EQUALS expression'
    if p[1] in variables:
        variables[p[1]] *= p[3]
    else:
        print(f"Переменная '{p[1]}' не определена")

def p_divide_equals(p):
    'statement : NAME DIVIDE_EQUALS expression'
    if p[1] in variables:
        variables[p[1]] /= p[3]
    else:
        print(f"Переменная '{p[1]}' не определена")

def p_statement_print(p):
    'statement : PRINT LPAREN expression RPAREN'
    print(p[3])

def p_statement_if(p):
    '''statement : IF expression COLON statements
                 | IF expression COLON statements ELSE COLON statements
                 | IF expression COLON statements elif_clauses
                 | IF expression COLON statements elif_clauses ELSE COLON statements'''
    if p[2]:
        p[0] = p[4]
    elif len(p) == 6:
        p[0] = p[6]
    elif len(p) == 8:
        p[0] = p[6] + p[8]
    else:
        p[0] = []

def p_elif_clauses(p):
    '''elif_clauses : ELIF expression COLON statements
                    | elif_clauses ELIF expression COLON statements'''
    if p[2]:
        p[0] = p[4]
    else:
        p[0] = []

def p_expression_binop(p):
    '''expression : expression PLUS expression
                  | expression MINUS expression
                  | expression TIMES expression
                  | expression DIVIDE expression
                  | expression GT expression
                  | expression LT expression
                  | expression EQ expression'''
    if p[2] == '+':
        p[0] = p[1] + p[3]
    elif p[2] == '-':
        p[0] = p[1] - p[3]
    elif p[2] == '*':
        p[0] = p[1] * p[3]
    elif p[2] == '/':
        p[0] = p[1] / p[3]
    elif p[2] == '>':
        p[0] = p[1] > p[3]
    elif p[2] == '<':
        p[0] = p[1] < p[3]
    elif p[2] == '==':
        p[0] = p[1] == p[3]

def p_expression_number(p):
    'expression : NUMBER'
    p[0] = p[1]

def p_expression_name(p):
    'expression : NAME'
    try:
        p[0] = variables[p[1]]
    except LookupError:
        print(f"Переменная '{p[1]}' не определена")
        p[0] = 0

def p_error(p):
    if p:
        print(f"Синтаксическая ошибка в '{p.value}'")
    else:
        print("Синтаксическая ошибка: неожиданный конец файла")

# Создание парсера
parser = yacc.yacc()

# Функция для интерпретации кода
def interpret(code):
    parser.parse(code)

# Пример использования
code = """
a = 5
b = 4
if a > b:
    p(1)
elif a < b:
    p(2)
    p(2)
else:
    p(3)
"""

interpret(code)

Суть кода: выполнить code. функция p это как print в python, условные операторы также работают как в python.

Почему вывод: Синтаксическая ошибка в 'a' ? Если ожидается: 1


Ответы (0 шт):