лаба 4
.docx
Федеральное агентство связи ордена Трудового Красного Знамени Федеральное государственное бюджетное образовательное учреждение высшего профессионального образования Московский Технический Университет связи и информатики
Кафедра «Математической кибернетики и информационных технологий»
Лабораторная работа №4 Лексический анализатор
Выполнила
студентка группы БСТ1904
Пантелеева К.А.
Вариант №8
Оглавление
1 Задание 3
2 Ход лабораторной работы 3
2.1 Код программы 3
2.2 Тестирование программы 7
3 Вывод 8
Список использованных источников 8
1 Задание
Написать программу, которая выполняет лексический анализ входного текста в соответствии с заданием и порождает таблицу лексем с указанием их типов. Программа должна выдавать сообщения о наличии во входном тексте ошибок, которые могут быть обнаружены на этапе лексического анализа.
Входной язык содержит логические выражения, разделённые символом ; (точка с запятой). Логические выражения состоят из идентификаторов, констант true и false, знака присваивания (:=), операций or, xor, and, not и круглых скобок.
2 Ход лабораторной работы
2.1 Код программы
#include <stdio.h>
#include <iostream>
#include <conio.h>
#include <ctype.h>
#include <vector>
#include <string>
#define BUFSIZE 80
std::vector<std::string> TD = { ";", "$"};
std::vector<std::string> TID;
std::vector<std::string> TSIM = { "True", "False" };
std::vector<std::string> TW = { "xor", "or", "and", "not", "(", ")" };
char buf[BUFSIZE];
char T = 'True';
char F = 'False';
int c;
int j;
int line = 0;
enum state { H, ID, W, SIM, ASN, DLM, ER, END };
enum state TC;
FILE* fp;
errno_t err;
unsigned int currentfilepos = 0;
void add(void) {
buf[currentfilepos] = c;
currentfilepos++;
};
void clear(void) {
std::fill_n(buf, BUFSIZE, NULL);
currentfilepos = 0;
};
int look(std::vector<std::string>& tab) {
std::string lex(buf);
if (lex == "") lex = c;
std::vector<std::string>::iterator itr = std::find(tab.begin(), tab.end(), lex);
if (itr != tab.cend()) {
return(int(std::distance(tab.begin(), itr)));
}
else {
return -1;
}
};
int putl(std::vector<std::string>& tab) {
std::string lex(buf);
if (lex == "") lex = c;
int pos = look(tab);
if (pos != -1) {
return(pos);
}
else {
tab.push_back(lex);
return(int(tab.size() - 1));
}
};;
void makelex(int b, int k) {
const char* value;
const char* type;
setlocale(LC_ALL, "Rus");
printf("%d строка: ", line);
switch (b) {
case W:
type = "Оператор";
value = TW.at(k).c_str();
printf("%8s №%1d %15s\n", type, k, value);
break;
case DLM:
type = "Разделитель";
value = TD.at(k).c_str();
printf("%8s №%1d %12s\n", type, k, value);
break;
case ID:
type = "Идентификатор";
value = TID.at(k).c_str();
printf("%8s №%1d %6s\n", type, k, value);
break;
case SIM:
type = "Константа";
value = TSIM.at(k).c_str();
printf("%8s №%1d %14s\n", type, k, value);
break;
case ASN:
type = "Присваивание";
value = ":=";
printf("%8s №%1d %7s\n", type, k, value);
break;
}
};
void gc(void) {
c = fgetc(fp);
}
void id_or_word(void) {
j = look(TW);
if (j != -1) makelex(W, j);
else {
j = putl(TID); makelex(ID, j);
}
}
void is_sim(void) {
j = look(TSIM);
if (j != -1) {
makelex(SIM, j);
gc();
TC = H;
}
else
{
TC = ER;
}
}
void is_assign(void) {
std::string lex(buf);
if (lex == ":=") {
makelex(ASN, 0);
gc();
TC = H;
}
else {
TC = ER;
}
}
void is_dlm(void) {
j = look(TD);
if (j != -1) {
makelex(DLM, j);
gc();
TC = H;
}
else {
TC = ER;
}
}
void scan(void) {
TC = H;
err = fopen_s(&fp, "flex.txt", "r");
if (err == 0)
{
setlocale(LC_ALL, "Rus");
printf("Файл 'flex.txt' был успешно открыт\n");
gc();
do {
switch (TC) {
case H:
if (c == ' ') gc();
else if (c == '\n') {
line++; gc();
}
else if ((c == T ) | (c == F) ){
TC = SIM;
}
else if (isalpha(c) | (isdigit(c))) {
clear();
add(); gc();
TC = ID;
}
else if (c == ':') {
clear();
add(); gc();
TC = ASN;
}
else if (c == '$') {
makelex(DLM, putl(TD));
TC = END;
}
else TC = DLM;
break;
case DLM:
clear();
is_dlm();
break;
case ID:
if (isalpha(c) || isdigit(c)) {
add(); gc();
}
else {
id_or_word();
TC = H;
}
break;
case SIM:
if ((c == True) | (c == False)) {
is_sim();
TC = H;
}
break;
case ASN:
if (c == '=')
{
add();
is_assign();
}
else
{
TC = H;
}
break;
}
} while (TC != END && TC != ER);
{
if (TC == ER)
{
printf("%d строка: ", line);
printf("<%8s,%02d> %12c - Неизвестная лексема\n", "ERROR", 0, c);
}
else printf("Лексический анализ программы был проведён успешно\n");
}
fclose(fp);
}
else
{
printf("Файл 'flex.txt' не был открыт\n");
}
}
int main()
{
scan();
_getch();
return 0;
}
2.2 Тестирование программы
Входные данные представлены на рисунке 1.
Рисунок 1 – Данные
Результат работы программы представлен на рисунке 2.
Рисунок 2 – Результат работы
Теперь посмотрим, как работает программа, когда текст с ошибкой. Для этого изменим входные данные (рисунок 3).
Рисунок 3 – Данные с ошибкой
А результат работы приведен на рисунке 4.
Рисунок 4 – Результат работы
3 Вывод
В результате данной работы я научилась разрабатывать лексический анализатор в Microsoft Visual Studio 2019 на языке С++.
Список использованных источников
1) ГОСТ 7.1-2001 СИБИД. Библиографическая запись. Библиографическое описание. Общие требования и правила составления [электронный ресурс] URL: https://internet-law.ru/gosts/gost/1560 (дата обращения 28.03.2020)
2) ГОСТ 7.32-2001 СИБИД. Отчет о научно-исследовательской работе. Структура и правила оформления (с Изменением N 1) [электронный ресурс] URL: http://docs.cntd.ru/document/gost-7-32-2001-sibid (дата обращения 28.03.2020)