Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ВВП - лекция 10.doc
Скачиваний:
1
Добавлен:
01.07.2025
Размер:
230 Кб
Скачать
☆

Тестирование процедуры RemoveExtraBlanks.

Для тестирования этой процедуры полезно пометить начало и конец строк, чтобы их легко было видеть. Для этой цели можно использовать символ #.

PROGRAM TestRes(INPUT, OUTPUT)

VAR

Ch: CHAR;

TestIn, TestOut: TEXT;

PROCEDURE RemoveExtraBlanks(VAR FileIn, FileOut: TEXT);

{ копирует слова из FileIn в FileOut, удаляя головные и хвостовые пробелы, а также лишние пробелы между словами }

BEGIN

ASSIGN(TestIn, ‘TestIn.txt’);

ASSIGN(TextOut, ‘TestOut.txt’);

WHILE NOT EOF

{копируем одну строку из INPUT в файл TestIn, с эхом ввода};

RemoveExtraBlanks(TestIn, TestOut);

{Копируем результирующую строку из TestOut в OUTPUT}

END

END

Задание 2. Написать недостающие разделы проекта для программы TestRes. При выводе результата на экран пометить начало и конец входной и выходной строки символом #.

INPUT:

Pack my box with six.

SOLIDPACKED□□

OUTPUT:

Input is: # Pack my box with six.#

Output is: #Pack my box with six.#

Input is: #SOLIDPACKED #

Output is: #SOLIDPACKED#

(15 баллов)

Программа передает каждую входную строку процедуре RemoveExtraBlanks и выводит результат. Описание синтаксиса входной строки в форме Бекуса-Наура для всех возможных входов (правила 1 и 2) дают нам способ выбора тестовых данных. Если мы полагаем, что разделы RemoveExtraBlanks для пропуска пробелов и копирования слов работают корректно, единственное, что должно быть протестировано – это комбинация позиций <слов> и <пробелов> описываемых данными синтаксическими правилами. Согласно этим правилам возможно 4 варианта:

<пробел>

<слово> <пробелы> <список-слов-пробелов> <пробел>

<пробелы> <пробел>

<пробелы> <слово> <проелы> <список-слов-пробелов> <пробел>

Заслуживающие внимания тестовые случаи, за исключением конечного <списка-слов-пробелов> <пробела> такие:

††

†the †

† †

† the †

10.1.5 Анализ процедуры RemoveExtraBlanks

Для того чтобы продемонстрировать, что RemoveExtraBlanks выполняет то, ради чего была спроектирована, ее функция должна быть вычислена. Пролект для части DO внутреннего оператора WHILE такой:

{копируем слово};

FlushBlanks(Ch);

{вставляем пробел, если это не последнее слово}

Соответствующая функция для каждой из этих трех частей может быть записана в виде условного присваивания.

Функция C для копирования слова такая:

C = C1 | C2

где

C1 = ((Ch <> ‘ ‘)

AND (NOT(EOF(FileIn))) AND (FileIn.2 = (x  B) & y)

AND (FileIn.3 = R) AND (FileOut.3 = W) 

Ch,FileOut.1,FileIn.1, FileIn.2 :=

□,(FileOut.1  Ch) & x,FileIn.1 & (x  B),y)

и

C2 = (Ch = ‘ ‘  )

где x – строка не пробельных символов, не содержащая маркера конца строки, y – строка, а B – либо маркер конца строки, либо □. В этом и в следующих условных присваиваниях элементы 3-списков файлов изображаются при помощи индекса, следующего за точкой. Например, FileIn.2 означает FileIn2, второй элемент списка (являющийся строкой будущего). Такая нотация позволяет записывать условные присваивания в комментариях программе, где запись индексов не возможна.

Функция F для FlushBlanks(Ch) такая:

F = (F0  (F1 | F2)) | F3

где

F0 = ((Ch = ‘ ‘) AND (NOT(EOF(FileIn))) AND (FileIn.3 = R)

F1 = (FileIn.2 = b  Z & w 

Ch, FileIn.1, FileIn.2 := Z, FileIn.1 & b  Z, w)

F2 = (FileIn.2 = b  / 

Ch, FileIn.1, FileIn.2 := □, FileIn.1 & FileIn.2, ††)

F3 = ((Ch <> ‘ ‘) OR (EOF(FileIn))  )

где b - строка из пробелов и маркеров конца строки (возможно, пустая), Z – это символ, отличный от пробела и маркера конца строки, а w – непустая строка символов.

Задание 3. Доказать, что

BEGIN {copy word} … END = C

и

FlushBlanks(Ch) = F

(30 баллов)

Доказательство того, что функция I соответствует условной вставке пробела, следует далее:

I = I1 | I2

I1 = ((NOT(EOF(FileIn))) AND (FileOut.3 = W) AND (FileIn.3 = 3) 

FileOut.1 = FileOut.1  □)

I2 = ((EOF(FileIn)) AND (FileIn.3 = R)  )

Значение части DO, следовательно, является композицией этих трех функций C◦ F ◦ I. Композиция может быть вычислена с использованием условных трассировочных таблиц. Каждое условие помечается. Имеется два условия для C, три условия для F и два - для I. Всего 12 комбинаций. Каждая таблица помечается условиями, которые она покрывает. Например, (C1, F1, I1) представляет первое условие C, первое условие F и первое условие I. FileIn и FileOut будут сокращенно называться FI и FO, соответственно.

12 случаев:

Случай 1(C1, F1, I1)

Случай 5 (C1, F3, I1)

Случай 9 (C2, F2, I1)

Случай 2(C1, F1, I2)

Случай 6 (C1, F3, I2)

Случай 10 (C2, F2, I2)

Случай 3(C1, F2, I1)

Случай 7 (C2, F1, I1)

Случай 11 (C2, F3, I1)

Случай1 4(C1, F2, I2)

Случай 8 (C2, F1, I2)

Случай 12 (C2, F3, I2)

Случай 1(C1, F1, I1)

Условие

Ch

F0.1

FI.1

FI.2

(Ch <> ‘ ‘) AND

(NOT(EOF(FI))) AND

(FI.2 = z  B & y) AND

(FI.3 = R) AND (FO.3 = W)

□

FO.1  Ch & z

FI.1 & z  B

y

(□ = ‘ ‘) AND

(NOT(EOF(<FI.1 & z  B,y,FI.3>)))

AND (FI.3 = R) AND (y = b  Z & w)

Z

FI.1 & z  B & b  Z

w

NOT(EOF(<FI.1 & z & B & b  Z, w, FI.3>))

AND (FI.3 = R) AND (FO.3 = W)

FO.1  Ch & z  □

Условие такое:

(Ch <> ‘ ‘) AND (NOT(EOF(FI))) AND (FI.2 = z  B & y) AND (FI.3 = R) AND (FO.3 = W) AND (□ = □)

AND (NOT(EOF(<FI.1 & z  B,y,FI.3>)) AND (y = b  Z & w)

AND (NOT(EOF(<FI.1 & z & B & b  Z, w, FI.3>)))

Несколько частей данного условия эквивалентны TRUE:

Условие

равно TRUE, т.к.

□ = □

Очевидно

NOT(EOF(<FI.1 & z  B,y,FI.3>))

Из-за следующего условия: y = b  Z & w, а w – не пусто

NOT(EOF(<FI.1 & z & B & b  Z, w, FI.3>))

W не пусто

Таким образом, выполнив подстановку y, условие уменьшается до:

Условие:

(Ch <> ‘ ‘) AND (NOT(EOF(FI))) AND (FI.2 = x  B & b  Z & w) AND (FI.3 = R) AND (FO.3 = W)

Присваивание:

Ch, FO.1, FI.1, FI.2 := Z, FO.1  Ch & x  □, FI.1 & x  B & b  Z, w

Задание 4. Аналогичным образом напишите условные присваивания для случаев 2 - 12. Покажите, что произойти могут только случаи 1, 4, 6, 7, 10 и 12.

(55 баллов)

Собирая вместе все возможные случаи, композиция трех функций C◦F◦I имеет условия и присваивания:

Случай 1.

Условие: (Ch <> ‘ ‘) AND (NOT(EOF(FI))) AND (FI.2 = x  B & b  Z & w) AND (FI.3 = R) AND (FO.3 = W)

Присваивание: Ch, FO.1, FI.1, FI.2 := Z, FO.1  Ch & x  □, FI.1 & x  B & b  Z, w

Случай 4.

Условие: (Ch <> ‘ ‘) AND (NOT(EOF(FI))) AND (FI.2 = x  B & b  /) AND (FI.3 = R) AND (FO.3 = W)

Присваивание: Ch, FO.1, FI.1, FI.2 := □, FO.1  Ch & x  □, FI.1 & x  B & b  /, ††

Случай 6.

Условие: (Ch <> ‘ ‘) AND (NOT(EOF(FI))) AND (FI.3 = R) AND (FO.3 = W) AND (FI.2 = x  /)

Присваивание: Ch, FO.1, FI.1, FI.2 := □, FO.1  Ch & x, FI.1 & x  /, ††

Случай 7.

Условие: (Ch = ‘ ‘) AND (NOT(EOF(FI))) AND (FI.3 = R) AND (FI.2 = b  Z & w) AND (FO.3 = W)

Присваивание: Ch, FO.1, FI.1, FI.2 := Z, FO.1  □, FI.1 & b  Z, w

Случай 10.

Условие: (Ch = ‘ ‘) AND (NOT(EOF(FI))) AND (FI.3 = R) AND (FI.2 = b  /)

Присваивание: Ch, FI.1, FI.2 := □, FI.1 & FI.2, ††

Случай 12.

Условие: (Ch = ‘ ‘) AND (NOT(EOF(FI))) AND (FI.3 = R)

Присваивание:

Игнорируя условия того, что входной файл должен быть открыт для чтения, а выходной – для записи, случаи 1, 4 и 6 происходят когда значении Ch не равно □, а входной файл не закончился, согласно значению FileIn.2, мы имеем следующее:

Случай

FileIn.2

Следующее слово z

Добавляение к FileOut.1

1

Z  B & b  Z & w

пары <пробел> <слово>

 Ch & z  □

4

Z  B & b  /

<пробелы>

 Ch & z

6

Z  /

Маркер конца строки

 Ch & z

z – это строка непробельных символов, не содаржащая маркер конца строки, B – пробел, либо маркер конца строки, b – строка пробелов или маркеров конца строк, w – это непустая строка, Z- символ, не являющийся пробелом либо маркером конца строки

Случаи 7 и 10 происходят, когда значения Ch равно □, а входной файл не закончился.

Случай

FileIn.2

Следующие <пробелы> b

Добавляение к FileOut.1

7

b  Z & w

пары <слово> <пробел>

 Ch & z  □

10

b  /

Маркер конца строки

 Ch & z

Случай 12 происходит в конце файла. К FileOut ничего не добавляется.

Функция g = C ◦ F ◦ I может быть записана в виде условного присваивания при помощи комбинирования случаев, написанных выше.

g =

((Ch <> ‘ ‘) AND (NOT(EOF(FI))) AND (FI.3 = R) AND (FO.3 = W) 

  1. (FI.2 = z  B & b  Z & w  Ch, FO.1, FI.1, FI.2 := Z, FO.1  Ch & x  □, FI.1 & x  B & b  Z, w) |

  1. (FI.2 = z  B & b  /  Ch, FO.1, FI.1, FI.2 := □,FO.1  Ch & x, FI.1 & x  B & b  /, ††) |

  1. (FI.2 = z  /  Ch, FO.1, FI.1, FI.2 :=□, FO.1  Ch & x, FI.1 & x  /, ††)) |

((Ch = ‘ ‘) AND (NOT(EOF(FI))) AND (FI.3 = R) 

  1. ((FI.2 = b  Z & w) AND (FO.3 = W)  Ch FO.1, FI.1, FI.2 := Z, FO.1  □, FI.1 & b  Z, w) |

  1. (FI.2 = b  /  Ch, FI.1, FI.2 := □, FI.1 & FI.2, ††)) |

((Ch = ‘ ‘) AND (EOF(FI)) AND (FI.3 = R)  )

Номера слева идентичны случаям, осуждаемым выше. Эта функция описывает копирование слова из FileIn в FileOut, начинающегося с символа в Ch (в том случае, когда он не равен пробелу); когда Ch является пробелом, единственный пробел добавляется к FileOut за исключение случая, при котором курсор в FileIn указывает на конец файла.

В проекте процедуры RemoveExtraBlanks входной и выходной файлы были описаны с использованием нотации Бекуса-Наура. Строки, описываемые нотацией BNF, могут также быть описаны с использованием формальных строковых операций, как это было сделано в определении функции g. Наличие соответствия между этими двумя описаниями помогает понять, как программа решает задачу. В случае 1, нам показывают, что входная строка имеет вид:

Ch & x B & b Z & w

Подчеркнутая последовательность может быть описана в виде BNF так:

<слово> <пробелы> <не пробел>

где <слово> - это непустая строка непробельных символов, <пробелы> - непустая строка □, а <непробел> - это непробельный символ. B & b могут содержать маркеры конца строки, но они будут сконвертированы в пробелы до того, как будут рассмотрены в Ch)

Выходная строка для случая 1 функции g изменяется путем добавления:

 Ch & x  □,

что в нотации BNF представляет собой

<слово> <пробел>

В случае 1, функция g конвертирует строку вида:

<слово> <пробелы> <не пробел>,

в строку вида:

<слово> <пробел> <не пробел>.

Аналогичным способом запишем в виде BNF оставшиеся случачаи: