Чтение онлайн

на главную - закладки

Жанры

UNIX — универсальная среда программирования
Шрифт:
Внесение изменений — унарный минус

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

yacc
, легко менять язык. В качестве примера добавим к
hoc1
унарный минус, чтобы выражения типа

– 3-4

вычислялись, а не отвергались как синтаксические ошибки. Всего две строки нужно дополнительно включить в

hoc.y
. Добавляется новая лексема
UNARYMINUS
в ту часть грамматики, где задаются приоритеты, чтобы унарный минус имел наивысший приоритет:

%left '+' '-'

%left '*' '/'

%left UNARYMINUS /*
новая лексема */

Грамматика увеличивается на одно правило для

expr
:

expr: NUMBER ($$= $1;}

 | '-' expr %prec UNARYMINUS {$$=- $2} /* новое */

Определение

%prec
"говорит", что символ унарного минуса (т.е. знак
"-"
перед выражением) имеет тот же приоритет, что и
UNARYMINUS
(наивысший); действие заключается в изменении знака. Приоритет минуса между двумя выражениями устанавливается по умолчанию.

Упражнение 8.2

Добавьте операции

%
(взятие остатка) и унарный плюс к
hoc1
. Рекомендация: обратитесь к справочному руководству по
frexp(3)
.

Некоторые замечания относительно
make

Обидно, что приходится вводить две команды для компиляции

hoc1
. Хотя, конечно, нетрудно составить командный файл для такого задания, но есть лучший способ, который позднее можно распространить на тот случай, когда программа состоит из нескольких исходных файлов. Программа
make
читает описания взаимозависимости компонентов программы и позволяет создать ее действующую версию. Она проверяет время последней модификации каждого компонента, выясняет минимальный объем перекомпиляции, которую необходимо выполнить для получения новой действующей версии, и затем запускает процесс. Программа
make
разбирается в запутанных многошаговых процессах, в частности в
yacc
, поэтому ей можно давать задания, не уточняя отдельные шаги.

Особенно полезно обращаться к

make
, когда создаваемая программа настолько велика, что "располагается" в нескольких исходных файлах. Однако она удобна и для таких малых программ, как
hoc1
. Ниже приведены описания команд для
make
, рассчитанные на
hoc1
, которые
make
предполагает найти в файле с именем
makefile
.

$ cat makefile

hoc1: hoc.o

cc hoc.o -o hoc1

$

Здесь сообщается, что

hoc1
зависит от
hoc.o
и что
hoc1
создается из
hoc.o
с помощью команды
сс
, которая запускает компилятор Си, помещая выходной поток в файл
hoc1
. Программа
make
уже "знает", как преобразовать входной файл для
yacc
hoc.y
в выходной файл
hoc.o
:

$ make
Проделаем первый раз получение hoc1 с помощью make

yacc hoc.y

сс -с y.tab.c

rm y.tab.c

mv y.tab.o hoc.о

сс hoc.о -о hoc1

$ make 
Попробуем еще раз

'hoc1' is up to date make
понимает, что это не нужно

$

8.2 Этап 2: переменные и восстановление после ошибки

Следующий шаг переход от

hoc1
к
hoc2
, который сводится к расширению памяти (в памяти хранится 26 переменных с именами от
а
до
z
). Это довольно несложный и весьма полезный промежуточный этап. Мы также введем здесь процесс обработки ошибок. Если вы проверите
hoc1
, то убедитесь, что реакцией на синтаксические ошибки являются вывод сообщения и прекращение работы. Поведение же
hoc1
в случае арифметических ошибок типа деления на нуль достойно всяческого порицания:

$ hoc1

1/0

Floating exception - core dump

$

Для реализации новых возможностей требуются лишь небольшие изменения: приблизительно 35 строк текста. Лексический анализатор

yylex
должен распознавать буквы как переменные, а грамматика содержать правила вывода вида

expr: VAR

 | VAR '=' expr

Выражение может содержать операцию присваивания; разрешены также многократные присваивания типа

x = y = z = 0

Простейший способ хранения значений переменных создать массив из 26 элементов; однобуквенную переменную можно использовать в качестве индекса массива. Однако если анализатору предстоит обрабатывать и имена переменных, и значения в одном стеке, необходимо сообщить

yacc
, что элемент стека является объединением
double
и
int
, а не просто элементом типа
double
. Это делается с помощью описания
%union
. Описания
#define
или
typedef
подходят для определения стека из базовых типов как
double
, но для типов объединения требуется описание
%union
, поскольку
yacc
осуществляет контроль типов в выражениях вида
$$ = $2
.

Ниже приведена часть определения грамматики

hoc.y
для программы
hoc2
:

$ cat hoc.y

%{

double mem[26]; /* memory for variables 'a'..'z' */

%}

%union { /* stack type */

 double val; /* actual value */

 int index; /* index into mem[] */

}

%token <val> NUMBER

%token <index> VAR

%type <val> expr

%right '='

%left '+'

%left '*' '/'

%left UNARYMINUS

%%

list: /* nothing */

 | list '\n'

 | list expr '\n' { printf ("\t%.8g\n", $2); }

 | list error '\n' { yyerrok; }

 ;

expr: NUMBER

 | VAR { $$ = mem[$1]; }

Поделиться:
Популярные книги

Хроники Тириса. Книга 1

Маханенко Василий Михайлович
1. Хроники Тириса
Фантастика:
боевая фантастика
космическая фантастика
фантастика: прочее
6.00
рейтинг книги
Хроники Тириса. Книга 1

Я царь. Книга XXVIII

Дрейк Сириус
28. Дорогой барон!
Фантастика:
боевая фантастика
аниме
попаданцы
5.00
рейтинг книги
Я царь. Книга XXVIII

Менталист. Конфронтация

Еслер Андрей
2. Выиграть у времени
Фантастика:
боевая фантастика
6.90
рейтинг книги
Менталист. Конфронтация

Бастард Императора. Том 5

Орлов Андрей Юрьевич
5. Бастард Императора
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бастард Императора. Том 5

Хозяин Стужи

Петров Максим Николаевич
1. Злой Лед
Фантастика:
аниме
фэнтези
попаданцы
7.00
рейтинг книги
Хозяин Стужи

Вперед в прошлое 2

Ратманов Денис
2. Вперед в прошлое
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Вперед в прошлое 2

Целеполагание

Владимиров Денис
4. Глэрд
Фантастика:
фэнтези
боевая фантастика
рпг
5.00
рейтинг книги
Целеполагание

Студент из прошлого тысячелетия

Еслер Андрей
2. Соприкосновение миров
Фантастика:
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Студент из прошлого тысячелетия

Мастер 4

Чащин Валерий
4. Мастер
Фантастика:
героическая фантастика
боевая фантастика
попаданцы
5.00
рейтинг книги
Мастер 4

Кодекс Охотника. Книга XIII

Винокуров Юрий
13. Кодекс Охотника
Фантастика:
боевая фантастика
попаданцы
аниме
7.50
рейтинг книги
Кодекс Охотника. Книга XIII

Мужчина моей судьбы

Ардова Алиса
2. Мужчина не моей мечты
Любовные романы:
любовно-фантастические романы
8.03
рейтинг книги
Мужчина моей судьбы

География растений

Гумбольдт Александр
Классики естествознания
Научно-образовательная:
ботаника
7.50
рейтинг книги
География растений

Цикл "Отмороженный". Компиляция. Книги 1-14

Гарцевич Евгений Александрович
Отмороженный
Фантастика:
боевая фантастика
рпг
постапокалипсис
5.00
рейтинг книги
Цикл Отмороженный. Компиляция. Книги 1-14

Первый среди равных. Книга IV

Бор Жорж
4. Первый среди Равных
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Первый среди равных. Книга IV