Информатика ← ЛабораторныеЛабораторная работа №11

Простейшие приемы лексического анализа

Задание

Составить программу на языке Си, выполняющую анализ и обработку вводимого текста в соответствии с выданным вариантом задания. В программе не должно быть ограничений на количество и длину строк исходного текста. Конец файла должен обрабатываться корректно, как это делается утилитами Unix cat, wc -c и т. д.).

Терминология

Слово — произвольная (в данном задании непустая) последовательность литер, не являющихся разделителями.

Число — произвольная непустая последовательность цифр данной системы счисления, быть может, начинающаяся со знака + или - и представляющая собой отдельное слово.

Строка — последовательность литер, заканчивающаяся символом переводая строки '\n' в языке Си, за исключением последней строки, которая может завершаться признаком конца файла (константой EOF, возвращаемой функцией чтения!).

Разделители — пробелы, запятые, табуляции \t, символы конца строки \n.

Варианты

  1. Подсчитать число слов в однострочных комментариях (//) в программе на Си.
  2. Подсчитать число слов в многострочных комментариях (/* и */) в программе на Си.
  3. Подсчитать число слов в комментариях ({ и } или (* и *)) в программе на Паскале.
  4. Подсчитать количество полнотетрадных (со всеми необходимыми ведущими нулями) двоичнокодированных десятичных чисел (BCD — Binary Coded Decimal).
  5. Подсчитать количество слов с лексикографически возрастающими буквами латинского алфавита.
  6. Подчситать количество слов — правильных идентификаторов языков Си или Паскаль.
  7. Закодировать текст по Цезарю с переменным ключом, равным номеру буквы в слове + 3.
  8. Раскодировать текст, закодированный по Цезарю с переменным ключом, равынм номеру слова в строке.
  9. Напечатать значения пятеричных чисел, не являющихъся троичными числами, в десятичной системе.
  10. Отделить пробелом слова, находящиеся вплотную к концу строки и к началу следующей. (Заменить перевод строки пробелом.)
  11. Выделить все 11-ричные числа с лексикографическим возрастанием цифр.
  12. Ко всем допустимым целым числам добавить ведущие нули.
  13. У всех допустимых 16-ричных чисел перенести ведущие нули в младшие разряды слова фиксированной длины.
  14. *Подчситать количество существительных в тексте на немецком языке.
  15. Подсчитать контрольные суммы всех слов исходного текста.
  16. Подсчитать количество малобуквенных слов (менее четырех символов) во всех строках исходного текста.
  17. Выделить все числа, записанные в троичной системе счисления и кратные 3.
  18. Перевести все мерные температуры из шкалы Цельсия (C) в шкалу Фаренгейта (F). Например: 100С в 212F.
  19. Перевести все мерные длины из дюймов (in) в миллиметры (mm). Например: 10in в 254mm.
  20. Перевести все мерные расстояния из миль (mi) в километры (km). Например: 1000mi в 1609km.
  21. *Подсчитать количество слов. которые являются числами в римской системе счисления.
  22. Подсчитать количество слов, содержащих не менее 3-х букв.
  23. Подсчитать количество положительных десятичных чисел в строке, допустимых 16-битными процессорами.
  24. Подсчитать количество восьмиричных чисел, находящихся в диапазоне от 10 до 1000.
  25. Выделить предпоследнее шестнадцатиричное число в строке.
  26. Выделить предпоследнее десятичное число и вычислить сумму его цифр.
  27. Выделить предпоследнее десятичное число и распечатать его цифры в системах счисления с основаниями 3, 7 и 11.
  28. Выделить первые и последние (по счету) десятичные числа строк текста.
  29. Удалить десятичные числа, не превышающие INT_MAX.
  30. *Удалить десятичные числа, превышающие INT_MAX.
  31. Распечатать каждое третье двоичное число.
  32. ВЫделить все десятичные числа от 17 до 77 по модулю и распечатать их значенпия в словесной форме по-русски.
  33. ВЫделить все восьмеричные числа от 17 до 77 по модулю и распечатать их значенпия в словесной форме по-английски.
  34. **Выделить все девятиричные числа от 17 до 77 по модулю и распечатать их значения в словесной форме по-немецки.
  35. *Выделить все десятичные числа от 17 до 77 по модулю и распечатать их значения в словесной форме по-французски.
  36. **Выделить все восьмеричные числа от 17 до 77 по модулю и распечатать их значения в словесной форме по-испански.
  37. **Выделить все девятеричные числа от 17 до 77 по модулю и распечатать их значения в словесной форме по-итальянски.
  38. Выделить все шестнадцатиричне числа, имеющие максимальное число цифр в 32-битной архитектуре.
  39. Подсчитать количество шестнадцатиричных слов в строке, изображающих отрицательные числа в 64-битной архитектуре.
  40. Выделить беззнаковые восьмеричные числа и напечатать их цифры в двоичной системе.
  41. ВЫделить десятичные целые числа без знака и напечатать суммы их четных цифр.
  42. Выделить шестнадцатиричные целые числа без знака и напечатать шестнадцатиричну3ю сумму их нечетных цифр.
  43. Подсчитать среднюю длину слова в тексте, закодированном в utf-8.

Пример

Подсчитать количество чисел во входном тексте.


#include <stdio.h>

typedef enum { IN, OUT, SKIP } state;

int is_space(int c)
{
  return c == ' ' || c == '\t' || c == ',' || c == '\n';
}

int is_digit(int c)
{
  return c >= '0' && c <= '9';
}

int is_letter(int c)
{
  return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
}

int main()
{
  state st = OUT;
  int c;
  int k = 0;
  while ((c = getchar()) != EOF) {
    switch (st) {
      case OUT: {
        if (is_digit(c))
          st = IN;
        else if (!is_space(c))
          st = SKIP; 
        break;
      }
      case IN: {
        if (is_space(c)) {
          st = OUT;
          k = k + 1;
        }
        else if (!is_digit(c))
          st = SKIP;
        break;
      }
      case SKIP: {
        if (is_space(c))
          st = OUT;
        break;
      }
    }
  }
  if (st == IN) ++k;
  printf("%d\n", k);
  return 0;
}

Ссылки

Оригинальный текст лабораторной