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

Мячина_7ЛР

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

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

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

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

(МТУСИ)

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

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

«Автоматизация проектирования лексических анализаторов»

по дисциплине «Системное программное обеспечение»

Вариант 24

Выполнила:

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

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

Проверила:

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

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

Москва, 2025 г.

Задание:

Задание 1. Выделение чисел во входной программе

Написать программу, которая заменяла бы во входном тексте целые числа на INTEGER и вещественные числа на FLOAT (и те, и другие – в формате C). Остальной текст оставить без изменений.

Задание 2. Выделение предложений во входном тексте

Написать программу, которая заменяла бы в тексте каждое предложение (то есть, последовательность слов, у первого из которых первая буква заглавная, а заканчивается последовательность точкой), на SENTENCE (N characters), где N число символов в предложении (всех, включая пробельные).

Задание 3. Создание лексического анализатора

Для грамматики вашего языка из предыдущих работ (5 и 6) создайте лексический анализатор с использованием Flex. Анализатор должен работать с программой, путь до файла которой передается при запуске. Вывод лексем осуществить в терминал.

Ход работы:

Язык содержит операторы цикла типа for (…; …; …) do со следующими лексемами:

1. Ключевые слова

  • for - начало оператора цикла

  • do - начало тела цикла

2. Идентификаторы

  • Регулярное выражение: [a-zA-Z][a-zA-Z0-9_]*

  • Примеры: i, sum, result, counter, var1

3. Римские числа

  • Регулярное выражение: [IVXLCDM]+

  • Примеры: I, V, X, L, C, D, M, II, III, XX

4. Операторы присваивания

  • := - оператор присваивания

5. Операторы сравнения

  • < - меньше

  • > - больше

  • = - равно

6. Арифметические операторы

  • + - сложение

  • - - вычитание

  • * - умножение

  • / - деление

7. Разделители и скобки

  • ; - точка с запятой (разделитель частей цикла)

  • ( - левая круглая скобка

  • ) - правая круглая скобка

8. Пробельные символы

  • Пробел, табуляция, перевод строки (игнорируются)

Листинг 1 - Выделение чисел во входной программе

# Создаем файл numbers.lex

cat > numbers.lex << 'EOF'

%{

#include <stdio.h>

%}

%option noyywrap

DIGIT [0-9]

INTEGER {DIGIT}+

FLOAT {DIGIT}+\.{DIGIT}*|{DIGIT}*\.{DIGIT}+

%%

{INTEGER} { printf("INTEGER"); }

{FLOAT} { printf("FLOAT"); }

. { printf("%s", yytext); }

%%

int main() {

yylex();

return 0;

}

EOF

# Создаем тестовый файл для задания 1

cat > test_numbers.txt << 'EOF'

int x = 123;

float y = 45.67;

double z = 89.0;

result = 100 + 23.45 - 67.8;

EOF

Рисунок 1 – test_numbers.txt

Листинг 2 - Выделение предложений во входном тексте

# Создаем файл sentences.lex

cat > sentences.lex << 'EOF'

%{

#include <stdio.h>

%}

%option noyywrap

%x SENTENCE

%%

[A-Z][a-zA-Z.,!? ]*[.!?] {

int length = yyleng;

printf("SENTENCE (%d characters)", length);

}

.|\n {}

%%

int main() {

yylex();

return 0;

}

EOF

Рисунок 2 – test_sentences.txt

Листинг 3 – Создание лексического анализатора

%{

#include <stdio.h>

#include <stdlib.h>

void print_token(const char* type, const char* value);

%}

%option noyywrap

LETTER [a-zA-Z]

DIGIT [0-9]

ID {LETTER}({LETTER}|{DIGIT}|_)*

ROMAN [IVXLCDM]+

ASSIGN ":="

OPERATOR [+\-*/]

COMPARISON [<>=]

DELIMITER [;()]

WHITESPACE [ \t\n]

%%

"for" { print_token("FOR", yytext); }

"do" { print_token("DO", yytext); }

{ASSIGN} { print_token("ASSIGN", yytext); }

{COMPARISON} { print_token("COMPARISON", yytext); }

{OPERATOR} { print_token("OPERATOR", yytext); }

{ROMAN} { print_token("ROMAN", yytext); }

";" { print_token("SEMICOLON", yytext); }

"(" { print_token("LPAREN", yytext); }

")" { print_token("RPAREN", yytext); }

{ID} { print_token("IDENTIFIER", yytext); }

{WHITESPACE} { /* ignore */ }

. { printf("ERROR: Invalid character '%s'\n", yytext); }

%%

void print_token(const char* type, const char* value) {

printf("%s: '%s'\n", type, value);

}

int main(int argc, char *argv[]) {

if (argc > 1) {

FILE *file = fopen(argv[1], "r");

if (file) {

yyin = file;

} else {

fprintf(stderr, "Cannot open file: %s\n", argv[1]);

return 1;

}

} else {

printf("Usage: %s <filename>\n", argv[0]);

return 1;

}

printf("=== LEXICAL ANALYSIS RESULTS ===\n");

yylex();

if (yyin != stdin) {

fclose(yyin);

}

return 0;

}

Рисунок 3 – program.txt

Листинг 4 - Скрипт для автоматизации

# Создаем скрипт для автоматизации

cat > run_all.sh << 'EOF'

#!/bin/bash

echo "=== Компиляция всех программ Flex ==="

# Задание 1: Числа

echo "1. Компиляция numbers.lex..."

flex numbers.lex

gcc -o numbers lex.yy.c

if [ $? -eq 0 ]; then

echo " ✓ Успешно скомпилировано: numbers"

else

echo " ✗ Ошибка компиляции numbers"

exit 1

fi

# Задание 2: Предложения

echo "2. Компиляция sentences.lex..."

flex sentences.lex

gcc -o sentences lex.yy.c

if [ $? -eq 0 ]; then

echo " ✓ Успешно скомпилировано: sentences"

else

echo " ✗ Ошибка компиляции sentences"

exit 1

fi

# Задание 3: Арифметические выражения

echo "3. Компиляция arithmetic.lex..."

flex arithmetic.lex

gcc -o arithmetic lex.yy.c

if [ $? -eq 0 ]; then

echo " ✓ Успешно скомпилировано: arithmetic"

else

echo " ✗ Ошибка компиляции arithmetic"

exit 1

fi

echo ""

echo "=== Тестирование программ ==="

echo ""

echo "1. Тестирование numbers (выделение чисел):"

echo "Входные данные:"

cat test_numbers.txt

echo ""

echo "Результат:"

./numbers < test_numbers.txt

echo ""

echo "2. Тестирование sentences (выделение предложений):"

echo "Входные данные:"

cat test_sentences.txt

echo ""

echo "Результат:"

./sentences < test_sentences.txt

echo ""

echo "3. Тестирование arithmetic (лексический анализ):"

echo "Анализируемая программа:"

cat program.txt

echo ""

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

./arithmetic program.txt

# Очистка временных файлов

echo ""

echo "=== Очистка временных файлов ==="

rm -f lex.yy.c numbers sentences arithmetic

echo "Временные файлы удалены"

echo ""

echo "=== Все задания выполнены! ==="

EOF

Выполнение скрипта:

Рисунок 4 – Результат (1)

Рисунок 5 – Результат (2)

Рисунок 6 – Результат (3)

Рисунок 7 – Результат (4)

Рисунок 8 – Результат (5)

Рисунок 5 – Результат (6)

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