Сделай Сам Свою Работу на 5

Синтаксис логических выражений.





 

Синтаксические правила, рассмотренные в разделе 3.3, не покрывают случай, когда логические выражения могут включать переменные и константы. Эти правила не задают структуру всех возможных допустимых строк, которые могут образовывать логические выражения. Новые правила для логических выражений приведены ниже:

 

<выражение> ::= <простое выражение>

| <простое выражение> <оператор сравнения> <простое выражение>

 

<простое выражение> ::= <простое выражение> OR <терм> | <терм>

<терм> ::= <терм> AND <множитель> | <множитель>

<множитель> ::= <переменная> | <константа> | (<выражение>) | NOT <множитель>

 

Синтаксически некорректно записывать:

X <= Y <= Z

Для того, чтобы определить, что Y имеет значение, находящееся между значениями X и Z. Вместо этого требуется записать

(X <= Y) AND (Y <= Z)

чтобы выполнить такую проверку.

 

Скобки в выражениях – часть синтаксиса Паскаля. Попытка построить синтаксическое дерево для первого выражения терпит неудачу:

 
 

 


Невозможно вывести строку X <= Y из первого <простого выражения> без введения дополнительных символов в строку (например скобок). Для второго выражения может быть построено корректное синтаксическое дерево:



 

 
 

 


Последовательные лево-ассоциативные операторы с одинаковым приоритетом применяются к их операндам в порядке слева-на-право. Таким образом, в выражении

X OR Y OR Z

подвыражение

X OR Y

будет вычислено первым. Синтаксическое дерево для этого выражения будет следующим:

 

 


Операнды для каждого OR в строке могут быть найдены поиском строк, выведенных из соотвествующего <простого выражения> и <терма>. Операндами левого OR являются X и Y, тогда как операндами правого OR являются X OR Y (строка выведенная из первого <простоего выражения>) и Z. Таким образом, левый OR применяется к операндам раньше правого. (Конечно, приоритет операторов в выражении может быть изменен с помощью скобок)

Правило синтаксиса является леворекурсивным, если определяемая величина (то, что размещается слева от ::=) также появляется на первом месте справа от ::=.



Правило для <term> леворекурсивоное:

<терм> ::= <терм> AND <множитель>

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

Относительный приоритет операторов также определен синтаксическими правилами. Синтаксическое дерево для

X OR Y AND Z

иллюстрирует приоритет операторов:

 

 


Несмотря на то, что AND расположен правее OR в строке, он применяется к его операндам, Y и Z до того как OR будет применен к своим операндам, X и Y AND Z. Таким образом, AND имеет более высокий приоритет в логических выражениях, чем OR.

 

Значение логических выражений.

 

Значение логического выражения задается следующим рекурсивным определением. Для любого состояния выполнения S:

E1 = E2(S) = (E1(S) = E2(S))

E1 <> E2(S) = (E1(S) ¹ E2(S))

E1 < E2(S) = (E1(S) < E2(S))

E1 <= E2(S) = (E1(S) ≤ E2(S))

E1 > E2(S) = (E1(S) > E2(S))

E1 >= E2(S) = (E1(S) ≥ E2(S))

E1 OR E2(S) = (E1(S) OR E2(S))

NOT E (S) = NOT E (S)

(E) (S) = E (S)

Операторы в левой части – те, что встречаются в Паскаль-программах. Те, которые в правой части – математические операции. Это определение дает значение каждого ператора по отдельности, но не указывает как будет вычисляться выражение с несколькими операторами. Ассоциативность и приоритет операторов в выражении определяется синтаксическими правилами Паскаля. Программное исчисление требут чтобы все операторы были определены, в противном случае математические свойства такие как коммутативность, (которую мы сипользуем чаще, чем предполагаем) нарушаются.

 

Ввод-вывод логических значений.

 

Логичесике переменные не могут появляться в операторах READ, но логические выражения могут появляться в операторах WRITE. Логические значения преобразуются в символы и выравниваются по правой стороне строки, длина которой зависит от реализации Паскаль-машины (например, 10 символов).



Последовательность операторов:

Condition := TRUE;

WRITE(Condition);

Добавляет строку † TRUE† в OUTPUT.

 

Поиск в файле.

 

Программа SarahRevere в части 2 распознает слова land и sea в INPUT. Разделы проекта этой программы переработаны с использованием логических перемнных и собраны вновь ниже.

 

PROGRAM SarahRevere(INPUT, OUTPUT);

VAR

W1, W2, W3, W4: CHAR;

Looking, Land, Sea: BOOLEAN;

 

BEGIN {SarahRevere}

BEGIN {Инициализируем W1, W2, W3, W4}

W1 := ‘ ‘;

W2 := ‘ ‘;

W3 := ‘ ‘;

W4 := ‘ ‘;

Looking := TRUE;

Land := FALSE;

Sea := FALSE;

END;

WHILE Looking AND NOT (Land OR Sea)

DO

BEGIN

BEGIN {движение окна, проверка на конец данных}

W1 := W2;

W2 := W3;

W3 := W4;

READ(W4);

Looking := W4 <> ‘#’

END;

BEGIN {проверка окна на land}

Land := (W1 = ‘l’) AND (W2 = ‘a’) AND

(W3 = ‘n’) AND (w4 = ‘d’)

END;

BEGIN {проверка окна на sea}

Sea := (W1 = ‘s’) AND (W2 = ‘e’) AND (W3 = ‘a’)

END;

END;

BEGIN {создание сообщения Sarah}

IF Land

THEN

WRITELN(‘The british are coming by land.’)

ELSE

IF Sea

THEN

WRITELN(‘The british are coming by sea.’)

ELSE

WRITELN(‘Sarah didn’t say.’)

END

END. {SarahRevere}

 

Оператор WHILE управляется выражением:

Looking AND NOT (Land OR Sea)

которое разрешает телу цикла выплняться до тех пор пока значение Looking равно TRUE и оба значения Land и Sea равны FALSE. Looking присваивается значение False когда встречается #:

Looking := W4 <> ‘#’

Land и Sea присваивается TRUE если W1, W2, W3, W4 содержат соотвествующую строку.

Использование логических переменных сократило программу с 57 строк до 43.

 

Тип INTEGER.

 

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

 

Тип данных INTEGER имеет значения, которые могут быть положительными и отрицательными целыми числами и нулем. Любая Паскаль-машина ограничивает целые значения до подмножества целых чисел:

{-MAXINT, …, -2, -1, 0, 1, 2, …, MAXINT}

MAXINT – предопределенная целочисленная константа (объчно степень двойки) соответствующая наибольшему целому значению котрое может быть представлено на данной Паскаль-машине. Переменным объявленным с типом INTEGER может быть присвоено одно из этих значений.

VAR

I,J: INTEGER;

Операторами для типа INTEGER являются операторы сравнения и:

+ - * DIV MOD

для прибавления, вычитания, умножения, деления с остатком и остатка от деления соответственно.

Добавление, вычитание и умножение могут вызывать переполнение (см. ниже), а DIV и MOD – не могут. Операторы + и – могут использоваться как унарные префиксы и как бинарные инфиксные операторы. Таким образом, выражение J – I может быть записано как –I + J. Деление с остатком обычно округляет до нуля как в следующем примере:

 

Операция Значение
5 DIV 3 -7 DIV 3 10 DIV –3 -5 DIV -2 -2 -3

 

В выражении I DIV J результат неопределен, если значение J нуль, результат равен нулю, если модуль I меньше модуля J. Иначе знак результата положительняй, если I и J имеют тот же знак и отрицательный, если у I и J знак различный.

Результат выражения I MOD J неопределен, если значение J меньше или равно нулю, иначе он равен остатку от деления I на J. Например:

 

Операция Значение
5 MOD 3 -7 MOD 3 -1

 

Остаток от деления определяется через деление с остатком, например для –7 MOD 3:

-7 – (-7 DIV 3*3)

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

Таким образом, значение предыдущего выражения будет:

 

Выражение Вычисление
-7 – (-7 DIV 3 * 3) -7 – (-2*3) -7 – (-6) -1 начинаем с выражения в скобках DIV имеет тот же приоритет что и * Вычисляем выражение в скобках

 

Информация о целочисленных операторах обобщена в таблице ниже.

 

Оператор Domain Range Ассоциативность Приоритет
унарный – + * DIV MOD + – сравнения integer integer x integer integer x integer integer x integer integer integer integer boolean правая левая левая нет наивысший     низший

 

 

Подсчет пробелов.

 

В разделе 13.1 ContingBlanksInText выполняла подсчет пробелов во входном файле с использованием модуля счетчика.

 

PROGRAM CountingBlanksInText(INPUT, OUTPUT);

VAR

Ch, X100, X10, X1: CHAR;

{Включить модуль счетчика}

BEGIN {CountingBlanksInText}

Start; {обнулить счетчик}

WHILE NOT EOF

DO

BEGIN

WHILE NOT EOLN

DO

BEGIN

READ(Ch);

IF Ch = ‘ ‘

THEN

BEGIN

Bump; {Увеличиваем счетчик на едеинцу}

Ch := ‘#’;

END;

WRITE(Ch);

END;

READLN;

WRITELN

END;

WRITELN;

Value(X100, X10, X1); {получаем значение счетчика}

IF (X100 = ‘9’) AND (X10 = ‘9’) AND (X1 = ‘9’)

THEN

WRITELN(‘Количество пробелов как минимум 999’)

ELSE

WRITELN(‘Количество пробелов ’, X100, X10, X1)

END. {CountingBlanksInText}

 

Модуль определял абстракцию счетчика состоящего из трех переменных. Start присваивала символ 0 каждой из трех переменных, Bump изображала добавление единицы к к символьному представлению целочисленного значения, Value возвращала значение счетчика. Эти процедуры добавляли порядка 50 строк к программе, делая ее общую длину более 75 строк. С использованием типа данных INTEGER счетчик может быть реализован как переменная программы.

VAR

Counter: INTEGER;

а процедуры Start и Bump становятся операторами присваивания:

Counter := 0; {Start}

Counter := Counter + 1; {Bump}

Value заменяется ссылкой на Counter и Counter может быть сравнен с целой константой 999. Полная программа приведена ниже (теперь каких-то 25 строк).

 

PROGRAM CountingBlanksInText(INPUT, OUTPUT);

VAR

Ch: CHAR;

Counter: INTEGER;

BEGIN {CountingBlanksInText}

Counter := 0; {обнулить счетчик}

WHILE NOT EOF

DO

BEGIN

WHILE NOT EOLN

DO

BEGIN

READ(Ch);

IF Ch = ‘ ‘

THEN {Увеличиваем счетчик на единицу}

Counter := Counter +1;

WRITE(Ch);

END;

READLN;

WRITELN

END;

WRITELN;

IF Counter >= 999

THEN

WRITELN(‘Количество пробелов как минимум 999’)

ELSE

WRITELN(‘Количество пробелов ’, Counter)

END. {CountingBlanksInText}

 

INPUT:

Now is

the time for

all good men.

 

OUTPUT:

Now is

the time for

all good men.

 

Количество пробелов 9

 

INPUT:

 

OUTPUT:

 

Количество пробелов 0

 

Тест на более чем трехзначные значения был оставлен, чтобы программа была похода на ту которая использовала модуль счетчика, хотя с целочисленной переменной действительным ограничением является MAXINT. Частной и небезопасной практикой является игнорирование существования MAXINT и надежда на то, что Паскаль-машина сама разберется с этими проблемами.

 

 








Не нашли, что искали? Воспользуйтесь поиском по сайту:



©2015 - 2024 stydopedia.ru Все материалы защищены законодательством РФ.