Конечные автоматы и обработка текстов
5.1. Составные символы, комментарии и т.п.
5.1.1. В тексте возведение в степень обозначалось двумя идущими подряд звездочками. Решено заменить это обозначение на (так что, к примеру, x**y заменится на ). Как это проще всего сделать? Исходный текст читается символ за символом, получающийся текст требуется печатать символ за символом.
Решение. В каждый момент программа находится в одном из двух состояний: "основное" и "после" (звездочки):
Состояние | Очередной входной символ | Новое состояние | Действие |
---|---|---|---|
основное | * | после | нет |
основное | * | основное | печатать x |
после | * | основное | печатать ^ |
после | * | основное | печатать *, x |
Если в конце текста программа оказывается в состоянии "после", то следует напечатать звездочку (и кончить работу).
Замечание. Наша программа заменяет *** на (но не на ). В условии задачи мы не оговаривали деталей, как это часто делается - предполагается, что программа "должна действовать разумно". В данном случае, пожалуй, самый простой способ объяснить, как программа действует - это описать ее состояния и действия в них.
5.1.2. Написать программу, удаляющую из текста все подслова вида abc.
5.1.3. В паскале комментарии заключаются в фигурные скобки:
begin {начало цикла} i:=i+1; {увеличиваем i на 1}
Написать программу, которая удаляла бы комментарии и вставляла бы вместо исключенного комментария пробел (чтобы превратилось не в , а в ).
Решение. Программа имеет два состояния: "основное" и "внутри" (комментария).
Состояние | Очередной входной символ | Новое состояние | Действие |
---|---|---|---|
основное | Y | внутри | нет |
основное | x | основное | печатать x |
внутри | } | основное | печатать пробел |
после | x | внутри | нет |
Замечание. Эта программа не воспринимает вложенные комментарии: строка вроде
{{комментарий внутри} комментария}
превратится в
комментария}
(в начале стоят два пробела). Обработка вложенных комментариев конечным автоматом невозможна (нужно "помнить число скобок" - а произвольное натуральное число не помещается в конечную память).
5.1.4. В паскалевских программах бывают также строки, заключенные в кавычки. Если фигурная скобка встречается внутри строки, то она не означает начала или конца комментария. В свою очередь, кавычка в комментарии не означает начала или конца строки. Как изменить программу, чтобы это учесть?
Указание. Состояний будет три: основное, внутри комментария, внутри строки.
5.1.5. Еще одна возможность многих реализаций паскаля - это комментарии вида
i:=i+1; (* here i is increased by 1 *)
при этом закрывающая скобка должна соответствовать открывающей (то есть не разрешается). Как удалять такие комментарии?