psychotrip

Untitled

Jan 23rd, 2024
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.96 KB | None | 0 0
  1. /*
  2. * Написать программу, которая должна читать входные данные из текстового файла (например, имеющего имя «input.txt»),
  3. * и выдавать результат работы в текстовый файл (например, имеющий имя «output.txt»).
  4. * Для ввода и вывода данных допускается использование в программе визуального интерфейса вместо файлового ввода/вывода.
  5. *
  6. * Вариант 1. На вход программы подается описание переменных на выбранном языке (Pascal, C++, C# и т.д.).
  7. * Программа должна проанализировать его при помощи регулярного выражения и выдать результат проверки.
  8. * При этом программа может быть написана на одном языке программирования,
  9. * но проверять правильность описания переменных на другом языке. Это может быть:
  10. * 1 Сообщение о том, что описание корректное;
  11. * 2 Сообщение о синтаксической ошибке. Указывать тип ошибки не обязательно,
  12. * требуется только указать строку и позицию в строке входного файла, где наблюдается ошибка.
  13. * Достаточно находить только первую ошибку в описании.
  14. * 3 Сообщение о дублировании имен переменных. В этом случае на выходе программы необходимо указать имя дублируемой
  15. * переменной, а также строку и позицию в строке, где встретился дубликат.
  16. */
  17.  
  18. #include <iostream>
  19. #include <fstream>
  20. #include <regex>
  21. #include <string>
  22. #include <unordered_set>
  23. #include <windows.h>
  24.  
  25. using namespace std;
  26.  
  27. int main() {
  28. SetConsoleOutputCP(CP_UTF8);
  29.  
  30. ifstream inputFile("input.txt");
  31. ofstream outputFile("output.txt");
  32.  
  33. // Проверка успешности открытия файлов ввода/вывода.
  34. if (!inputFile.is_open() || !outputFile.is_open()) {
  35. cerr << "Не удалось открыть файлы ввода/вывода." << endl;
  36. return 1;
  37. }
  38.  
  39. // Регулярное выражение для анализа описания переменных.
  40. string regexPattern =
  41. "\\b"
  42. /*
  43. * Это граница слова (word boundary). Это используется для того, чтобы удостовериться, что ключевые слова
  44. * (например, "int", "double") полностью соответствуют словам, а не являются частью других слов.
  45. */
  46. "(?:int|long int|double|float|char|short int|long double|long|short)?"
  47. /*
  48. * Это некаптурирующая группа, которая представляет собой ключевые слова для объявления переменных.
  49. * Знак вопроса в конце делает эту группу необязательной.
  50. */
  51. "\\s+"
  52. // Это один или более пробельных символов.
  53. "([a-zA-Z_][a-zA-Z0-9_]*)"
  54. /*
  55. * Это группа захвата для имени переменной. Она начинается с буквы или подчеркивания,
  56. * за которыми могут следовать буквы, цифры или подчеркивания.
  57. */
  58. "\\s*(?:\\[([0-9]+)\\])?"
  59. /*
  60. * Это некаптурирующая группа, представляющая собой опциональные квадратные скобки
  61. * с числовым значением внутри. Это может использоваться для обозначения размера массива.
  62. */
  63. "(?:\\[([0-9]+)\\])?\\s*(?:,\\s*([a-zA-Z_]\\w*)\\s*(?:\\[([0-9]+)\\])?(?:\\[([0-9]+)\\])?\\s*)*"
  64. /*
  65. * Это часть, которая позволяет определить
  66. * список переменных, разделенных запятой. Это повторяющаяся часть, где после первой переменной может
  67. * следовать запятая и дополнительные переменные.
  68. */
  69. ";";
  70. // Это точка с запятой в конце, обозначающая конец оператора объявления переменных.
  71.  
  72. regex variablePattern(regexPattern);
  73.  
  74. unordered_set<string> variableNames;
  75.  
  76. string line;
  77. int lineNumber = 0;
  78. bool hasErrors = false;
  79.  
  80. // Чтение файла построчно.
  81. while (getline(inputFile, line)) {
  82. lineNumber++;
  83.  
  84. smatch match;
  85. // Поиск соответствия регулярному выражению в текущей строке.
  86. if (regex_search(line, match, variablePattern)) {
  87. // Проверка, соответствует ли вся строка описанию переменных.
  88. string syntaxCheck = match[0];
  89. if (syntaxCheck != line) {
  90. outputFile << "Синтаксическая ошибка в строке " << lineNumber << ", позиция " << (match.position() + 1)
  91. << endl;
  92. hasErrors = true;
  93. }
  94.  
  95. // Проверка дубликатов имен переменных.
  96. for (size_t i = 1; i < match.size(); ++i) {
  97. string variables = match[i];
  98. istringstream variableStream(variables);
  99. string variableName;
  100.  
  101. // Обработка списка переменных в текущей группе.
  102. while (getline(variableStream, variableName, ',')) {
  103. variableName.erase(remove_if(variableName.begin(), variableName.end(), ::isspace),
  104. variableName.end());
  105.  
  106. // Проверка на дубликаты.
  107. if (variableNames.count(variableName) > 0) {
  108. outputFile << "Дублирование переменной '" << variableName << "' в строке " << lineNumber <<
  109. ", позиция " << (match.position(i) + 1) << endl;
  110. hasErrors = true;
  111. } else {
  112. variableNames.insert(variableName);
  113. }
  114. }
  115. }
  116. } else {
  117. // Вывод сообщения об ошибке, если не найдено соответствие регулярному выражению.
  118. outputFile << "Синтаксическая ошибка в строке " << lineNumber << ", позиция " << (match.position() + 1)
  119. << endl;
  120. hasErrors = true;
  121. }
  122. }
  123.  
  124. // Вывод результата в файл.
  125. if (!hasErrors)
  126. outputFile << "Описание переменных корректное." << endl;
  127.  
  128. // Закрытие файлов.
  129. inputFile.close();
  130. outputFile.close();
  131.  
  132. cout << "Программа завершила выполнение." << endl;
  133.  
  134. return 0;
  135. }
Advertisement
Add Comment
Please, Sign In to add comment