Мячина_7ЛР
.docxМИНИСТЕРСТВО ЦИФРОВОГО РАЗВИТИЯ, СВЯЗИ И МАССОВЫХ КОММУНИКАЦИЙ РОССИЙСКОЙ ФЕДЕРАЦИИ
Ордена Трудового Красного Знамени федеральное государственное бюджетное образовательное учреждение высшего образования
Московский технический университет связи и информатики
(МТУСИ)
Кафедра «Системное программирование»
Лабораторная работа №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)
