Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Мячина_6ЛР

.docx
Скачиваний:
0
Добавлен:
02.08.2026
Размер:
166 Кб
Скачать

МИНИСТЕРСТВО ЦИФРОВОГО РАЗВИТИЯ, СВЯЗИ И МАССОВЫХ КОММУНИКАЦИЙ РОССИЙСКОЙ ФЕДЕРАЦИИ

Ордена Трудового Красного Знамени федеральное государственное бюджетное образовательное учреждение высшего образования

Московский технический университет связи и информатики

(МТУСИ)

Кафедра «Системное программирование»

Лабораторная работа №6

«Проектирование лексического анализатора»

по дисциплине «Построение простейшего дерева вывода»

Вариант 24

Выполнила:

студентка группы БФИ2203

Мячина Лада Андреевна

Проверила:

Старший преподаватель

Алексанян Диана Ашотовна

Москва, 2025 г.

Задание:

  1. Выбрать вариант задания в соответствии с номером в журнале.

  2. Построить множества крайних левых и крайних правых символов, множества крайних правых и крайних левых терминальных символов и матрицу операторного предшествования для заданной грамматики (если для построения синтаксического распознавателя предполагается использовать другой механизм, отличный от грамматик операторного предшествования, то форму его надо предварительно согласовать).

  3. Заполнить матрицу предшествования для грамматики

  4. Написать и отладить программу.

Подготовить и защитить отчет, продемонстрировать работу программы.

Вариант для выполнения работы представлен ниже:

Вариант

№ грамматики

Допустимые лексемы входного языка

8, 24

4

Идентификаторы, римские числа

Ход работы:

Исходная грамматика представлена на рисунке 1

Рисунок 1 – Исходная грамматика

Грамматика в форме Бэкуса-Наура представлена на рисунке 2.

Рисунок 2 – Грамматика в форме Бэкуса-Наура

Таблица 1 – крайне левые и крайне правые символы грамматики

Символ U

L (U)

R (U)

S

L(F) = {if, a}

R(F) = {else, a, ;}

F

{if, a}

{else, a, ;}

T

L(F) ∪ {;} = {if, a, ;}

R(F) ∪ {;} = {else, a, ;}

E

{a}

{a}

Таблица 2 – крайне левые и крайне правые символы грамматики

Символ U

L (U)

R (U)

S

{if, a}

{else, a, ;}

F

{if, a}

{else, a, ;}

T

{if, a, ;}

{else, a, ;}

E

{a}

{a}

Таблица 3 – Матрица операторного предшествования

if

then

else

a

:=

<

>

=

if

=

<

then

<

=

<

else

<

>

<

a

>

>

>

=

=

=

=

:=

=

<

=

>

=

=

=

Листинг программы для выполнения ЛР:

import re

# Класс для представления лексемы

class Token:

def __init__(self, type, value):

self.type = type

self.value = value

def __str__(self):

return f"{self.type}('{self.value}')"

def __repr__(self):

return self.__str__()

# Лексический анализатор

class Lexer:

def __init__(self):

self.keywords = {'if', 'then', 'else'}

self.operators = {':=', '<', '>', '=', ';'}

def tokenize(self, text):

tokens = []

pos = 0

while pos < len(text):

# Пропускаем пробелы

if text[pos].isspace():

pos += 1

continue

# Проверяем ключевые слова и идентификаторы

if text[pos].isalpha():

# Извлекаем слово

word = ''

while pos < len(text) and (text[pos].isalpha() or text[pos] == '_' or text[pos].isdigit()):

word += text[pos]

pos += 1

if word in self.keywords:

tokens.append(Token(word.upper(), word))

else:

# Проверяем, является ли слово римским числом

if self.is_roman_numeral(word):

tokens.append(Token('A', word))

else:

tokens.append(Token('A', word)) # Идентификатор

# Проверяем операторы

elif text[pos] == ':' and pos + 1 < len(text) and text[pos + 1] == '=':

tokens.append(Token('ASSIGN', ':='))

pos += 2

elif text[pos] in self.operators:

tokens.append(Token(text[pos], text[pos]))

pos += 1

else:

raise ValueError(f"Неизвестный символ: {text[pos]}")

return tokens

def is_roman_numeral(self, s):

# Простая проверка на римские числа

roman_pattern = r'^[IVXLCDM]+$'

return bool(re.match(roman_pattern, s.upper()))

# Класс для представления узла дерева разбора

class ParseTreeNode:

def __init__(self, symbol, value=None):

self.symbol = symbol

self.value = value

self.children = []

def add_child(self, child):

self.children.append(child)

def __str__(self, level=0):

result = " " * level + f"{self.symbol}"

if self.value:

result += f"({self.value})"

result += "\n"

for child in self.children:

result += child.__str__(level + 1)

return result

# Улучшенный синтаксический анализатор

class ImprovedParser:

def __init__(self):

self.tokens = []

self.pos = 0

self.current_token = None

def parse(self, tokens):

self.tokens = tokens

self.pos = 0

self.current_token = self.tokens[0] if self.tokens else None

root = ParseTreeNode('S')

f_node = self.parse_F()

root.add_child(f_node)

return root

def advance(self):

self.pos += 1

if self.pos < len(self.tokens):

self.current_token = self.tokens[self.pos]

else:

self.current_token = None

def parse_F(self):

if self.current_token and self.current_token.type == 'IF':

return self.parse_if_statement()

else:

return self.parse_assignment()

def parse_if_statement(self):

# Обрабатываем 'if'

if_node = ParseTreeNode('F', 'if-then-else')

if_node.add_child(ParseTreeNode('IF', 'if'))

self.advance()

# Обрабатываем E (условие)

e_node = self.parse_E()

if_node.add_child(e_node)

# Обрабатываем 'then'

if self.current_token and self.current_token.type == 'THEN':

if_node.add_child(ParseTreeNode('THEN', 'then'))

self.advance()

else:

raise SyntaxError("Ожидается 'then'")

# Обрабатываем T или F после then

if self.current_token and self.current_token.type == ';':

t_node = self.parse_T()

if_node.add_child(t_node)

else:

f_node = self.parse_F()

if_node.add_child(f_node)

# Обрабатываем 'else' (если есть)

if self.current_token and self.current_token.type == 'ELSE':

if_node.add_child(ParseTreeNode('ELSE', 'else'))

self.advance()

# Обрабатываем F после else

f_node_else = self.parse_F()

if_node.add_child(f_node_else)

return if_node

def parse_T(self):

t_node = ParseTreeNode('T')

# Первый F (может отсутствовать)

if self.current_token and self.current_token.type == 'A':

f_node1 = self.parse_assignment()

t_node.add_child(f_node1)

# Первая ;

if self.current_token and self.current_token.type == ';':

t_node.add_child(ParseTreeNode(';', ';'))

self.advance()

else:

raise SyntaxError("Ожидается ';'")

# E

e_node = self.parse_E()

t_node.add_child(e_node)

# Вторая ;

if self.current_token and self.current_token.type == ';':

t_node.add_child(ParseTreeNode(';', ';'))

self.advance()

else:

raise SyntaxError("Ожидается ';'")

# Второй F (может отсутствовать)

if self.current_token and self.current_token.type == 'A':

f_node2 = self.parse_assignment()

t_node.add_child(f_node2)

return t_node

def parse_E(self):

e_node = ParseTreeNode('E')

# Первый A

if self.current_token and self.current_token.type == 'A':

e_node.add_child(ParseTreeNode('A', self.current_token.value))

self.advance()

else:

raise SyntaxError("Ожидается идентификатор или число")

# Оператор сравнения

if self.current_token and self.current_token.type in ['<', '>', '=']:

e_node.add_child(ParseTreeNode(self.current_token.type, self.current_token.value))

self.advance()

else:

raise SyntaxError("Ожидается оператор сравнения")

# Второй A

if self.current_token and self.current_token.type == 'A':

e_node.add_child(ParseTreeNode('A', self.current_token.value))

self.advance()

else:

raise SyntaxError("Ожидается идентификатор или число")

return e_node

def parse_assignment(self):

assign_node = ParseTreeNode('F', 'assignment')

# Левый A

if self.current_token and self.current_token.type == 'A':

assign_node.add_child(ParseTreeNode('A', self.current_token.value))

self.advance()

else:

raise SyntaxError("Ожидается идентификатор или число")

# ASSIGN

if self.current_token and self.current_token.type == 'ASSIGN':

assign_node.add_child(ParseTreeNode('ASSIGN', ':='))

self.advance()

else:

raise SyntaxError("Ожидается ':='")

# Правый A

if self.current_token and self.current_token.type == 'A':

assign_node.add_child(ParseTreeNode('A', self.current_token.value))

self.advance()

else:

raise SyntaxError("Ожидается идентификатор или число")

return assign_node

# Главная функция

def main():

print("Лабораторная работа №6: Построение простейшего дерева вывода")

print("Вариант 24: Идентификаторы, римские числа")

print("Грамматика:")

print("S → F")

print("F → if E then T else F | if E then F | a := a")

print("T → F ; E ; F | ; E ; F | F ; E ; | ; E ;")

print("E → a < a | a > a | a = a")

print()

# Пример входных данных

test_input = "if x := V then ; y > X ; else z := XX"

print(f"Входные данные: {test_input}")

print()

# Лексический анализ

lexer = Lexer()

try:

tokens = lexer.tokenize(test_input)

print("Результат лексического анализа:")

for token in tokens:

print(f" {token}")

print()

except Exception as e:

print(f"Ошибка лексического анализа: {e}")

return

# Синтаксический анализ

parser = ImprovedParser()

try:

parse_tree = parser.parse(tokens)

print("Дерево разбора:")

print(parse_tree)

print("Синтаксический анализ завершен успешно!")

except SyntaxError as e:

print(f"Ошибка синтаксического анализа: {e}")

except Exception as e:

print(f"Общая ошибка: {e}")

if __name__ == "__main__":

main()

Файл без ошибок:

Файл с ошибками

Соседние файлы в предмете Системное программное обеспечение