Операционная система UNIX. Руководство программиста


Более сложный пример


В этом пункте рассматривается пример грамматики, в которой используются некоторые специфические свойства yacc'а. Калькулятор из предыдущего пункта реконструируется, чтобы обеспечить действия над вещественными числами и над интервалами таких чисел. Калькулятор понимает вещественные константы, арифметические операции +, -, *, /, унарный -, переменные от a до z. Кроме того, он воспринимает интервалы вида

(X, Y)

где X не превосходит Y. Можно использовать 26 переменных типа интервал с именами от A до Z. Калькулятор работает аналогично тому, который был описан в пункте Простой пример; присваивания не возвращают значений и ничего не выводят, остальные выражения выводят результат (вещественный или интервальный).

В данном примере используется ряд интересных особенностей yacc'а и языка C. Интервал представляется структурой, состоящей из левой и правой границ, значения которых имеют тип double. При помощи конструкции typedef этому структурному типу дается имя INTERVAL. В стек значений yacc'а могут быть занесены также значения целого и вещественного типов (целые числа используются в качестве индекса в массиве, содержащем значения переменных). Отметим, что организация вычислений в целом сильно зависит от возможности присваивать структуры и объединения в языке C. Многие действия вызывают функции, возвращающие значения структурного типа.

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

Кроме смешивания типов в стеке значений данная грамматика демонстрирует любопытный способ отслеживания типа (скалярного или интервального) промежуточных выражений. Отметим, что скаляр может быть автоматически преобразован в интервал, если контекст требует значения интервального типа. Это приводит к большому числу конфликтов, которые обнаруживает в грамматике yacc: 18 конфликтов свертка-перенос и 26 свертка-свертка. Проблему можно рассмотреть на примере двух входных строк




Начало  Назад  Вперед



Книжный магазин