Категории
Самые читаемые
ChitatKnigi.com » 🟢Компьютеры и Интернет » Интернет » UNIX — универсальная среда программирования - Керниган Брайан Уилсон

UNIX — универсальная среда программирования - Керниган Брайан Уилсон

Читать онлайн UNIX — универсальная среда программирования - Керниган Брайан Уилсон
1 ... 102 103 104 105 106 107 108 109 110 ... 187
Перейти на страницу:

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать

 2.5410306

exp(2*3*log(1.5))

 2.5410306

sin(PI/2)

 1

atan(1)*DEG

 45

Несколько улучшилась и работа распознавателя. В hoc2 присваивание x = expr не только вызывало присваивание, но и приводило к печати значения, поскольку все выражения печатаются:

$ hoc2

x=2*3.14159

6.28318 В случае присваивания переменной значение печатается

В программе hoc3 проводится различие между присваиваниями и выражениями; значения печатаются только для выражений:

$ hoc3

x=2*3.14159 Присваивание: значение не печатается

x           Выражение:

6.28318     Значение печатается

Получившаяся в результате всех этих изменений программа настолько велика (около 250 строк текста), что для простоты редактирования и ускорения компиляции лучше разбить ее на отдельные файлы. Итак, теперь мы имеем пять файлов вместо одного:

hoc.y грамматика, main, yylex (как и прежде); hoc.h глобальные структуры данных для включения в другие файлы; symbol.c функции, работающие с таблицей имен: lookup, install; unit.c встроенные функции и константы; init; math.c функции для вызова стандартных математических функций: Sqrt, Log и т.д.

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

Вернемся снова к программе make и рассмотрим вначале структуру таблицы имен. Поименованный объект имеет имя, тип (VAR или BLTIN) и значение. Так, объект типа VAR имеет значение double; если объект является встроенным, то его значением служит указатель на функцию, возвращающую double. Данная информация используется в hoc.y, symbol.c и init.c. Ее можно размножить в трех экземплярах, но тогда легко ошибиться или забыть исправить один из экземпляров при внесении изменений. Вместо этого мы поместили общую информацию в файл макроопределений hoc.h, который можно включить при необходимости в любой файл. (Окончание .h традиционно, но не контролируется никакими программами.) В файл makefile также добавлены сведения о зависимости исходных файлов от hoc.h, чтобы при изменении hoc.h была проведена требуемая перекомпиляция.

$ cat hoc.h

typedef struct Symbol { /* symbol table entry */

 char *name;

 short type; /* VAR, BLTIN, UNDEF */

 union {

  double val; /* if VAR */

  double (*ptr)(); /* if BLTIN */

 } u;

 struct Symbol *next; /* to link to another */

} Symbol;

Symbol *install(), *lookup();

$

Тип UNDEF обозначает VAR, которой пока не присвоили значения. Объекты связаны в список с помощью элемента next в записи Symbol. Сам список является локальным для symbol.c, доступ к нему возможен только посредством функций lookup и install. Это позволяет в случае необходимости легко менять структуру таблицы имен (что мы уже сделали однажды). Функция lookup отыскивает в списке заданное имя и возвращает указатель на Symbol, если имя найдено, и 0 в противном случае. Таблица имен рассчитана на линейный поиск, что вполне допустимо для диалогового калькулятора, поскольку поиск имен выполняется не во время его работы, а в процессе разбора. Функция install вносит переменную и связанные с ней тип и значение в начало списка. Функция emalloc обращается к стандартной функции размещения malloc (см. справочное руководство по malloc(3)) и проверяет результат. Указанные три функции составляют содержимое файла symbol.c. Файл y.tab.h создается при выполнении команды yacc -d; он содержит операторы #define, порождаемые yacc для лексем NUMBER, VAR, BLTIN и т.д.

$ cat symbol.c

#include "hoc.h"

#include "y.tab.h"

static Symbol *symlist = 0; /* symbol table: linked list */

Symbol *lookup(s) /* find s in symbol table */

 char *s;

{

 Symbol *sp;

 for (sp = symlist; sp != (Symbol*)0; sp = sp->next)

  if (strcmp(sp->name, s) == 0)

1 ... 102 103 104 105 106 107 108 109 110 ... 187
Перейти на страницу:
Открыть боковую панель
Комментарии
Jonna
Jonna 02.01.2025 - 01:03
Страстно🔥 очень страстно
Ксения
Ксения 20.12.2024 - 00:16
Через чур правильный герой. Поэтому и остался один
Настя
Настя 08.12.2024 - 03:18
Прочла с удовольствием. Необычный сюжет с замечательной концовкой
Марина
Марина 08.12.2024 - 02:13
Не могу понять, где продолжение... Очень интересная история, хочется прочесть далее
Мприна
Мприна 08.12.2024 - 01:05
Эх, а где же продолжение?